SQLServer之FOREIGN KEY約束

来源:https://www.cnblogs.com/vuenote/archive/2018/09/01/9570821.html
-Advertisement-
Play Games

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、批量導入數據時,會存在外鍵校驗,需要先關閉外鍵約束,導入完成再打開外鍵約束,操作比較麻煩。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 【原文】https://www.toutiao.com/i6593191234326495752/ 一、硬碟 硬碟最怕的是震動,大的震動會讓磁頭組件碰到碟片上,劃傷了可就壞大事了,修都不好修,最重要的是你的數據可就沒了——你的心血喲! 二、主板 主板最怕的是靜電和形變。靜電可能會弄壞BIOS晶元和數... ...
  • 一. Linux文件系統路徑說明 熟悉windows系統的,都知道文件路徑表示,如C:\User\rich\Documnets\test.doc。 在linux中目錄稱為虛擬目錄(virtual directory) 根目錄是root,根目錄下的目錄和文件會按照訪問它們的目錄路徑一一列出。如:/ho ...
  • FTP全名是File Transfer Protocol(文件傳輸協議) C/S架構 簡介: 下麵是關於FTP這個服務的屬性 (1)FTP服務相關軟體 IIS Serv-U Vsftpd proftpd pureftpd (2)FTP客戶端相關軟體 ftp命令 CuteFTP FlashFTP Le ...
  • 變數名 含義 ARGC 命令行變元個數 ARGV 命令行變元數組 FILENAME 當前輸入文件名 FNR 當前文件中的記錄號 FS 輸入域分隔符,預設為一個空格 RS 輸入記錄分隔符 NF 當前記錄里域個數 NR 到目前為止記錄數 OFS 輸出域分隔符 ORS 輸出記錄分隔符 1、awk '/10 ...
  • Linux Namespaces機制提供一種資源隔離方案。 PID,IPC,Network等系統資源不再是全局性的,而是屬於特定的Namespace。每個Namespace裡面的資源對其他Namespace都是透明的。 要創建新的Namespace,只需要在調用clone時指定相應的flag。 Li ...
  • 常見的linux指令 1、ls ll 查看文件信息 2、cd 切換工作目錄 cd 或 cd ~ 切換到/home/用戶目錄 cd. 切換到當前目錄 cd.. 切換到上級目錄 cd- 切換入上次所在的目錄 3、clear 或 ctrl + l 清屏 4、pwd 顯示當前路徑 5、mkdir 創建目錄 ...
  • 初學mysql時,可能不太明白delimiter的真正用途,delimiter在mysql很多地方出現,比如存儲過程、觸發器、函數等。 學過oracle的人,再來學mysql就會感到很奇怪,百思不得其解。 其實就是告訴mysql解釋器,該段命令是否已經結束了,mysql是否可以執行了。預設情況下,d ...
  • 當MySQL單表記錄數過大時,增刪改查性能都會急劇下降,可以參考以下步驟來優化:除非單表數據未來會一直不斷上漲,否則不要一開始就考慮拆分,拆分會帶來邏輯、部署、運維的各種複雜度,一般以整型值為主的表在千萬級以下,字元串為主的表在五百萬以下是沒有太大問題的。而事實上很多時候MySQL單表的性能依然有不... ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...