主鍵、唯一鍵與唯一索引的區別

来源:http://www.cnblogs.com/roucheng/archive/2016/05/29/weiyi.html
-Advertisement-
Play Games

一般,我們看到術語“索引”和“鍵”交換使用,但實際上這兩個是不同的。索引是存儲在資料庫中的一個物理結構,鍵純粹是一個邏輯概念。鍵代表創建來實施業務規則的完整性約束。索引和鍵的混淆通常是由於資料庫使用索引來實施完整性約束。 接下來我們看看資料庫中的主鍵約束、唯一鍵約束和唯一索引的區別。 SQL> se ...


一般,我們看到術語“索引”和“鍵”交換使用,但實際上這兩個是不同的。索引是存儲在資料庫中的一個物理結構,鍵純粹是一個邏輯概念。鍵代表創建來實施業務規則的完整性約束。索引和鍵的混淆通常是由於資料庫使用索引來實施完整性約束。

 

接下來我們看看資料庫中的主鍵約束、唯一鍵約束和唯一索引的區別。

SQL> select * from v$version;

 

 

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

PL/SQL Release 11.2.0.1.0 - Production

CORE    11.2.0.1.0      Production

TNS for Linux: Version 11.2.0.1.0 - Production

NLSRTL Version 11.2.0.1.0 - Production

 

SQL> create table test (          

  2  id int,

  3  name varchar2(20),

  4  constraint pk_test primary key(id))

  5  tablespace users;

 

Table created.

 

SQL> select constraint_name, constraint_type from user_constraints;

 

CONSTRAINT_NAME                C

------------------------------ -

PK_TEST                        P

 

在test表中,我們指定了ID列作為主鍵,Oracle資料庫會自動創建一個同名的唯一索引:

SQL> select index_name, index_type, uniqueness, tablespace_name

  2  from user_indexes

  3  where table_owner='SCOTT'

  4  and table_name = 'TEST';

 

INDEX_NAME           INDEX_TYPE           UNIQUENES TABLESPACE_NAME

-------------------- -------------------- --------- ------------------------------

PK_TEST              NORMAL               UNIQUE    USERS

 

此時,如果我們再試圖在ID列上創建一個唯一索引,Oracle會報錯,因為該列上已經存在一個唯一索引:

SQL> create unique index idx_test_uk on test(id);

create unique index idx_test_uk on test(id)

                                        *

ERROR at line 1:

ORA-01408: such column list already indexed

即使創建非唯一索引也不行:

SQL> create index idx_test_id on test(id);

create index idx_test_id on test(id)

                                 *

ERROR at line 1:

ORA-01408: such column list already indexed

 

 

那麼唯一鍵約束的情況是怎樣的呢?

SQL> drop table test purge;

 

Table dropped.

 

SQL> create table test(

  2  id int,

  3  name varchar2(20),

  4  constraint uk_test unique(id));

 

Table created.

 

SQL> select constraint_name, constraint_type from user_constraints;

 

 

CONSTRAINT_NAME                C

------------------------------ -

UK_TEST                        U

 

查看此時的索引情況:

SQL> select index_name, index_type, uniqueness, tablespace_name

  2  from user_indexes

  3  where table_owner='SCOTT'

  4  and table_name = 'TEST';

 

INDEX_NAME           INDEX_TYPE           UNIQUENES TABLESPACE_NAME

-------------------- -------------------- --------- ------------------------------

UK_TEST              NORMAL               UNIQUE    USERS

Oracle同樣自動創建了一個同名的唯一索引,而且也不允許再在此列上創建唯一索引或非唯一索引。

 

 

 

我們知道,主鍵約束要求列值非空(NOT NULL),那麼唯一鍵約束是否也要求非空呢?

SQL> insert into test values(1, 'Sally');

 

1 row created.

 

SQL> insert into test values(null, 'Tony');

 

1 row created.

 

SQL> insert into test values(null, 'Jack');

 

1 row created.

 

SQL> select * from test;

 

        ID NAME

---------- --------------------

         1 Sally

           Tony

           Jack

從實驗結果來看,唯一鍵約束並沒有非空要求。

 

接下來我們看看唯一索引對列值的非空要求有什麼不同。

SQL> drop table test purge;

 

Table dropped.

 

SQL> create table test(

  2  id int,

  3  name varchar2(20));

 

Table created.

 

SQL> create unique index idx_test_id on test (id);

 

Index created.

 

SQL> insert into test values(1, 'Sally');

 

1 row created.

 

SQL> insert into test values(null, 'Tony');

 

