Oracle 資料庫表中已有重覆數據添加唯一鍵(唯一約束) 問題描述 以 demo 舉例,模擬真實場景。 表 TEST_TABLE 有如下欄位和數據:id 是主鍵,code 沒有設置鍵和索引 ID | CODE | 1 | code1 2 | code2 3 | code2 4 | code2 5 ...
Oracle 資料庫表中已有重覆數據添加唯一鍵(唯一約束)
問題描述
以 demo 舉例,模擬真實場景。
表 TEST_TABLE 有如下欄位和數據:id 是主鍵,code 沒有設置鍵和索引
ID | CODE |
---|---|
1 | code1 |
2 | code2 |
3 | code2 |
4 | code2 |
5 | code3 |
通過以上表中數據可以看出 code 是有重覆數據的,此時如果我們直接添加唯一鍵,會報錯。
通過 PL/SQL 可視化操作,或者通過 SQL 語句添加(ENABLE NOVALIDATE 的作用是約束新增數據但不會驗證已有數據):ALTER TABLE TEST_TABLE ADD CONSTRAINT UK_TEST_TABLE_CODE UNIQUE(CODE) ENABLE NOVALIDATE;
即使用到了 ENABLE NOVALIDATE 也報錯,如下:
ORA-02299: cannot validate(TESTUSER.TEST_TABLE.UK_TEST_TABLE_CODE)-duplicate keys found
--Create/Recreate primary, unique and foreign key constraints alter table TEST_TABLE and constraint UK_TEST_TABLE_CODE unique(CODE) novalidate
解決方案
- 先添加普通索引
CREATE INDEX IDX_TEST_TABLE_CODE ON TEST_TABLE(CODE);
- 再添加唯一鍵
ALTER TABLE TEST_TABLE ADD CONSTRAINT UK_TEST_TABLE_CODE UNIQUE(CODE) ENABLE NOVALIDATE;
如果你對上面提到的基本概念不太清楚,建議繼續往下看,或者查找資料去學習,然後多在測試資料庫中模擬“犯罪現場”,然後進行還原問題、找問題、分析問題和解決問題。
基本概念
鍵、索引、約束的區別
一般,我們看到術語“索引”和“鍵”交換使用,但實際上這兩個是不同的。索引是存儲在資料庫中的一個物理結構,鍵純粹是一個邏輯概念。鍵代表創建來實施業務規則的完整性約束。索引和鍵的混淆通常是由於資料庫使用索引來實施完整性約束。
- 主鍵索引和主鍵有什麼關係?
主鍵索引是創建主鍵的時候系統自動創建的索引,主鍵要求不重覆,不為空,但是他如何判斷有效率呢?當然是建索引了,老是全表遍歷還不瘋掉。
所以建立主鍵會自動的建立主鍵索引。
主鍵和唯一鍵的區別在於唯一鍵可以為空,主鍵不可以
建立唯一約束和唯一索引又什麼區別?
同理,建立唯一約束的時候,也會自動的創建唯一索引。建立唯一索引可以說是唯一約束的一種手段。
基本上,實現起來是沒有什麼區別的。如果實在理解不了,就當一樣好了。
- 聚簇索引和非聚簇索引有何區別?
這個上邊已經講和很詳細了,還附有兩篇文章,這裡就不說了。
- 約束和主鍵有什麼區別?
約束一般有主鍵約束,外鍵約束,唯一約束等。
分別為primary key,foreign key,unique 其中主鍵約束只是約束的一種。
其實他們是不同概念的東西。
參考資料
- https://www.cnblogs.com/dayang12525/articles/7762634.html
- http://blog.sina.com.cn/s/blog_82ee2ee60100xwl4.html