Postgresql外键约束级联删除时容易忽略的问题

外键约束用来实现表与表之间的参照完整性(referential integrity)。
外键约束是指一个引用表(referencing table)中的一个或多个引用字段(referencing column)必须与另一个被引用表(referenced table)中相应的被引用字段(referenced column)匹配,而且类型和值都必须匹配。
被引用表(referenced table)中的被引用列(referenced column)必须是一个非延迟的唯一约(unique key)束或者主键约束(primary key)。

外键约束可以设置级联删除。
设表B的字段y引用了表A的字段x(primary key or unique constraint),并设置了级联删除。当表A的某条记录删除时(x=x0),表B的某条记录(如果存在)也要被删除。
容易出现的问题:如果表B的字段y上没有建索引,删除表B记录时就会使用顺序扫描(Seq Scan)。当表B记录条数较多时顺序扫描会消耗较长时间。
解决方法:
表B的字段y增加索引。

1、创建索引的好处

–帮助用户提高查询速度 

–利用索引的唯一性来控制记录的唯一性 
–可以加速表与表之间的连接 
–降低查询中分组和排序的时间 
2、创建索引的坏处
–存储索引占用磁盘空间
–执行数据修改操作(INSERT、UPDATE、DELETE)产生索引维护

 

注意:没有索引的话  会全表查找,效率非常慢

索引可以建可以不建 
如果涉及查找的话,最好建索引。

上面引用原文:https://www.jianshu.com/p/fb1fab048584

https://blog.csdn.net/qq_29784441/article/details/80887544

附录:postgre所有外键设置级联删除语句

; WITH CTE AS (
SELECT
	KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME,
	KCU1.TABLE_SCHEMA AS FK_SCHEMA_NAME,
	KCU1.TABLE_NAME AS FK_TABLE_NAME,
	KCU1.COLUMN_NAME AS FK_COLUMN_NAME,
	KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION,
	KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME,
	KCU2.TABLE_SCHEMA AS REFERENCED_SCHEMA_NAME,
	KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME,
	KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME,
	KCU2.ORDINAL_POSITION AS REFERENCED_ORDINAL_POSITION 
FROM
	INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
	INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG 
	AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA 
	AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
	INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2 ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG 
	AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA 
	AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME 
	AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION 
	) SELECT
	QUOTE_IDENT ( REFERENCED_TABLE_NAME ),
	FK_SCHEMA_NAME,
	FK_TABLE_NAME,
	FK_CONSTRAINT_NAME,
	FK_COLUMN_NAME,
	REFERENCED_COLUMN_NAME,
	'ALTER TABLE ' || QUOTE_IDENT ( FK_SCHEMA_NAME ) || '.' || QUOTE_IDENT ( FK_TABLE_NAME ) || ' ' || 'DROP CONSTRAINT ' || QUOTE_IDENT ( FK_CONSTRAINT_NAME ) || '; ' AS DropStmt,
'ALTER TABLE ' || QUOTE_IDENT ( FK_SCHEMA_NAME ) || '.' || QUOTE_IDENT ( FK_TABLE_NAME ) || ' 
ADD CONSTRAINT ' || QUOTE_IDENT ( FK_CONSTRAINT_NAME ) || ' 
FOREIGN KEY(' || string_agg ( FK_COLUMN_NAME, ', ' ) || ') 
' || '    REFERENCES ' || QUOTE_IDENT ( REFERENCED_SCHEMA_NAME ) || '.' || QUOTE_IDENT ( REFERENCED_TABLE_NAME ) || '(' || string_agg ( REFERENCED_COLUMN_NAME, ', ' ) || ') 
ON DELETE CASCADE 
	; ' AS CreateStmt,
'create index ' || QUOTE_IDENT ( FK_TABLE_NAME ) || '__' || string_agg ( FK_COLUMN_NAME, ', ' ) || '__index  ON ' || QUOTE_IDENT ( FK_SCHEMA_NAME ) || '.' || QUOTE_IDENT ( FK_TABLE_NAME ) || ' ' || '(' || string_agg ( FK_COLUMN_NAME, ', ' ) || ') ' || '; ' AS createIndexStmt 
FROM
	CTE 
GROUP BY
	QUOTE_IDENT ( REFERENCED_TABLE_NAME ),
	FK_SCHEMA_NAME,
	FK_TABLE_NAME,
	FK_CONSTRAINT_NAME,
	FK_COLUMN_NAME,
	REFERENCED_COLUMN_NAME,
	REFERENCED_SCHEMA_NAME,
	REFERENCED_TABLE_NAME 
ORDER BY
	FK_SCHEMA_NAME,
	FK_TABLE_NAME;

其中分别通过DropStmt列和CreateStmt列,进行外键删除和重建外键并设置级联删除操作

通过createIndexStmt列创建外键索引,提高级联删除操作时的效率。

你可能感兴趣的:(Postgresql外键约束级联删除时容易忽略的问题)