1 row created.

 

SQL> insert into test values(null, 'Jack');

 

1 row created.

 

SQL> select * from test;

 

        ID NAME

---------- --------------------

         1 Sally

           Tony

           Jack

通過實驗,我們看出唯一索引與唯一鍵約束一樣對列值非空不做要求。

 

如果我們讓主鍵約束或者唯一鍵約束失效,Oracle自動創建的唯一索引是否會受到影響?

SQL> drop table test purge;

 

Table dropped.

 

SQL> create table test(

  2  id int,

  3  name varchar2(20),

  4  constraint uk_test unique(id));

 

Table created.

 

SQL> select index_name, index_type, uniqueness from user_indexes;

 

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

------------------------------ --------------------------- ---------

UK_TEST                        NORMAL                      UNIQUE

 

SQL> alter table test disable constraint uk_test;

 

 

Table altered.

 

SQL> select index_name, index_type, uniqueness from user_indexes;

 

no rows selected

當主鍵約束或者唯一鍵約束失效時,Oracle會刪除隱式創建的唯一索引。

 

如果我們先創建唯一索引,再創建主鍵或者唯一鍵約束,情況又會怎樣呢?

SQL> drop table test purge;

 

Table dropped.

 

SQL> create table test(

  2  id int,

  3  name varchar2(20));

 

Table created.

 

SQL> create unique index idx_test_id on test (id);

 

Index created.

 

SQL> select index_name, index_type, uniqueness

  2  from user_indexes

  3  where table_owner = 'SCOTT'

  4  and table_name = 'TEST';

 -- 何問起 hovertree.com 

 

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

------------------------------ --------------------------- ---------

IDX_TEST_ID                    NORMAL                      UNIQUE

 

SQL> alter table test add constraint uk_test unique (id);

 

Table altered.

 

SQL> select index_name, index_type, uniqueness

  2  from user_indexes

  3  where table_owner = 'SCOTT'

  4  and table_name = 'TEST';

 

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

------------------------------ --------------------------- ---------

IDX_TEST_ID                    NORMAL                      UNIQUE

 

SQL> select constraint_name, constraint_type

  2  from user_constraints

  3  where table_name = 'TEST';

 

CONSTRAINT_NAME                C

------------------------------ -

UK_TEST                        U

 

SQL> alter table test disable constraint uk_test;

 

Table altered.

 

SQL> select constraint_name, constraint_type, status

  2  from user_constraints

  3  where table_name = 'TEST';

 

CONSTRAINT_NAME                C STATUS

------------------------------ - --------

UK_TEST                        U DISABLED

 

SQL> select index_name, index_type, uniqueness, status

  2  from user_indexes

  3  where table_owner = 'SCOTT'

  4  and table_name = 'TEST';

 

INDEX_NAME                     INDEX_TYPE                  UNIQUENES STATUS

------------------------------ --------------------------- --------- --------

IDX_TEST_ID                    NORMAL                      UNIQUE    VALID

 

實驗結果表明,先創建的唯一索引不受約束失效的影響。

 

總結如下:

(1)主鍵約束和唯一鍵約束均會隱式創建同名的唯一索引,當主鍵約束或者唯一鍵約束失效時,隱式創建的唯一索引會被刪除;

(2)主鍵約束要求列值非空,而唯一鍵約束和唯一索引不要求列值非空;

(3)相同欄位序列不允許重覆創建索引

http://www.cnblogs.com/roucheng/


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

