2011-09-22 37 views
34

Ai đó có thể làm rõ mục đích của việc có chỉ mục duy nhất không có ràng buộc duy nhất (Oracle) là gì? Ví dụ:Ràng buộc duy nhất của Oracle và chỉ mục duy nhất

create table test22(id int, id1 int, tmp varchar(20)); 
create unique index idx_test22 on test22(id); 
insert into test22(id, id1, tmp) values (1, 2, 'aaa'); // ok 
insert into test22(id, id1, tmp) values (1, 2, 'aaa'); // fails, ORA-00001: unique 
    // constraint (TEST.IDX_TEST22) violated 

Cho đến nay có vẻ như có ràng buộc. Nhưng

create table test33(id int not null primary key, 
test22_id int not null, 
foreign key(test22_id) references test22(id)); 

cũng không thành công với "ORA-02270: no matching unique or primary key for this column-list". Tôi hoàn toàn bối rối bởi hành vi này. Có hạn chế hay không?

Có nhiều bài viết giải thích tại sao có thể có ràng buộc duy nhất không có chỉ mục duy nhất; điều đó rõ ràng và có ý nghĩa hoàn hảo. Tuy nhiên, tôi không hiểu lý do cho chỉ mục duy nhất mà không bị ràng buộc.

Trả lời

39

Ràng buộc và chỉ mục là các thực thể logic riêng biệt. Ví dụ: một ràng buộc duy nhất, hiển thị trong USER_CONSTRAINTS (hoặc ALL_CONSTRAINTS hoặc DBA_CONSTRAINTS). Chỉ mục hiển thị trong USER_INDEXES (hoặc ALL_INDEXES hoặc DBA_INDEXES).

Ràng buộc duy nhất được thực thi bởi chỉ mục mặc dù có thể (và đôi khi cần thiết) để thực thi ràng buộc duy nhất bằng cách sử dụng một chỉ mục không duy nhất. Ví dụ, một ràng buộc duy nhất có thể trì hoãn, được thực thi bằng cách sử dụng một chỉ mục không duy nhất. Nếu bạn tạo một chỉ mục không duy nhất trên một cột và sau đó tạo ra ràng buộc duy nhất, bạn cũng có thể sử dụng chỉ mục không duy nhất đó để thực thi ràng buộc duy nhất. Trong thực tế, một chỉ mục duy nhất hoạt động rất giống như một ràng buộc duy nhất, không thể trì hoãn ở chỗ nó làm tăng cùng một lỗi mà ràng buộc duy nhất tăng lên kể từ khi thực hiện các ràng buộc duy nhất sử dụng chỉ mục. Nhưng nó không hoàn toàn giống nhau bởi vì không có ràng buộc. Vì vậy, như bạn đã thấy, không có ràng buộc duy nhất, do đó bạn không thể tạo ra ràng buộc khóa ngoài tham chiếu đến cột.

Có những trường hợp bạn có thể tạo chỉ mục duy nhất mà bạn không thể tạo ràng buộc duy nhất. Ví dụ, chỉ mục dựa trên chức năng thực thi tính duy nhất có điều kiện. Nếu tôi muốn tạo ra một bảng hỗ trợ xóa logic nhưng đảm bảo rằng COL1 là duy nhất cho tất cả các hàng không bị xóa

SQL> ed 
Wrote file afiedt.buf 

    1 CREATE TABLE t (
    2 col1 number, 
    3 deleted_flag varchar2(1) check(deleted_flag in ('Y','N')) 
    4*) 
SQL>/

Table created. 

SQL> create unique index idx_non_deleted 
    2  on t(case when deleted_flag = 'N' then col1 else null end); 

Index created. 

SQL> insert into t values(1, 'N'); 

1 row created. 

SQL> insert into t values(1, 'N'); 
insert into t values(1, 'N') 
* 
ERROR at line 1: 
ORA-00001: unique constraint (SCOTT.IDX_NON_DELETED) violated 


SQL> insert into t values(1, 'Y'); 

1 row created. 

SQL> insert into t values(1, 'Y'); 

1 row created. 

Nhưng nếu chúng ta đang nói về một độc đáo phi chức năng chỉ số dựa thẳng, có lẽ tương đối vài trường hợp nó thực sự có ý nghĩa hơn để tạo chỉ mục thay vì tạo ra ràng buộc. Mặt khác, có khá ít trường hợp nó tạo ra sự khác biệt trong thực tế. Bạn hầu như không bao giờ muốn khai báo ràng buộc khóa ngoài tham chiếu ràng buộc duy nhất thay vì ràng buộc khóa chính, do đó bạn hiếm khi mất thứ gì đó bằng cách chỉ tạo chỉ mục và không tạo ràng buộc.

+0

Cảm ơn câu trả lời của bạn, hiện đã rõ ràng hơn. Những gì tôi thực sự không thích là cùng một mã lỗi ('ORA-00001') cho cả hai trường hợp, với ràng buộc và chỉ số duy nhất. – a1ex07

+0

Tuyệt vời, cảm ơn "câu nói cuối cùng" về việc liệu bạn có thể tạo ra một ràng buộc duy nhất trên một FBI duy nhất hay không. – orbfish

+0

Cảm ơn - đây là giải thích rõ ràng duy nhất về sự khác biệt giữa hai tôi đã tìm thấy. Tôi đã thấy một số đề cập đến việc tuyên bố một ràng buộc duy nhất cung cấp cho trình tối ưu hóa nhiều thông tin hơn một chỉ mục duy nhất ...điều đó có đúng không, và điều đó có nghĩa là một ràng buộc duy nhất có thể cung cấp một số lợi ích hiệu suất so với chỉ mục duy nhất không có ràng buộc? – Mike

1

Một điểm khác có thể hữu ích trong ngữ cảnh này là: Tắt/Giảm ràng buộc duy nhất hiện tại không làm giảm chỉ mục duy nhất cơ bản. Bạn phải thả chỉ mục duy nhất một cách rõ ràng.

+2

Điều đó không đúng (ít nhất là 10g). Trong thực tế, bạn phải chỉ định 'KEEP INDEX' trong khi giảm ràng buộc duy nhất để giữ chỉ mục. Ngoài ra, chỉ mục không phải là duy nhất. – a1ex07

+0

Thú vị. Tuy nhiên, nó không phải như vậy từ 11g. – Syamjith

Các vấn đề liên quan