2008-11-21 20 views
40

Tôi đang xem tài liệu MySQL here và cố gắng phân loại sự khác biệt giữa các khóa NGOẠI HỐI và CONSTRAINT. Tôi nghĩ rằng một FK một ràng buộc, nhưng các tài liệu dường như nói về chúng như chúng là những thứ riêng biệt.Thuật ngữ MySQL "khó khăn" so với "ngoại khóa" khác biệt?

Cú pháp để tạo một FK là (một phần) ...

[CONSTRAINT [symbol]] FOREIGN KEY 
    [index_name] (index_col_name, ...) 
    REFERENCES tbl_name (index_col_name,...) 

Vì vậy, các "CONSTRAINT" khoản là không bắt buộc. Tại sao bạn bao gồm nó hoặc không bao gồm nó? Nếu bạn bỏ nó ra thì MySQL có tạo ra khóa ngoại nhưng không phải là một ràng buộc không? Hoặc là nó giống như một "CONSTRAINT" là gì hơn một cái tên cho bạn FK, vì vậy nếu bạn không chỉ định nó, bạn sẽ nhận được một FK ẩn danh?

Bất kỳ làm rõ nào cũng sẽ được đánh giá cao.

Cảm ơn,

Ethan

Trả lời

55

Có, khóa ngoại là loại ràng buộc. MySQL có hỗ trợ không đồng đều cho các ràng buộc:

  • PRIMARY KEY: có ràng buộc bảng và ràng buộc cột.
  • FOREIGN KEY: có dưới dạng ràng buộc bảng, nhưng chỉ với các công cụ lưu trữ InnoDB và BDB; nếu không được phân tích cú pháp nhưng bị bỏ qua.
  • CHECK: được phân tích cú pháp nhưng bị bỏ qua trong tất cả các công cụ lưu trữ.
  • UNIQUE: có như ràng buộc bảng và ràng buộc cột.
  • NOT NULL: có dưới dạng ràng buộc cột.
  • DEFERRABLE và các thuộc tính ràng buộc khác: không hỗ trợ.

Điều khoản CONSTRAINT cho phép bạn đặt tên ràng buộc một cách rõ ràng, để làm cho siêu dữ liệu dễ đọc hơn hoặc sử dụng tên khác khi bạn muốn bỏ ràng buộc. Chuẩn SQL yêu cầu mệnh đề CONSTRAINT là tùy chọn. Nếu bạn để nó ra, RDBMS tạo một tên tự động, và tên là tùy thuộc vào việc thực hiện.

1

không thể trả lời cho MySQL nhưng FK của những hạn chế. Bất cứ điều gì buộc dữ liệu của bạn vào một điều kiện nhất định là một ràng buộc. Có một số loại ràng buộc, Unique, Primary Key, Check và Foreign Keys là tất cả các ràng buộc. Có lẽ MySQL có người khác.

Đôi khi các từ được cho phép trong các lệnh nhưng không bắt buộc trước đây cho khả năng đọc như FROM trong câu lệnh DELETE.

9

Nói chung (không cần thiết MySQL), khóa ngoại là những ràng buộc, nhưng ràng buộc không phải lúc nào cũng là khóa ngoài. Hãy suy nghĩ về các ràng buộc chính, hạn chế duy nhất, v.v.

Quay lại câu hỏi cụ thể, chính xác, bỏ qua phần CONSTRAINT [symbol] sẽ tạo FK với tên được tạo tự động.

0

Đây có lẽ là điều khó hiểu nhất trong MySQL.

Nhiều người nói rằng, ví dụ: 'PRIMARY KEY', 'KEY NGOÀI' và phím 'UNIQUE' thực sự là chỉ mục!(Tài liệu chính thức của MySQL được bao gồm ở đây)

Nhiều trường hợp khác, nói rằng chúng khá hạn chế (có ý nghĩa, gây ra khi bạn sử dụng chúng, bạn thực sự áp đặt các hạn chế đối với các cột bị ảnh hưởng) .

