FOREIGN KEY約束添加規則 1、外鍵約束並不僅僅可以與另一表的主鍵約束相鏈接,它還可以定義為引用另一個表中 UNIQUE 約束的列。 2、如果在 FOREIGN KEY 約束的列中輸入非 NULL 值,則此值必須在被引用列中存在;否則,將返回違反外鍵約束的錯誤信息。 若要確保驗證了組合外鍵約 ...
FOREIGN KEY約束添加規則
1、外鍵約束並不僅僅可以與另一表的主鍵約束相鏈接,它還可以定義為引用另一個表中 UNIQUE 約束的列。
2、如果在 FOREIGN KEY 約束的列中輸入非 NULL 值,則此值必須在被引用列中存在;否則,將返回違反外鍵約束的錯誤信息。 若要確保驗證了組合外鍵約束的所有值,請對所有參與列指定 NOT NULL。
3、FOREIGN KEY 約束僅能引用位於同一伺服器上的同一資料庫中的表。 跨資料庫的引用完整性必須通過觸發器實現。
4、FOREIGN KEY 約束可引用同一表中的其他列。 此行為稱為自引用。
5、在列級指定的 FOREIGN KEY 約束只能列出一個引用列。 此列的數據類型必須與定義約束的列的數據類型相同。
6、在表級指定的 FOREIGN KEY 約束所具有的引用列數目必須與約束列列表中的列數相同。 每個引用列的數據類型也必須與列表中相應列的數據類型相同。
7、對於表可包含的引用其他表的 FOREIGN KEY 約束的數目或其他表所擁有的引用特定表的 FOREIGN KEY 約束的數目, 資料庫引擎 都沒有預定義的限制。 儘管如此,可使用的 FOREIGN KEY 約束的實際數目還是受硬體配置以及資料庫和應用程式設計的限制。 表最多可以將 253 個其他表和列作為外鍵引用(傳出引用)。 SQL Server 2016 (13.x) 將可在單獨的表中引用的其他表和列(傳入引用)的數量限制從 253 提高至 10,000。 (相容性級別至少必須為 130。)數量限制的提高帶來了下列約束:
DELETE 和 UPDATE DML 操作支持大於 253 個外鍵引用。 不支持 MERGE 操作。
對自身進行外鍵引用的表仍只能進行 253 個外鍵引用。
列存儲索引、記憶體優化表和 Stretch Database 暫不支持進行超過 253 個外鍵引用。
8、對於臨時表不強制 FOREIGN KEY 約束。
9、如果在 CLR 用戶定義類型的列上定義外鍵,則該類型的實現必須支持二進位排序。
10、僅當 FOREIGN KEY 約束引用的主鍵也定義為類型 varchar(max) 時,才能在此約束中使用類型為varchar(max) 的列。
使用SSMS資料庫管理工具添加外鍵約束
本示例演示當表結構已存在時添加外鍵約束,創建表時添加外鍵約束步驟和表結構存在時添加外鍵步驟相同。示例演示如下:
1、連接資料庫,打開要添加外鍵的數據表-》右鍵點擊-》選擇設計。
2、在表設計視窗-》選擇要添加外鍵的數據行-》右鍵點擊-》選擇關係。
3、在外鍵關係視窗中-》點擊添加。
4、添加完畢後-》首先修改表和列規範。
5、在表和列視窗中-》輸入外鍵名-》在左邊選擇主表和關聯的列-》在右邊選擇從表和作為外鍵的列-》點擊確定。
6、在外鍵關係視窗中-》可選擇添加或者不添加外鍵描述-》可選擇添加或者不添加修改或者刪除數據時級聯操作-》可選擇添加或者不添加強制外鍵約束-》可選擇添加或者不添加強制用於複製-》點擊關閉。
7、點擊保存按鈕(ctrl+s)-》此時表會彈出警告視窗,點擊是-》刷新查看外鍵是否添加成功。
使用T-SQL腳本添加外鍵約束
當表結構已存在時
如果要添加約束的表已存在外鍵約束,需要先刪除外鍵約束再添加外鍵約束。如果不存在外鍵約束可以添加外鍵約束。
語法:
if exists(select * from sysobjects where name=約束名)
alter table 資料庫名.[dbo].表名 drop constraint 約束名;
alter table 資料庫名.[dbo].表名 with check add constraint 約束名 foreign key(列名)
references 資料庫名.[dbo].表名(列名)
on delete cascade
on update cascade;
go
示例:
if exists(select * from sysobjects where name='t1_t2')
alter table [testss].[dbo].[test1] drop constraint t1_t2;
alter table [testss].[dbo].[test1] with check add constraint t1_t2 foreign key(classid)
references [testss].[dbo].[test2](id)
on delete cascade
on update cascade;
go
在新表中創建外鍵
語法:
if exists( select * from sysobjects where name=表名 and type ='U')
drop table 表名;
go
--當表結構不存在時
--建表語法聲明
create table 表名
(
--欄位聲明
列名 int identity(1,1) not null,
列名 int,
primary key clustered(id asc) with(ignore_dup_key=off) on [primary], --主鍵索引聲明
constraint 外鍵名 foreign key(列名)
references 主表名(列名)
on update cascade--是否級聯操作
on delete cascade
)on [primary]
--欄位註釋聲明
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'列說明' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'表名', @level2type=N'COLUMN',@level2name=N'列名';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'列說明' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'表名', @level2type=N'COLUMN',@level2name=N'列名';
go
示例:
if exists( select * from sysobjects where name='test1'and type ='U')
drop table test1;
go
--當表結構不存在時
--建表語法聲明
create table test1
(
--欄位聲明
id int identity(1,1) not null,
name nvarchar(50) null,
sex nvarchar(50) null,
age nvarchar(50) null,
classid int,
primary key clustered(id asc) with(ignore_dup_key=off) on [primary], --主鍵索引聲明
constraint t3_t4 foreign key(classid)
references test2 (id)
on update cascade
on delete cascade
)on [primary]
--欄位註釋聲明
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'id主鍵' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'id';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'姓名' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'name';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'性別' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'sex';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'年齡' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'age';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'班級id' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'classid';
go
FOREIGN KEY約束優缺點
優點:
1、保證數據的一致性,完整性,更可靠。
2、關聯查詢時,可以用到FK 的統計信息。
3、有主外鍵的資料庫設計可以增加ER圖的可讀性。
缺點:
1、刪隊或更新關聯數據時需要做檢查,效率會很低。
2、手工調數據時,會存在主從表校驗,會比較麻煩。
3、批量導入數據時,會存在外鍵校驗,需要先關閉外鍵約束,導入完成再打開外鍵約束,操作比較麻煩。