1. 程式人生 > >談談唯一約束和唯一索引

談談唯一約束和唯一索引

最近在看資料庫相關知識,感覺唯一約束和唯一索引好像有點類似,於是研究了一番,於是就有了這篇文章。

概念

開始之前,先解釋一下約束和索引。

約束 全稱完整性約束,它是關係資料庫中的物件,用來存放插入到一個表中一列資料的規則,用來確保資料的準確性和一致性。

索引 資料庫中用的最頻繁的操作是資料查詢,索引就是為了加速表中資料行的檢索而建立的一種分散的資料結構。可以把索引類比成書的目錄,有目錄的肯定比沒有目錄的書,更方便查詢。

唯一約束 保證在一個欄位或者一組欄位裡的資料都與表中其它行的對應資料不同。和主鍵約束不同,唯一約束允許為 NULL,只是只能有一行。

唯一索引 不允許具有索引值相同的行,從而禁止重複的索引或鍵值。

唯一約束和唯一索引都是為了保證表中被限制的欄位不允許有重複的值,看起來功能是一樣的,那為什麼要設計這樣兩種一樣的功能呢?

探究

帶著這個問題,我在網上搜索了一番。

這裡寫圖片描述

大概意思是說,他看了一本關於 Oracle 的書,書中說,唯一約束和唯一索引是不同的,但是書中沒解釋這兩個有什麼不同。

然後下面跟了一個答案如下

這裡寫圖片描述

大意是說,約束和索引是不同的,約束為優化提供了更多資訊,並且允許在唯一約束上建立外來鍵,而唯一索引是不行的,然後還提供了一個小例子。

不能聽他說兩句就相信了,本著實踐出真理的原則,我做了下面的求證。儘管文章中提到的是 Oracle 資料庫,而我本地的是 MySQL,不過還是決定試一遍,按照他給出的例子,在本地做了如下測試。

首先建立兩個欄位值一樣的表 t1,t2,併為 t1 表中的 col1 列設定唯一約束。

CREATE TABLE t1 (
    col1 INT(11), 
    col2 VARCHAR(20), 
    CONSTRAINT t1_uq UNIQUE (col1)
);

CREATE TABLE t2 (
    col1 INT(11), 
    col2 VARCHAR(20)
);

執行結果

這裡寫圖片描述

然後為表 t2 表中的 col1 列設定唯一索引

CREATE UNIQUE INDEX 
    t2_idx ON t2 (col1);

執行結果

這裡寫圖片描述

建立表 t3,並將 t1 表中的 col1 列設定為 t3 表中 col2 列的外來鍵

CREATE TABLE t3 (
    col1 INT(11), 
    col2 INT(11), 
    col3 VARCHAR(20), 
    CONSTRAINT t3_fk FOREIGN KEY (col2) REFERENCES t1 (col1)
);

執行結果

這裡寫圖片描述

建立表 t4,並將 t2 表中的 col1 列設定為 t4 表中 col2 列的外來鍵

CREATE TABLE t4 (
    col1 INT(11), 
    col2 INT(11), 
    col3 VARCHAR(20), 
    CONSTRAINT t4_fk FOREIGN KEY (col2) REFERENCES t2 (col1)
);

重點來了,根據上面回答唯一約束和唯一索引的區別,t4 表應該是建不成功的,因為 t4 表中 col2 列依賴於 t2 表中 col1 列,而 t2 表中的 col1 列建立了唯一索引,並沒有建立唯一約束,因此 t4 表應該建立失敗。

然而,執行結果如下

這裡寫圖片描述

是的,沒有看錯,表 t4 建立成功了,並沒有報錯,也沒有出現上面回答中提到的結果。

為什麼會這樣呢,首先想到的就是不同的資料庫對這一點的實現方式不同,Oracle 資料庫下會是這樣的區別,其它資料庫就不一定了。

正好,電腦上裝的有 SQL Server 2008,在 SQL Server 依次執行了一遍,也都成功了,沒出現上面提到的問題。

難道只有 Oracle 資料庫裡才有那樣的區別,如果你電腦上剛好有 Oracle,可以幫我試一下。

再探求

難道唯一約束和唯一索引,在 MySQL 和 SQL Server 裡真的一點區別都沒有嗎?

用 Navicat 開啟剛剛在 MySQL 資料庫裡建好的表,看下錶定義

表 t1 DDL

這裡寫圖片描述

表 t2 DDL

這裡寫圖片描述

