Foreign key refering to primary keys across multiple tables? - postgresql

i have three tables say city,state and road
1) city -> city_id(PK),name
2) state-> Stt_id(PK),name
3) Road-> Edge_id(PK), Admin_id(FK)
where Admin_id refers to city_id and Stt_id both.
This is done because the tables are too huge.
say city_id contains 1,2,3
and Stt_id contains 4,5,6
now if i am inserting 1,2,3,4,5,6 in admin_id it is throuing an error .. what is the solution of my problem,
regards
sanjay

Create an admin table that holds an entry for every city and state, using its admin_ids as city_id and stt_id in their respective tables. Then declare foreign keys on city_id, stt_id and road.admin_id, referencing admin.admin_id (retaining all the existing PKs, of course).

Related

How to create encoded primary key for table from two different table primary keys

I have two table Table 1 and Table 2 now I have to create thrid table whose primary key is encoded and combination of table1 and table 2 pk's. I also want to fetch the record of table3 with table 1 and table 2 on the basis of table 3 pk.
can some one help me.
solution in my mind was if I can create some thing similar to JWT toke from the table 1 and table 2 pk's and store it in table 3 pk. but the problems is how I will decode it and perform basic CRUD operation with join query between different tables

How to edit a record that results in a uniqueness violation and echo the change to child tables?

PostgreSQL 11.1
How can "Editing" of a record be transmitted to dependent records?
Summary of my issue:
The master table, disease, needs a unique constraint on the description column. This unique constraint is needed for foreign key ON UPDATE CASCADE to its children tables.
To allow for a temporary violation of the unique constraint, it must be made deferrable. BUT A DEFERABLE CONSTRAINT CAN NOT BE USED IN A FOREIGN KEY.
Here is the situation.
The database has 100+ tables (and keeps on growing).
Most all information has been normalized in that repeating groups of information have been delegated to their own table.
Following normalization, most tables are lists without duplication of records. Duplication of records within a table is not allowed.
All tables have a unique ID assigned to each record (in addition to a unique constraint placed on the record information).
Most tables are dependent on another table. The foreign keys reference the primary key of the table they are dependent on.
Most unique constraints involve a foreign key (which in turn references the primary key of the parent table).
So, assume the following schema:
CREATE TABLE phoenix.disease
(
recid integer NOT NULL DEFAULT nextval('disease_recid_seq'::regclass),
code text COLLATE pg_catalog."default",
description text COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT disease_pkey PRIMARY KEY (recid),
CONSTRAINT disease_code_unique UNIQUE (code)
DEFERRABLE,
CONSTRAINT disease_description_unique UNIQUE (description)
,
CONSTRAINT disease_description_check CHECK (description <> ''::text)
)
CREATE TABLE phoenix.dx
(
recid integer NOT NULL DEFAULT nextval('dx_recid_seq'::regclass),
disease_recid integer NOT NULL,
patient_recid integer NOT NULL,
CONSTRAINT pk_dx_recid PRIMARY KEY (recid),
CONSTRAINT dx_unique UNIQUE (tposted, patient_recid, disease_recid)
,
CONSTRAINT dx_disease_recid_fkey FOREIGN KEY (disease_recid)
REFERENCES phoenix.disease (recid) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT dx_patients FOREIGN KEY (patient_recid)
REFERENCES phoenix.patients (recid) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT
)
(Columns not involved in this question have been removed. :) )
There are many other children tables of disease with the same basic dependency on the disease table. Note that the primary key of the disease table is a foreign key to the dx table and that the dx table uses this foreign key in a unique constraint. Also note that the dx table is just one table of a long chain of table references. (That is the dx table also has its primary key referenced by other tables).
The problem: I wish to "edit" the contents of the parent disease record. By "edit", I mean:
change the data in the description column.
if the result of the change causes a duplication in the disease table, then one of the "duplicated" records will need to be deleted.
Herein lies my problem. There are many different tables that use the primary key of the disease table in their own unique constraint. If those tables ALSO have a foreign key reference to the duplicated record (in disease), then cascading the delete to those tables would be appropriate -- i.e., no duplication of records will occur.
However, if the child table does NOT have a reference to the "correct" record in the parent disease table, then simply deleting the record (by cascade) will result in loss of information.
Example:
Disease Table:
record 1: ID = 1 description = "ABC"
record 2: ID = 2 description = "DEF"
Dx Table:
record 5: ID = 5 refers to ID=1 of Disease Table.
Editing of record 1 in Disease table results in description becoming "DEF"
Disease Table:
record 1: ID = 1 "ABC" --> "DEF"
I have tried deferring the primary key of the disease table so as to allow the "correct" ID to be "cascaded" to the child tables. This causes the following errors:
A foreign key can not be dependent on a deferred column. "cannot use a deferrable unique constraint for referenced table "disease"
additionally, the parent table (disease) has no way of knowing ahead of time if its children already have a reference to the "correct" record so allowing deletion, or if the child needs to change its own column data to reflect the new "correct" id.
So, how can I allow a change in the parent table (disease) and notify the child tables to change their column values -- and delete within them selves should a duplicate record arise?
Lastly, I do not know today what future tables I will need. So I cannot "precode" into the parent table who its children are or will be.
Thank you for any help with this.

