外键的使用大家都不陌生,是我们用于保持数据引用完整性的作用~辣今天我就分享一下外键的一些限制。
1、外键引用的是需要其它表的主键,或者候选键。(这个比较好理解,就不写代码了╮(╯_╰)╭)
2、外键创建之后并不会自动创建索引,这个是有开发人员自己考虑在外键上建相关索引是否能获取到查询效率上的提升
3、默认的情况下如果在引用表插入不存在的外键值或者在主表删除了一个被引用的数据,数据库都会报错。比如我们做个栗子
CREATE TABLE PK_Table ( ID INT IDENTITY(1,1) PRIMARY KEY, Name NVARCHAR(50) ) INSERT INTO dbo.PK_Table ( Name ) VALUES ( '主键1'),('主键2'); CREATE TABLE FK_Table1 ( ID INT PRIMARY KEY, PKID1 INT CONSTRAINT FK_1 FOREIGN KEY REFERENCES PK_Table(ID) ON DELETE NO ACTION, Name NVARCHAR(50) UNIQUE ) INSERT INTO dbo.FK_Table1 ( ID,PKID1, Name ) VALUES ( 1,1,N'外键1' ),( 2,2,N'外键2' ); CREATE TABLE FK_Table1_1 ( ID INT IDENTITY(1,1) PRIMARY KEY, FKID1 INT CONSTRAINT FK_1_1 FOREIGN KEY REFERENCES FK_Table1(ID) ON DELETE NO ACTION, Name NVARCHAR(50) ) INSERT INTO dbo.FK_Table1_1 ( FKID1, Name ) VALUES ( 1,N'外键1_1' ),( 1,N'外键1_2' ),( 2,N'外键2_1' ),( 2,N'外键2_2' );
然后删除一条
DELETE FROM dbo.PK_Table WHERE ID = 2 或者 DELETE FROM dbo.FK_Table1 WHERE ID = 2
数据库直接抛错~正常嘛,人家就是这样纸定义的。
但是其实行为并不止 NO ACTION 一种,还有CASCADE (级联删除), SET NULL(设置空) 和 SET DEFAULT(设置默认值) 3种行为的 字面上比较好理解。
SET NULL 和 SET DEFAULT 就比较好理解就不说了~
级联的话如果定义了就一定要小心。 还是定义刚刚的Table 只是将FK_Table1 改成 CASCADE
CREATE TABLE PK_Table ( ID INT IDENTITY(1,1) PRIMARY KEY, Name NVARCHAR(50) ) INSERT INTO dbo.PK_Table ( Name ) VALUES ( '主键1'),('主键2'); CREATE TABLE FK_Table1 ( ID INT PRIMARY KEY, PKID1 INT CONSTRAINT FK_1 FOREIGN KEY REFERENCES PK_Table(ID) ON DELETE CASCADE, Name NVARCHAR(50) UNIQUE ) INSERT INTO dbo.FK_Table1 ( ID,PKID1, Name ) VALUES ( 1,1,N'外键1' ),( 2,2,N'外键2' ); CREATE TABLE FK_Table1_1 ( ID INT IDENTITY(1,1) PRIMARY KEY, FKID1 INT CONSTRAINT FK_1_1 FOREIGN KEY REFERENCES FK_Table1(ID) ON DELETE NO ACTION, Name NVARCHAR(50) )
然后一删除~
DELETE FROM dbo.PK_Table WHERE ID = 2
DELETE 语句与 REFERENCE 约束"FK_1"冲突。该冲突发生于数据库"Test",表"dbo.FK_Table1", column 'PKID1'。
其实就是因为 FK_Table1 的行不能删除引起的~所以,如果定义了CASADE 要注意多层嵌套的使用