表 t1 是直接在建表時對 col1 列定義唯一約束的,而表 t2 是建立完成後,通過修改表才對 col1 列建立唯一索引的。但是最終兩個表的 DDL 完全一樣,說明在 MySQL 資料庫裡唯一約束和唯一索引只是概念不同,在不同的功能中叫法不同罷了,其實現方式是完全一樣的。

再次用 Navicat 開啟剛剛在 SQL Server 資料庫裡建好的表,看下錶定義

表 t1 DDL

這裡寫圖片描述

表 t2 DDL

這裡寫圖片描述

可以看出,和 MySQL 資料庫不同,SQL Server 資料庫下,表 t1 為 col1 列建立了唯一約束,表 t2 為 col1 列建立了唯一索引,但是表 t3 和 t4 也被成功建立了,可見最終的結果還是一樣,也即沒有證明上面那個回答。至於 SQL Server 下除此之外,還有沒有其它的區別,在我搜索的答案中暫時還沒發現,如果你發現了,歡迎回復交流。

總結

到此為止,基本上就能得出,唯一約束和唯一索引在 MySQL 資料庫裡區別了

  1. 概念上不同,約束是為了保證資料的完整性,索引是為了輔助查詢;
  2. 建立唯一約束時,會自動的建立唯一索引;
  3. 在理論上,不一樣,在實際使用時,基本沒有區別。

關於第二條,MySQL 中唯一約束是通過唯一索引實現的,為了保證沒有重複值,在插入新記錄時會再檢索一遍,怎樣檢索快,當然是建索引了,所以,在建立唯一約束的時候就建立了唯一索引。

相關推薦

談談唯一約束唯一索引

最近在看資料庫相關知識,感覺唯一約束和唯一索引好像有點類似,於是研究了一番,於是就有了這篇文章。 概念 開始之前,先解釋一下約束和索引。 約束 全稱完整性約束,它是關係資料庫中的物件,用來存放插入到一個表中一列資料的規則,用來確保資料的準確性和一致性。

oracle 唯一約束 唯一索引