Nếu chúng thực sự là chỉ mục, thì điểm trong việc sử dụng mệnh đề ràng buộc để đặt tên cho nó là gì, vì bạn có thể sử dụng tên của chỉ mục đó khi tạo nó?

Ví dụ:

... NƯỚC NGOÀI INDEX_NAME KEY (col_name1, col_name2, ...)

Nếu FOREIGN KEY là một chỉ số, sau đó chúng tôi sẽ có thể sử dụng INDEX_NAME để xử lý nó. Tuy nhiên, chúng tôi không thể.

Nhưng nếu chúng không phải là chỉ mục mà là các đường viền thực sự sử dụng các chỉ mục để làm việc thì điều này có ý nghĩa.

Trong mọi trường hợp, chúng tôi không biết. Trên thực tế, không ai có vẻ biết.

1

Nếu tôi không sai, các ràng buộc cần chỉ mục, vì vậy khi bạn tạo, ví dụ, một ràng buộc khóa ngoài MySQL cũng tự động tạo ra một chỉ mục.

1

Hiện tại, DDL TẠO TẠO của chúng tôi có định dạng này - hãy chú ý đến cú pháp định nghĩa KEY UNIQUE và NGOẠI TỆ mà chúng tôi đã sử dụng.

CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY, 
    account_nbr INT NOT NULL, 
    account_name VARCHAR(50) NOT NULL, 
    active_flg CHAR(1) NOT NULL DEFAULT 'Y', 
    vendor_nbr INT NOT NULL, 
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp, 
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR', 
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp, 
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR', 
    UNIQUE KEY uk1_my_table(account_nbr, account_name), 
    FOREIGN KEY fk1_my_table(vendor_nbr) REFERENCES vendor(vendor_nbr) 
    ); 

Ở định dạng này, MySQL đang tạo INDEX-es với tên uk1_my_table và fk1_my_table tự động; nhưng tên đối tượng FK là một cái gì đó khác nhau - my_table_ibfk_1 (tức là tablename_ibfk_N - hệ thống được định nghĩa). Vì vậy, ALTER TABLE my_table DROP FOREIGN KEY fk1_my_table sẽ không hoạt động (và do đó làm phiền và tăng báo động), vì không có đối tượng db FK nào theo tên đó.

Dưới đây là một wrt định dạng thay thế DDL các constarints (Ref: https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html): -

CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY, 
    account_nbr INT NOT NULL, 
    account_name VARCHAR(50) NOT NULL, 
    active_flg CHAR(1) NOT NULL DEFAULT 'Y', 
    vendor_nbr INT NOT NULL, 
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp, 
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR', 
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp, 
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR', 
    CONSTRAINT uk1_my_table UNIQUE KEY (account_nbr, account_name), 
    CONSTRAINT fk1_my_table FOREIGN KEY (vendor_nbr) REFERENCES vendor(vendor_nbr) 
    ); 

Trong định dạng này, MySQL vẫn tạo INDEX-es với tên uk1_my_table và fk1_my_table tự động, nhưng tên đối tượng FK không phải là một cái gì đó khác nhau - đó là fk1_my_table như đã đề cập trong DDL. Vì vậy, ALTER TABLE my_table DROP FOREIGN KEY fk1_my_table hoạt động, nhưng để lại đằng sau tên INDEX.

Và lưu ý rằng ALTER TABLE my_table DROP INDEX fk1_my_table sẽ không hoạt động lúc đầu (khi FK chưa được loại bỏ), với thông báo lỗi đang được sử dụng trong FK! Nếu lệnh DROP FK đã được thực hiện thành công thì chỉ DROP INDEX hoạt động.

Hy vọng điều này sẽ giải thích và giúp giải quyết sự nhầm lẫn.

+0

Câu trả lời hay! – HPM

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