PostgreSQL Foreign Key -3
PRACTICAL 6.CHILD TABLE CAN HAVE MORE THAN ONE FOREIGN KEY CONSTRAINTS:
- A Child table can have more than one foreign key constraint. This is used to implement many-to-many relationships between tables.
- Say you have tables about Sales2,Products2 and Electronics2,Electronics2 table can have more referencing like sales2 and products2
Parent table_2(Referenced table):
postgres=# CREATE TABLE sales2 (
sales_id integer PRIMARY KEY,
price integer
);
Parent table_2(Referenced table):
postgres=# CREATE TABLE products2 (
product_name varchar,
product_category varchar,
product_id integer PRIMARY KEY
);
Child table(Referencing table):
postgres=# CREATE TABLE Electronics2 (
Electronics_name varchar,
Electroics_id integer REFERENCES products2(product_id),
Foreign key(Electroics_id) REFERENCES sales2(sales_id)
);
postgres=# \d sales2
Table "public.sales2"
Column | Type | Modifiers
----------+---------+-----------
sales_id | integer | not null
price | integer |
Indexes:
"sales2_pkey" PRIMARY KEY, btree (sales_id)
Referenced by:
TABLE "electronics2" CONSTRAINT "electronics2_electroics_id_fkey1" FOREIGN KEY (electroics_id) REFERENCES sales2(sales_id)
postgres=# \d products2
Table "public.products2"
Column | Type | Modifiers
------------------+-------------------+-----------
product_name | character varying |
product_category | character varying |
product_id | integer | not null
Indexes:
"products2_pkey" PRIMARY KEY, btree (product_id)
Referenced by:
TABLE "electronics2" CONSTRAINT "electronics2_electroics_id_fkey" FOREIGN KEY (electroics_id) REFERENCES products2(product_id)
postgres=# \d electronics2
Table "public.electronics2"
Column | Type | Modifiers
------------------+-------------------+-----------
electronics_name | character varying |
electroics_id | integer |
Foreign-key constraints:
"electronics2_electroics_id_fkey" FOREIGN KEY (electroics_id) REFERENCES products2(product_id)
"electronics2_electroics_id_fkey1" FOREIGN KEY (electroics_id) REFERENCES sales2(sales_id)
From above example electroics2 table in the column electroics_id having two referencing table one is column product_id in table of products2 and second one is column sales_id in table of sales2.
--Now let us make some inserting operation for understanding purposes
Parent1_1 table:
postgres=# insert into sales2 values(1,4000),(2,550),(3,430);
INSERT 0 3
postgres=# select * from sales2;
sales_id | price
----------+-------
1 | 4000
2 | 550
3 | 430
(3 rows)
parent_2 table:
postgres=# insert into products2 values('wire','electronics',1),('switch','electronics',2);
INSERT 0 2
postgres=# select * from products2;
product_name | product_category | product_id
--------------+------------------+------------
wire | electronics | 1
switch | electronics | 2
(2 rows)
postgres=# insert into electronics2 values('wire',1);
INSERT 0 1
postgres=# insert into electronics2 values('switch',2);
INSERT 0 1
postgres=# insert into electronics2 values('cables',3);
ERROR: insert or update on table "electronics2" violates foreign key constraint "electronics2_electroics_id_fkey"
DETAIL: Key (electroics_id)=(3) is not present in table "products2".
postgres=# select * from electronics2;
electronics_name | electroics_id
------------------+---------------
wire | 1
switch | 2
(2 rows)
Solution:
product_id 3 is not there in products2 table that is why it shown error.
postgres=# insert into products2 values('cable','electronics',3);
INSERT 0 1
postgres=# insert into electronics2 values('cables',3);
INSERT 0 1
--You cannot delete parent table rows if that rows having any reference,without reference row only can be deleted
postgres=# delete from sales2 where sales_id=3; ERROR: update or delete on table "sales2" violates foreign key constraint "electronics2_electroics_id_fkey1" on table "electronics2" DETAIL: Key (sales_id)=(3) is still referenced from table "electronics2".
But you can delete child table rows if that table having whether reference or not
postgres=# delete from electronics2 where electronics_name='wire'; DELETE 1
PRACTICAL 7.DELETING FOREIGN REFERENCE KEY ROWS:
- when someone wants to Delete a row of SALES3 table that is still referenced by an PRODUCTS3 table, It disallow to delete.
- If someone delete a row of CATEGORY3 table , the PRODUCTS3 are removed as well:
parent table -1:
CREATE TABLE SALES3 (
sales_id integer PRIMARY KEY,
price numeric
);
parent table -2:
CREATE TABLE CATEGORY3 (
category_id integer PRIMARY KEY,
cat_name text
);
Child table:
CREATE TABLE PRODUCTS3 (
product_no integer REFERENCES sales3(sales_id) ON DELETE RESTRICT,
order_id integer REFERENCES category3(category_id) ON DELETE CASCADE,
quantity integer,
PRIMARY KEY (product_no, order_id)
);
postgres=# \d sales3
Table "public.sales3"
Column | Type | Modifiers
----------+---------+-----------
sales_id | integer | not null
price | numeric |
Indexes:
"sales3_pkey" PRIMARY KEY, btree (sales_id)
Referenced by:
TABLE "products3" CONSTRAINT "products3_product_no_fkey" FOREIGN KEY (product_no) REFERENCES sales3(sales_id) ON DELETE RESTRICT
postgres=# \d category3
Table "public.category3"
Column | Type | Modifiers
-------------+---------+-----------
category_id | integer | not null
cat_name | text |
Indexes:
"category3_pkey" PRIMARY KEY, btree (category_id)
Referenced by:
TABLE "products3" CONSTRAINT "products3_order_id_fkey" FOREIGN KEY (order_id) REFERENCES category3(category_id) ON DELETE CASCADE
postgres=# \d products3
Table "public.products3"
Column | Type | Modifiers
------------+---------+-----------
product_no | integer | not null
order_id | integer | not null
quantity | integer |
Indexes:
"products3_pkey" PRIMARY KEY, btree (product_no, order_id)
Foreign-key constraints:
"products3_order_id_fkey" FOREIGN KEY (order_id) REFERENCES category3(category_id) ON DELETE CASCADE
"products3_product_no_fkey" FOREIGN KEY (product_no) REFERENCES sales3(sales_id) ON DELETE RESTRICT
Insert some valuse:
postgres=# delete from sales3 where price=400;
ERROR: update or delete on table "sales3" violates foreign key constraint "products3_product_no_fkey" on table "products3"
DETAIL: Key (sales_id)=(1) is still repostgres=# insert into sales3 values(1,400),(2,500),(3,1000);
INSERT 0 3
postgres=# insert into category3 values(1,'pendrive'),(2,'pen'),(3,'mouse');
INSERT 0 3
postgres=# insert into products3 values(1,1,50),(2,2,73),(3,3,65);
INSERT 0 3
Parent table-1:
postgres=# select * from sales3;
sales_id | price
----------+-------
1 | 400
2 | 500
3 | 1000
(3 rows)
Parent table -2:
postgres=# select * from category3;
category_id | cat_name
-------------+----------
1 | pendrive
2 | pen
3 | mouse
(3 rows)
Child table:
postgres=# select * from products3;
product_no | order_id | quantity
------------+----------+----------
1 | 1 | 50
2 | 2 | 73
3 | 3 | 65
(3 rows)ferenced from table "products3".
--Now we are going to delete sales3 table row,Below deleting particular row is referenced by products3
postgres=# delete from sales3 where price=400; ERROR: update or delete on table "sales3" violates foreign key constraint "products3_product_no_fkey" on table "products3" DETAIL: Key (sales_id)=(1) is still referenced from table "products3".
--Now we are going to delete category rows this table already having reference with "cascade" option that is why
postgres=# delete from category3 where category_id=1;
DELETE 1
postgres=# select * from category3;
category_id | cat_name
-------------+----------
2 | pen
3 | mouse
(2 rows)
postgres=# select * from products3;
product_no | order_id | quantity
------------+----------+----------
2 | 2 | 73
3 | 3 | 65
(2 rows)
When deleting a Row, PostgreSQL gives us the following main options:
- DELETE RESTRICT:PostgreSQL does not delete a row in the parent(SALES3) table until all referenced rows in the child(PRODUCTS3)table deleted. To achieve this, we use ON DELETE RESTRICT expression when we define a the foreign key constraint.
- DELETE CASCADE:PostgreSQL will delete all rows in the CHILD(PRODUCTS3) table that are referenced to the rows that are being deleted in the PARENT(CATEGORY) table
- NO ACTION:By default. With NO ACTION, PostgreSQL will raise an error if the referencing rows still exist when the constraint is checked.
To add a foreign key constraint to a table:
ALTER TABLE CHILD ADD CONSTRAINT KEY_NMAE FOREIGN KEY (CHILD_COLUMN_1) REFERENCES PARENT (PAREN_COLUMN_1) MATCH FULL;
--Constraint views:
postgres=# select a.conname,a.contype,a.conrelid,b.relname,b.relid from pg_constraint a,pg_stat_all_tables b
where a.conrelid=b.relid;
conname | contype | conrelid | relname | relid
----------------------------------+---------+----------+----------------+-------
products2_pkey | p | 25127 | products2 | 25127
orders1_product_no_fkey | f | 24937 | orders1 | 24937
orders1_pkey | p | 24937 | orders1 | 24937
car_sales_id_fkey | f | 24955 | car | 24955
car_pkey | p | 24955 | car | 24955
check_name3 | c | 24814 | village | 24814
sales1_product_name_key | u | 25018 | sales1 | 25018
sales1_reg_id_key | u | 25018 | sales1 | 25018
sales1_pkey | p | 25018 | sales1 | 25018
postgres_ord_no_key | u | 24715 | postgres | 24715
products1_pkey | p | 24929 | products1 | 24929
(10 rows)
Comments
Post a Comment