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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...