MySQL không thể tạo ràng buộc khóa ngoại


84

Tôi đang gặp một số vấn đề khi tạo khóa ngoại cho bảng hiện có trong cơ sở dữ liệu mysql.

Tôi có bảng exp:

+-------------+------------------+------+-----+---------+-------+
| Field       | Type             | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| EID         | varchar(45)      | NO   | PRI | NULL    |       |
| Comment     | text             | YES  |     | NULL    |       |
| Initials    | varchar(255)     | NO   |     | NULL    |       |
| ExpDate     | date             | NO   |     | NULL    |       |
| InsertDate  | date             | NO   |     | NULL    |       |
| inserted_by | int(11) unsigned | YES  | MUL | NULL    |       |
+-------------+------------------+------+-----+---------+-------+

và tôi sẽ không tạo một bảng mới được gọi là sample_dftham chiếu cái này, bằng cách sử dụng như sau:

CREATE TABLE sample_df (
df_id mediumint(5) unsigned AUTO_INCREMENT primary key,
sample_type mediumint(5) unsigned NOT NULL,
df_10 BOOLEAN NOT NULL,
df_100 BOOLEAN NOT NULL,
df_1000 BOOLEAN NOT NULL,
df_above_1000 BOOLEAN NOT NULL,
target INT(11) unsigned NOT NULL,
assay MEDIUMINT(5) unsigned zerofill NOT NULL,
insert_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
inserted_by INT(11) unsigned NOT NULL,
initials varchar(255),
experiment VARCHAR(45),
CONSTRAINT FOREIGN KEY (inserted_by) REFERENCES user (iduser),
CONSTRAINT FOREIGN KEY (target) REFERENCES protein (PID),
CONSTRAINT FOREIGN KEY (sample_type) REFERENCES sample_type (ID),
CONSTRAINT FOREIGN KEY (assay) REFERENCES assays (AID),
CONSTRAINT FOREIGN KEY (experiment) REFERENCES exp (EID)
);

Nhưng tôi gặp lỗi:

ERROR 1215 (HY000): Cannot add foreign key constraint

Để có thêm một số thông tin, tôi đã làm:

SHOW ENGINE INNODB STATUS\G

Từ đó tôi nhận được:

FOREIGN KEY (experiment) REFERENCES exp (EID)
):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.

Đối với tôi, các loại cột dường như khớp nhau, vì chúng đều là varchar (45). (Tôi cũng đã thử đặt experimentcột thành không null, nhưng điều này không khắc phục được) Vì vậy, tôi đoán vấn đề phải là như vậy Cannot find an index in the referenced table where the referenced columns appear as the first columns. Nhưng tôi không chắc điều này có nghĩa là gì hoặc cách kiểm tra / sửa chữa nó. Có ai có bất kỳ đề nghị? Và nghĩa là first columnsgì?


11
Không nơi nào trong bất kỳ câu trả lời hoặc câu hỏi nào, tôi có thể nhận thấy rằng lỗi này có thể xảy ra do sự khác biệt trong bộ ký tự. Cảm ơn .. Chúc mừng !!!
proprius

3
Ngoài ra, hãy kiểm tra kỹ đối chiếu cột của bạn. Bảng của bạn có thể là utf8mb4 nhưng cột có thể có một đối chiếu khác!
Watson

Bộ ký tự @Watson trong trường hợp của tôi nhưng bạn nhận được sự ủng hộ của tôi vì đã khiến tôi phải suy nghĩ.
dùng2910265

Câu trả lời:


153

Chỉ cần ném điều này vào hỗn hợp các nguyên nhân có thể xảy ra, tôi đã gặp phải điều này khi cột bảng tham chiếu có cùng "loại" nhưng không có cùng ký.

Trong trường hợp của tôi, cột bảng được tham chiếu là TINYINT UNSIGNED và cột bảng tham chiếu của tôi là TINYINT SIGNED. Căn chỉnh cả hai cột đã giải quyết được vấn đề.