唯一性約束 唯一性約束指表中一個欄位或者多個欄位聯合起來能夠唯一標識一條記錄的約束。聯合欄位中,可以包含空值。 注:在Oracle中,唯一性約束最多可以有32列。 唯一性約束可以在建立表時或使用ALTER TABLE語句建立。 唯一性約束和主鍵的區別 主鍵(Primary

資料庫MySQL之主鍵約束唯一約束是什麼?

資料庫MySQL之主鍵約束、唯一約束是什麼? 文章目錄 1. 主鍵約束 2. 唯一約束 2.1 UNIQUE KEY 1. 主鍵約束 主鍵可以寫為PRIMARY KEY,也可以寫成KEY 每張資

唯一約束檢查約束(oracle)

1.唯一約束和主鍵區別 主鍵欄位值必須是非空的 唯一約束允許有一個空值 2.唯一約束關鍵字:unique 3.在建立表時設定唯一約束 constraint  constraint_name  unique( column_name) 4.在修改表新增唯一約

MYSQL(4) 記錄的插入與查詢 主鍵約束唯一約束

1.插入記錄    INSERT [INTO] tb_name [(col_name,……)] VALUES(val,……);    如果欄位名稱不寫,預設為所有欄位賦值2.記錄查詢 SELECT * FROM tb_name;3.MYSQL空值與非空    NULL 欄位值

oracle 唯一索引唯一約束,主鍵之間的聯系

檢查 特性 dad cda 聯系 其它 分享圖片 ges oracl 主鍵(primary key)是表中的一個或多個字段,它的值用於唯一地標識表中的某一條記錄,在兩個表的關系中,主鍵用來在一個表中引用來自於另一個表中的特定記錄,,主鍵時一種唯一關鍵字,表定義的一部分。一個

【數論】Sumdiv(整數的唯一分解定理+約束公式+遞歸求等比)

ali 同余模公式 left 一個 c++ 出現 素數分解 code 特殊 來源:https://blog.csdn.net/lyy289065406/article/details/6648539 題目描述 Consider two natural numbers A a

數據庫數據插入,空值非空判斷,自動排序,約束主鍵,唯一約束,外健約束

.com auto 設置 添加數據 name inf 表結構 alt incr 1.查看表結構 2.插入數據 3.空值和非空判斷 如上圖,添加數據默認為null,如果我們不想要為空,則 如圖,username設置為not null,則插入數據的時候如

普通索引唯一索引的區別、性能差異,以及其他索引簡介

整數 排列 唯一索引 同名 關聯 超過 結果 其它 加載 唯一索引和普通索引使用的結構都是B-tree,執行時間復雜度都是O(log n)。 1、普通索引  普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對數據的訪問速度。因此,應該只為那些最經常出現在查

oracle新增、刪除、啟用、禁用主鍵唯一約束

-- 新增主鍵約束 -- 第一種寫法簡單,但constraint名稱由oracle確定,含義不明確,如SYS_C007490 alter table t modify id primary key; alter table t add constraint t_pk primary ke

唯一索引普通索引的區別

一、背景介紹 索引用來快速地尋找那些具有特定值的記錄,如果沒有索引,執行查詢時Mysql必須從第一個記錄開始掃描整個表的所有記錄,直至找到符合要求的記錄,表裡面的記錄數量越多,這個操作的代價就越高,如果作為搜尋條件的列上已經建立了索引,mysql無需掃描任何記錄即可迅速得到目標記錄所在的位置。如

普通索引唯一索引的區別

轉自:https://blog.csdn.net/u014071328/article/details/78780683 唯一索引和普通索引使用的結構都是B-tree,執行時間複雜度都是O(log n)。 1、普通索引   普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快

普通索引唯一索引的選擇

一 查詢過程:普通索引是找到葉子節點,然後再葉子節點中二分法找到那條記錄,然後向後找,找不到就停止,然後回表。 唯一索引是找到一條就不找了,因為是唯一的。效能差別不到。 資料庫查詢記錄,首先是把這條記錄的所在的頁全部載入到記憶體中,16k, 二 更新過程:更新過程普通索引會用change buffer

主鍵(primary key)唯一索引(unique index)區別

主鍵一定是唯一性索引,唯一性索引並不一定就是主鍵。 所謂主鍵就是能夠唯一標識表中某一行的屬性或屬性組,一個表只能有一個主鍵,但可以有多個候選索引。因為主鍵可以唯一標識某一行記錄,所以可以確保執行資料更新、刪除的時候不會出現張冠李戴的錯誤。主鍵除了上述作用外,常常與外來鍵構成參照完整性約束,防止出現數

sql:主鍵(primary key)唯一索引(unique index)區別

主鍵一定是唯一性索引,唯一性索引並不一定就是主鍵。  所謂主鍵就是能夠唯一標識表中某一行的屬性或屬性組,一個表只能有一個主鍵,但可以有多個候選索引。因為主鍵可以唯一標識某一行記錄,所以可以確保執行資料更新、刪除的時候不會出現張冠李戴的錯誤。主鍵除了上述作用外,常常與外來鍵構成參照完整性約束

【轉】Mysql學習-索引總結(B-treehash、主鍵索引唯一索引、普通索引、全文索引組合索引)

常用的兩種索引結構:B-tree和HASH B-tree   B-tree索引能夠加快訪問資料的速度,因為儲存引擎不再需要經行全表掃描來獲取需要的資料,取而代之的是從根節點開始搜尋。根節點的槽中存放了指向子節點的指標,儲存引擎根據這些指標向下查詢。通常比較節點頁的值和要查詢的值可以找

唯一性約束、主鍵約束唯一索引的區別

1.主鍵約束(PRIMARY KEY) 主鍵用於唯一地標識表中的每一條記錄 可以定義一列或多列為主鍵 主鍵列上沒有任何兩行具有相同值(即重複值) 主鍵列上也不能為空值 2.唯一性約束(UNIQUE) 唯一性約

主鍵唯一索引有什麼區別

CREATE TABEL T( ID INT ); CREATE UNIQUE INDEX T_INDEX_ID ON T(ID); 和 CREATE TABEL T( ID INT PRIMARY KEY );   主鍵是表中的一個或多個欄位,它的值用於惟一地標識表中的某一條記錄.;使用索引可快速訪問資料

MySQL 普通索引唯一索引索引

1、普通索引   普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件(WHEREcolumn=)或排序條件(ORDERBYcolumn)中的資料列建立索引。只要有可能,就應該選擇一個數據最整齊、最緊湊

普通索引唯一索引的區別、效能差異,以及其他索引簡介

今天在我的虛擬機器中佈置了環境,測試抓圖如下: 抓的這幾個都是第一次執行的,刷了幾次後,取平均值,效率大致相同,而且如果在一個列上同時建唯一索引和普通索引的話,mysql會自動選擇唯一索引。 谷歌一下: 唯一索引和普通索引使用的結構都是B-tree,執行時間複