Foreign key from multiple tables

I am thinking of three tables;
Employee with emp_id an, emp_name and other related data.
and
Person table with person_id, person_name and other related data.
and
GroupList with grp_list_id, member_id (either emp_id or person_id) and is_employee (true for employee and false for person) and other related data.
This is the first time I am trying to do a table whose foreign key can come from two different tables. Can someone please suggest the best way to achieve it?

PostgreSQL simple key vs composite key

We are going to store in PostgreSQL some info about organizations (in fact that is some entity, but I say "organization" just for clarity of structure). Each organization has 6 sublevels. First level - departments, second (inside departments) - sections etc. Each department (just like section and other) can have a unique name. We are thinking about 7 tables like
Table organizations
id (primary key) -- organization name
Table level_1
id (primary key) -- organization_id (foreign key) -- name
Table level_2
id (primary key) -- level_1_id (foreign key) -- name
etc
We suppose that on low levels (2-6) we can have thousands ob objects for each level.
The question is how we should construct the primary key - as simple key (like described above) or composite key. F.i.
Table level_1
id (primary key) -- organization_id (primary key) -- name
Table level_2
id (primary key) -- level_1_id (primary key) -- name
etc
What key type is better (first of all, faster for SELECT queries) and why?
Thank you.
IMHO, it's a bad design.
What will you do if you need to add a level ?
You'll need to add a table
You'll need to modify all your code, views...
Not very scalable...
You should have only one table.
Organizations
Id Parent_Id Name
Data Sample:
1 NULL Corporation
2 1 Division_1
3 1 Division_2
4 2 Dept_1_of_Division_1
5 2 Dept_2_of_Division_1
6 3 Dept_1_of_Division_2
To query this table, you would need to use WITH RECURSIVE

Constraint to avoid combination of foreign keys

I've here a problem that I couldn't find a proper solution on my researches, maybe it's because I couldn't find out the exact terms to search for it, so if this is a duplicate I will delete it.
My problem is I want to know if it is possible to avoid a combination of data between two fields. I will show the structure and the kind of data I want to avoid. It will be easier to understand.
Table_A Table_B
------------------------ -------------------------------
id integer (PK) id integer (PK)
description varchar(50) title varchar(50)
id1_fromA (FK A->id)
id2_fromA (FK A->id)
I'm trying to validate the following data on table Table_B (combination is between id1_fromA and id2_fromA)
id title id1_fromA id2_fromA
1 Some Title 1 2 --It will be permmited
2 Some other 1 2 --It is a duplicate NOT ALLOWED
3 One more 1 1 --It is equals NOT ALLOWED
4 Another 2 1 --It is same as registry id 1 so NOT ALLOWED
5 Sample data 3 2 --It is ok
With above data I can easily solve the problem for registry ID=2 with
ALTER TABLE table_B ADD CONSTRAINT UK_TO_A_FKS UNIQUE (id1_fromA, id2_fromA);
And the problem for registry ID=3 with
ALTER TABLE table_B ADD CONSTRAINT CHK_TO_A_FKS CHECK (id1_fromA != id2_fromA);
My Problem is with the registry ID=4 I want to avoid such duplicate of combination as 1,2=2,1. Is it possible to do it with a CONSTRAINT or an INDEX or an UNIQUE or I will need to create a trigger or a procedure to do so?
Thanks in advance.
You can't do this with a unique constraint, but you can do this with a unique index.
create unique index UK_TO_A_FKS
on table_b (least(id1_froma, id2_froma), greatest(id1_froma, id2_froma));