1
Giải pháp do @ austen-hoogen đề xuất đã giải quyết được sự cố của tôi. Nhưng do điểm danh tiếng thấp, tôi không thể bỏ phiếu và bình luận cho giải pháp của anh ấy. Trong trường hợp của tôi, Khóa chính là số nguyên, tự động tăng dần và không có dấu. Nhưng khóa ngoại (cột của bảng tham chiếu) đã được ký kiểu. Tôi đã thay đổi nó thành không dấu và có thể tạo quan hệ thành công.
Bal Singh

Có, đã trải qua cùng một vấn đề. Khóa chính của tôi là BIGINT (20) và khóa tham chiếu của tôi trong một bảng khác, nó là INT (10) chưa được ký. chúng tôi cần đảm bảo tất cả chúng đều phù hợp. I E. Bigint (20), và trong bảng tham chiếu cũng nên bigint (20)
Manjunath Reddy

Cảm ơn bạn! Giải pháp này cũng giải quyết được vấn đề của tôi! Tôi có inttrong bảng nơi tôi định đặt khóa ngoại và bigint trong bảng thứ hai.
Aleksej_Shherbak

36

Lỗi này cũng có thể xảy ra nếu bảng tham chiếu và bảng hiện tại không có cùng bộ ký tự.


3
Sau khi đặt bộ ký tự như latintrong bảng tham chiếu, tôi bắt đầu thở lại sau 3 giờ.
Abhishek Kamal

24

Theo http://dev.mysql.com/doc/refman/5.5/vi/create-table-foreign-keys.html

MySQL yêu cầu chỉ mục trên khóa ngoại và khóa tham chiếu để việc kiểm tra khóa ngoại có thể nhanh chóng và không yêu cầu quét bảng. Trong bảng tham chiếu, phải có một chỉ mục trong đó các cột khóa ngoại được liệt kê là các cột đầu tiên theo cùng một thứ tự.

InnoDB cho phép một khóa ngoại tham chiếu đến bất kỳ cột chỉ mục hoặc nhóm cột nào. Tuy nhiên, trong bảng được tham chiếu, phải có một chỉ mục trong đó các cột được tham chiếu được liệt kê là các cột đầu tiên theo cùng một thứ tự.

Vì vậy, nếu chỉ mục trong bảng được tham chiếu tồn tại và nó bao gồm từ một số cột và cột mong muốn không phải là cột đầu tiên, thì lỗi sẽ xảy ra.

Nguyên nhân gây ra lỗi của chúng tôi là do vi phạm quy tắc sau:

Các cột tương ứng trong khóa ngoại và khóa được tham chiếu phải có kiểu dữ liệu tương tự. Kích thước và dấu của các kiểu số nguyên phải giống nhau. Độ dài của các loại chuỗi không được giống nhau. Đối với cột chuỗi không nhị phân (ký tự), bộ ký tự và đối chiếu phải giống nhau.


19

Như đã đề cập @Anton, điều này có thể là do kiểu dữ liệu khác nhau. Trong trường hợp của tôi, tôi có khóa chính BIGINT (20) và cố gắng đặt khóa dự đoán bằng INT (10)


2
Cảm ơn bạn! Vấn đề tương tự khi tôi đang sử dụng INT (11) với INT (11) nhưng một khóa là khóa chính và do đó chưa được ký trong khi khóa kia đã được ký!
Michael Scott Cuthbert

@MichaelScottCuthbert Tương tự
Germa Vinsmoke


6

Của tôi là một vấn đề đối chiếu giữa bảng được tham chiếu và bảng sẽ được tạo, vì vậy tôi phải đặt rõ ràng loại đối chiếu của khóa tôi đang tham chiếu.

  • Đầu tiên, tôi chạy một truy vấn tại bảng được tham chiếu để lấy loại đối chiếu của nó
