2009-05-05 25 views
16

Khi tôi thực hiện theo hai bước tìm kiếm (Tôi đã lột chúng xuống hoàn toàn cần thiết):MySql Lỗi 150 - phím Ngoại

mysql> CREATE TABLE foo(id INT PRIMARY KEY); 
Query OK, 0 rows affected (0.01 sec) 

mysql> CREATE TABLE bar (id INT, ref INT, FOREIGN KEY (ref) REFERENCES foo(id)) ENGINE InnoDB; 

tôi nhận được lỗi sau: ERROR 1005 (HY000): Không thể tạo bảng './test/bar.frm' (errno: 150)

Trường hợp **** là lỗi của tôi? Tôi đã không tìm thấy anh ta trong khi nhìn chằm chằm vào điều này trong nửa giờ.

Trả lời

29

Từ FOREIGN KEY Constraints

If you re-create a table that was dropped, it must have a definition that conforms to the foreign key constraints referencing it. It must have the right column names and types, and it must have indexes on the referenced keys, as stated earlier. If these are not satisfied, MySQL returns error number 1005 and refers to error 150 in the error message.

My nghi ngờ là nó vì bạn không tạo foo như InnoDB, như mọi thứ khác có vẻ OK.

Edit: so với cùng trang -

Both tables must be InnoDB tables and they must not be TEMPORARY tables.

+0

Một chút thử nghiệm nhanh, tạo ra một 'foo' như trên với MyISAM, và một' thanh' với InnoDB, cho thấy rằng đó là trường hợp - hãy thử kiểm tra lại kiểu bảng của bạn cho 'foo'. – Rob

+0

+1 cho "Cả hai bảng phải là bảng InnoDB", cảm ơn rất nhiều! – sanbhat

+1

Ngay cả khi cả hai bảng đều là InnoDB, tôi vẫn có cùng một vấn đề. Tôi đã sửa nó bằng cách tạo chỉ mục trên bảng được giới thiệu trước khi tạo khóa ngoài. – IROEGBU

1

tôi đã cùng một vấn đề, đối với những người đang có này cũng:

kiểm tra các tên bảng của bảng tham chiếu

tôi đã quên 's' ở cuối tên bảng của tôi

ví dụ như bảng Khách hàng -> Khách hàng

:)

0

Tôi đã có vấn đề rất giống nhau và lý do là "đối chiếu" của các cột khác nhau. Một là latin1 trong khi người kia là utf8

9

Bạn có thể sử dụng lệnh SHOW ENGINE INNODB STATUS

+0

Cảm ơn bạn! Đã lưu ngày của tôi –

+0

Đồng ý! Nó cho thấy một phần "Lỗi khóa ngoài nước ngoài", mà trong trường hợp của tôi nói với tôi rằng tên trường mục tiêu của một ràng buộc khoá ngoại không được tìm thấy. Điều này hữu ích hơn một "Lỗi 150" tuyệt đối ;-) –

+0

Trong trường hợp của tôi, tôi đã quên đặt cột để cho phép NULL, và đặt SET NULL vào ràng buộc. Nhưng tôi chỉ phát hiện ra lý do bằng cách chạy 'SHOW ENGINE INNODB STATUS' –

1

Ngoài hình thức nhiều lý do khác để kết thúc với MySql Lỗi 150 (trong khi sử dụng InnoDB), Một trong những lý do có thể xảy ra, là xác định KEY trong câu lệnh tạo của bảng chứa tên cột được tham chiếu như một khoá ngoại trong bảng tương đối.

Hãy nói rằng các tạo tuyên bố của bảng tổng thể là -

CREATE TABLE 'master_table' (
 'id' int(10) NOT NULL AUTO_INCREMENT,
 'record_id' char(10) NOT NULL,
 'name' varchar(50) NOT NULL DEFAULT '',
 'address' varchar(200) NOT NULL DEFAULT '',
 PRIMARY KEY ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

và tạo ra cú pháp cho bảng relative_table nơi ràng buộc khoá ngoại được thiết lập từ bảng chính -

CREATE TABLE 'relative_table' (
 'id' int(10) NOT NULL AUTO_INCREMENT,
 'salary' int(10) NOT NULL DEFAULT '',
 'grade' char(2) NOT NULL DEFAULT '',
 'record_id' char(10) DEFAULT NULL,
 PRIMARY KEY ('id'),
 CONSTRAINT 'fk_slave_master' FOREIGN KEY ('record_id') REFERENCES 'master' ('record_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Kịch bản này chắc chắn sẽ kết thúc với lỗi MySql 150 nếu sử dụng InnoDB.

Để giải quyết vấn đề này, chúng tôi cần thêm KEY cho cột record_id trong bảng master_table và sau đó tham chiếu trong bảng relative_table để được sử dụng làm một ngoại tuyến.

Cuối cùng, tạo ra tuyên bố cho master_table, sẽ -

CREATE TABLE 'master_table' (
 'id' int(10) NOT NULL AUTO_INCREMENT,
 'record_id' char(10) NOT NULL,
 'name' varchar(50) NOT NULL DEFAULT '',
 'address' varchar(200) NOT NULL DEFAULT '',
 PRIMARY KEY ('id'),
 KEY 'record_id' ('record_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4

Để tạo một khóa ngoại,

  1. cả cột chính và cột tham khảo phải có cùng một nghĩa.
  2. cả hai công cụ bảng phải là InnoDB.

Bạn có thể thay đổi công cụ của bảng bằng lệnh này, vui lòng thực hiện sao lưu trước khi thực hiện lệnh này.

thay đổi bảng [tên bảng] ENGINE = InnoDB;

+2

" phải có cùng định nghĩa "được mã hóa charset giống với tôi – gengisdave

+0

" phải có cùng định nghĩa "giống cờ cờ giống nhau cho tôi: Khóa chính hiện có mà tôi đã tham chiếu đã được UNSIGNED, vì vậy tôi phải tạo cột của bảng mới cũng là khóa ngoại trong lần đầu tiên – cellepo

0

Điều này cũng có thể xảy ra nếu bạn không cung cấp tên cột đúng sau từ khóa "tham chiếu".

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