-Advertisement-
Play Games
更多相關文章
  • 1. PCH文件概述 PCH文件是一種預編譯頭文件(一般擴展名為.PCH),是把一個工程中較穩定的代碼預先編譯好放在一個文件(.PCH)里。這些預先編譯好的代碼可以是任何的C/C++代碼--甚至可以是inline函數,只它們在整個工程中是較為穩定的,即在工程開發過程中不會經常被修改的代碼。 在 Xc ...
  • 看了很多別人寫的安卓SQlite數據的操作代碼,都是浮雲,瞎弄!一點也不通俗易懂,我覺得我寫的不錯,而且安卓項目也用上了,所以在博客園裡保存分享一下! 一SQLiteHelper類是自動重載增刪改查函數的,另外一個是自己定義的類,用Context傳值。我用的是Fragment,用Activity的話 ...
  • 此前編譯過Android4.4的源碼,但是現在Android都到了7.0的版本,不禁讓我感嘆Google的步伐真心難跟上,趁這周周末時間比較充裕,於是在過去的24小時里,毅然花了9個小時編譯了一把Android6.0的源碼,但是昨天編譯完之後已經很晚了,沒來得及記錄編譯的步驟,今天才慢悠悠地來記錄一 ...
  • 教你如何在 Android 使用多線程下載文件 =============================================== 前言 在 Android 日常開發中,我們會經常遇到下載文件需求,這裡我們也可以用系統自帶的 api 來解決這個問題,當然我們也可以自己來寫。在這裡我將教大 ...
  • 我們在使用手機的時候,經常會遇到一個問題:先是卡死,然後跳出該程式無響應,是否關閉的提示(當然有可能是我們手機性能太差=。=)這是因為線程的阻塞引起的,在這裡我講述一下UI線程,一般處理程式會在UI線程中執行耗時操作,這回導致UI線程阻塞,當UI線程阻塞,屏幕會出現卡死,用戶體驗會變得非常差,當線程 ...
  • OC 觀察者模式(通知中心,KVO) 什麼是觀察者模式??? A對B的變化感興趣,就註冊為B的觀察者,當B發生變化時通知A,告知B發生了變化。這就是觀察者模式。 觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,使它們 ...
  • 在資料庫遠程連接上,很多時候我們總是連接不上,這時候很有可能1433埠未開放導致的。 解決方案: (1)在Windows防火牆中開放1433的入站(在Windows中開放1433埠的步驟:1.打開控制面板,2.點擊系統和安全,3.點擊防火牆,4.點擊高級設置,可以看到入站規則和出站規則,5.右鍵 ...
  • 現在很多用戶被資料庫的慢的問題所困擾,又苦於花錢請一個專業的DBA成本太高。軟體維護人員對資料庫的瞭解又不是那麼深入,所以導致問題遲遲不能解決,或只能暫時解決不能得到根治。開發人員解決數據問題基本又是搜遍百度各種方法嘗試個遍,可能錯過診斷問題的最佳時機又可能嘗試一堆方法最後無奈放棄。 怎麼樣讓瑣事纏 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:本文代碼示例演示瞭如何在WPF中使用LiveCharts庫創建動態條形圖。通過創建數據模型、ViewModel和在XAML中使用`CartesianChart`控制項,你可以輕鬆實現圖表的數據綁定和動態更新。我將通過清晰的步驟指南包括詳細的中文註釋,幫助你快速理解並應用這一功能。 先上效果: 在 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • 概述:本示例演示了在WPF應用程式中實現多語言支持的詳細步驟。通過資源字典和數據綁定,以及使用語言管理器類,應用程式能夠在運行時動態切換語言。這種方法使得多語言支持更加靈活,便於維護,同時提供清晰的代碼結構。 在WPF中實現多語言的一種常見方法是使用資源字典和數據綁定。以下是一個詳細的步驟和示例源代 ...
  • 描述(做一個簡單的記錄): 事件(event)的本質是一個委托;(聲明一個事件: public event TestDelegate eventTest;) 委托(delegate)可以理解為一個符合某種簽名的方法類型;比如:TestDelegate委托的返回數據類型為string,參數為 int和 ...
  • 1、AOT適合場景 Aot適合工具類型的項目使用,優點禁止反編 ,第一次啟動快,業務型項目或者反射多的項目不適合用AOT AOT更新記錄: 實實在在經過實踐的AOT ORM 5.1.4.117 +支持AOT 5.1.4.123 +支持CodeFirst和非同步方法 5.1.4.129-preview1 ...
  • 總說周知,UWP 是運行在沙盒裡面的,所有許可權都有嚴格限制,和沙盒外交互也需要特殊的通道,所以從根本杜絕了 UWP 毒瘤的存在。但是實際上 UWP 只是一個應用模型,本身是沒有什麼許可權管理的,許可權管理全靠 App Container 沙盒控制,如果我們脫離了這個沙盒,UWP 就會放飛自我了。那麼有沒... ...
  • 目錄條款17:讓介面容易被正確使用,不易被誤用(Make interfaces easy to use correctly and hard to use incorrectly)限制類型和值規定能做和不能做的事提供行為一致的介面條款19:設計class猶如設計type(Treat class de ...
  • title: 從零開始:Django項目的創建與配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 後端開發 tags: Django WebDev Python ORM Security Deployment Op ...
  • 1、BOM對象 BOM:Broswer object model,即瀏覽器提供我們開發者在javascript用於操作瀏覽器的對象。 1.1、window對象 視窗方法 // BOM Browser object model 瀏覽器對象模型 // js中最大的一個對象.整個瀏覽器視窗出現的所有東西都 ...