show table STATUS like '<table_name_here>';
  • Sau đó, tôi sao chép kiểu đối chiếu và nêu rõ kiểu đối chiếu của worker_id tại truy vấn tạo. Trong trường hợp của tôi, nó là utf8_general_ci
CREATE TABLE dbo.sample_db
(
  id INT PRIMARY KEY AUTO_INCREMENT,
  event_id INT SIGNED NOT NULL,
  employee_id varchar(45) COLLATE utf8_general_ci NOT NULL,
  event_date_time DATETIME,
  CONSTRAINT sample_db_event_event_id_fk FOREIGN KEY (event_id) REFERENCES event (event_id),
  CONSTRAINT sample_db_employee_employee_id_fk FOREIGN KEY (employee_id) REFERENCES employee (employee_id)
);

2

Thứ tự chính xác của khóa chính cũng cần khớp với không có cột thừa ở giữa.

Tôi đã thiết lập khóa chính trong đó thứ tự cột thực sự khớp, nhưng vấn đề là khóa chính có một cột phụ trong đó không phải là một phần của khóa ngoại của bảng tham chiếu

ví dụ: bảng 2, cột (a, b, c) -> bảng 1, cột (a, b, d, c) - THẤT BẠI NÀY

Tôi đã phải sắp xếp lại các cột khóa chính để không những chúng được sắp xếp theo cùng một cách mà còn không có cột thừa ở giữa:

ví dụ: bảng 2, cột (a, b, c) -> bảng 1, cột (a, b, c, d) - NÀY THÀNH CÔNG


2

Trong một số trường hợp, tôi phải đặt trường được tham chiếu là duy nhất bên cạnh việc xác định nó là khóa chính.

Nhưng tôi thấy rằng không xác định nó là duy nhất không tạo ra vấn đề trong mọi trường hợp. Mặc dù vậy, tôi đã không thể tìm ra các kịch bản. Có lẽ là một cái gì đó để làm với định nghĩa nullable.


Bạn đã đọc phần giới thiệu về FK hoặc sách hướng dẫn chưa? FK tham chiếu một UNIQUE; PK có nghĩa là DUY NHẤT KHÔNG PHẢI KHÔNG ĐỦ.
philipxy 17-08-19

2

Trong trường hợp của tôi được tạo bằng cách sử dụng số nguyên cho id và bảng tham chiếu đang tạo theo mặc định một khóa ngoại bằng cách sử dụng bigint .

Điều này gây ra một cơn ác mộng lớn trong ứng dụng Rails của tôi vì quá trình di chuyển không thành công nhưng các trường thực sự đã được tạo trong DB, vì vậy chúng hiển thị trong DB nhưng không hiển thị trong lược đồ của ứng dụng Rails.


1

Tham chiếu cùng một cột nhiều lần trong cùng một ràng buộc cũng tạo ra Cannot find an index in the referenced tablelỗi này , nhưng có thể khó phát hiện trên các bảng lớn. Chia nhỏ các ràng buộc và nó sẽ hoạt động như mong đợi.


1

Tôi cũng có lỗi này. Không có câu trả lời nào liên quan đến tôi. Trong trường hợp của tôi, GUI của tôi tự động tạo một bảng có số nhận dạng duy nhất chính là "chưa được gán". Điều này không thành công khi tôi thử và tạo khóa ngoại và cho tôi cùng một lỗi. Khóa chính của tôi cần được chỉ định.

Nếu bạn viết chính SQL như vậy id int unique auto_incrementthì bạn không gặp sự cố này nhưng vì lý do nào đó mà GUI của tôi thực hiện điều này thay thế id int unassigned unique auto_increment.

Hy vọng điều này sẽ giúp người khác trên con đường.


1

Đối với tôi, đó chỉ là bảng mã và đối chiếu của DB. Tôi đã đổi thành utf8_unicode_ci và hoạt động


1
Bạn có thể bao gồm một ví dụ về cách kiểm tra bảng mã / đối chiếu hiện tại không?
thelr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.