Oracle主鍵約束、唯一鍵約束、唯一索引的區別(轉)
一般,我們看到術語“索引”和“鍵”交換使用,但實際上這兩個是不同的。索引是儲存在資料庫中的一個物理結構,鍵純粹是一個邏輯概念。鍵代表建立來實施業務規則的完整性約束。索引和鍵的混淆通常是由於資料庫使用索引來實施完整性約束。
接下來我們看看資料庫中的主鍵約束、唯一鍵約束和唯一索引的區別。
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';
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)相同欄位序列不允許重複建立索引;
相關文章
- 【INDEX】Oracle中主鍵、唯一約束與唯一索引之區別IndexOracle索引
- ORACLE: 查詢(看)表的主鍵、外來鍵、唯一性約束和索引Oracle索引
- 唯一性約束和唯一性索引的區別索引
- Oracle主鍵、唯一鍵與唯一索引的區別Oracle索引
- 查詢(看)表的主鍵、外來鍵、唯一性約束和索引索引
- 資料庫約束 主鍵-唯一性-Check-外來鍵資料庫
- 【PK】Oracle 10g刪除主鍵約束後無法刪除唯一約束索引問題的模擬與分析Oracle 10g索引
- MySQL·捉蟲動態·唯一鍵約束失效MySql
- 主鍵和唯一索引的區別索引
- Oracle定義約束 外來鍵約束Oracle
- oracle鍵約束控制Oracle
- 主鍵、自增主鍵、主鍵索引、唯一索引概念區別與效能區別索引
- Oracle唯一約束中NULL的處理OracleNull
- PostgreSQL唯一約束如何使用?SQL
- Mysql-基本練習(06-唯一約束、外來鍵約束、新增、刪除單列)MySql
- SQL Server唯一約束的使用SQLServer
- SQL的主鍵和外來鍵約束SQL
- Javaweb-約束-外來鍵約束JavaWeb
- 解決資料庫的索引亂碼問題,先刪除外來鍵約束,再刪除主鍵約束及其索引資料庫索引
- 約束:確保資料的完整性(主鍵,唯一,檢查,預設,非空,外來鍵)
- 建立Oracle唯一約束,忽略已有的重複值Oracle
- oracle外來鍵約束的總結Oracle
- 資料完整性約束:主鍵、外來鍵、各種約束的建立刪除語句
- 主鍵(PK)與非空唯一索引(Unique Index)的區別索引Index
- oracle主外來鍵鎖_lock_約束Oracle
- NULL和唯一約束UNIQUE的對應關係Null
- SQL SERVER中找出拙劣的約束,索引,外來鍵SQLServer索引
- Sql Server系列:鍵和約束SQLServer
- 主鍵約束設定Enable Novalidate時報錯
- Oracle外來鍵約束中NULL的處理OracleNull
- 建約束(Constraint)時隱式建立索引(Index)及先建立索引後建立約束的區別AI索引Index
- Oracle約束Oracle
- oracle 約束Oracle
- 【SQL】15 SQL 約束(Constraints)、NOT NULL 約束、UNIQUE 約束、PRIMARY KEY 約束、FOREIGN KEY 約束、CHECK 約束、DEFAULT約束SQLAINull
- 主鍵,唯一性約束,不同session間未提交事務中的爭議性資料引起的問題。Session
- 教你mysql如何增加外來鍵約束MySql
- MySQL禁用恢復外來鍵約束MySql
- oracle中的約束Oracle