2013-09-21 64 views
36

Tôi đã đọc Khái niệm hệ thống cơ sở dữ liệu, ấn bản thứ 6, Silberschatz. Tôi sẽ triển khai hệ thống cơ sở dữ liệu đại học thể hiện trong chương 2 trên OS X trên MySQL. Nhưng tôi gặp rắc rối khi tạo bảng course. bảng department trông giống nhưMySQL: ERROR 1215 (HY000): Không thể thêm ràng buộc khóa ngoài

mysql> select * from department 
    -> ; 
+------------+----------+-----------+ 
| dept_name | building | budget | 
+------------+----------+-----------+ 
| Biology | Watson | 90000.00 | 
| Comp. Sci. | Taylor | 100000.00 | 
| Elec. Eng. | Taylor | 85000.00 | 
| Finance | Painter | 120000.00 | 
| History | Painter | 50000.00 | 
| Music  | Packard | 80000.00 | 
| Physics | Watson | 70000.00 | 
+------------+----------+-----------+ 

mysql> show columns from department 
    -> ; 
+-----------+---------------+------+-----+---------+-------+ 
| Field  | Type   | Null | Key | Default | Extra | 
+-----------+---------------+------+-----+---------+-------+ 
| dept_name | varchar(20) | NO | PRI |   |  | 
| building | varchar(15) | YES |  | NULL |  | 
| budget | decimal(12,2) | YES |  | NULL |  | 
+-----------+---------------+------+-----+---------+-------+ 

Tạo bảng course gây lỗi sau.

mysql> create table course 
    -> (course_id varchar(7), 
    -> title varchar (50), 
    -> dept_name varchar(20), 
    -> credits numeric(2,0), 
    -> primary key(course_id), 
    -> foreign key (dept_name) references department); 
ERROR 1215 (HY000): Cannot add foreign key constraint 

sau khi tìm kiếm google cho ràng buộc khoá ngoại, tôi đã chỉ biết được rằng từ 'chính hạn chế nước ngoài chỉ ra rằng dữ liệu từ cột khóa ngoại trong bảng course phải tồn tại trong cột khóa chính trong bảng department. Nhưng tôi phải gặp lỗi này khi chèn dữ liệu.

Nếu không, tại sao tác giả làm cho tôi thực thi câu lệnh SQL đó?

Nếu tôi thực sự thực thi câu lệnh SQL sai, tôi có phải chỉ định dept_name trong bảng khóa học làm khóa ngoài sau khi chèn một số dữ liệu không?

EDIT: gõ set foreign_key_checks=0 vào mysql> không khắc phục lỗi.

------------------------ 
LATEST FOREIGN KEY ERROR 
------------------------ 
2013-09-21 16:02:20 132cbe000 Error in foreign key constraint of table university/course: 
foreign key (dept_name) references department): 
Syntax error close to: 
) 
mysql> set foreign_key_checks=0 
    -> ; 
Query OK, 0 rows affected (0.00 sec) 
mysql> create table course 
    -> (course_id varchar(7), 
    -> title varchar(50), 
    -> dept_name varchar(20), 
    -> credits numeric(2,0), 
    -> primary key(course_id), 
    -> foreign key (dept_name) references department); 
ERROR 1215 (HY000): Cannot add foreign key constraint 
+0

http://stackoverflow.com/a/15535110/242520 –

+0

tất cả 'dept_name' trong cả hai bảng là varchar (15). Tôi có phải gõ 'set foreign_key_checks = 0' không? – inherithandle

+0

nhập 'set foreign_key_checks = 0' vào' mysql> 'không sửa lỗi. – inherithandle

Trả lời

40

Cú pháp của FOREIGN KEY cho CREATE TABLE được cấu trúc như sau:

FOREIGN KEY (index_col_name) 
     REFERENCES table_name (index_col_name,...) 

Vì vậy, MySQL DDL của bạn nên là:

create table course (
     course_id varchar(7), 
     title varchar(50), 
     dept_name varchar(20), 
     credits numeric(2 , 0), 
     primary key (course_id), 
     FOREIGN KEY (dept_name) 
      REFERENCES department (dept_name) 
    ); 

Ngoài ra, trong bảng departmentdept_name nên VARCHAR(20)

Thông tin khác có thể được tìm thấy trong số MySQL documentation

+0

Tôi sẽ rất vui khi bạn giải thích chi tiết những câu nói đó là gì. Tôi chưa bao giờ nhìn thấy chữ “CONSTRAINT'. – inherithandle

+0

'CONSTRAINT link_dept_course' đưa ra một biểu tượng cho mối quan hệ này. và nó là tùy chọn. Nếu mệnh đề không được đưa ra, hoặc một biểu tượng không được bao gồm sau từ khóa CONSTRAINT, một tên cho ràng buộc được tạo tự động. FYI: http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html – Strik3r

+0

Phần ràng buộc là tùy chọn, nhưng danh sách các cột PK thì không. Vì vậy, bộ phận tham khảo 'so với' bộ phận tham khảo (dept_name) 'thực sự sửa chữa nó. Tôi không biết rằng MySQL không hỗ trợ ký pháp "ngắn tay" (như được định nghĩa bởi tiêu chuẩn SQL) –

6
foreign key (dept_name) references department 

Cú pháp này không hợp lệ cho MySQL. Thay vào đó, nó phải là:

foreign key (dept_name) references department(dept_name) 

MySQL requires dept_name to be used twice. Một lần để xác định cột nước ngoài, và một lần để xác định cột chính.

13.1.17.2. Using FOREIGN KEY Constraints

... [the] essential syntax for a foreign key constraint definition in a CREATE TABLE or ALTER TABLE statement looks like this:

[CONSTRAINT [symbol]] FOREIGN KEY 
    [index_name] (index_col_name, ...) 
    REFERENCES tbl_name (index_col_name, ...) 
    [ON DELETE reference_option] 
    [ON UPDATE reference_option] 

reference_option: 
    RESTRICT | CASCADE | SET NULL | NO ACTION 
19

Có thể các cột dept_name của bạn có bộ ký tự khác nhau.

Bạn có thể thử thay đổi một hoặc cả hai trong số họ:

ALTER TABLE department MODIFY dept_name VARCHAR(20) CHARACTER SET utf8; 
ALTER TABLE course MODIFY dept_name VARCHAR(20) CHARACTER SET utf8; 
+0

Đó là một điều khó khăn. Tôi đã có một bảng sử dụng một cách rõ ràng UTF8, không phải là khác. Khi di chuyển đến một máy chủ không sử dụng UTF8 làm mặc định, lược đồ làm việc ngừng hoạt động. Điều này đã cứu tôi! –

+0

Cảm ơn câu trả lời này, trong trường hợp của tôi, khóa chính là utf8_bin và "wannabe-foreign" là utf8_general_ci. Điều này đã cứu tôi quá! –

0

Nó đáng chú ý rằng lỗi này cũng có thể xảy ra nếu các bảng mục tiêu hoặc cột mà bạn đang sử dụng trong phần Tài liệu tham khảo chỉ đơn giản là không tồn tại .

40

Khi bạn nhận được thông báo lỗi mơ hồ này, bạn có thể tìm ra các lỗi cụ thể hơn bằng cách chạy

SHOW ENGINE INNODB STATUS; 

Những lý do phổ biến nhất là khi tạo ra một chìa khóa nước ngoài, cả hai lĩnh vực tham chiếu và các lĩnh vực trọng điểm nước ngoài cần phải phù hợp:

  • nên giống ví dụ InnoDB
  • Kiểu dữ liệu phải giống nhau và có cùng độ dài.
    ví dụ: VARCHAR (20) hoặc INT (10) UNSIGNED
  • Collation phải giống nhau. ví dụ: utf8
  • Độc đáo - Khóa ngoại nên tham chiếu đến trường duy nhất là (thường là riêng tư) trong bảng tham chiếu.

Một nguyên nhân của lỗi này là:
Bạn đã xác định một điều kiện SET NULL mặc dù một số trong các cột được định nghĩa là NOT NULL.

+4

Tôi chỉ bị vấp vì một trường là 'UNSIGNED' trong khi trường kia không phải, vì vậy chỉ cần chỉnh sửa câu trả lời của bạn để bao gồm. Hy vọng đó là OK. –

+0

@SimonEast thx để chỉ cho tôi đúng hướng có cùng Vấn đề :) – DevJ3rry

+0

Điều này đáng lẽ phải là câu trả lời được chấp nhận vì nó sẽ hữu ích nhất cho những người tìm thấy trang này tìm kiếm giải pháp cho vấn đề của họ – blueimpb

-1
CONSTRAINT vendor_tbfk_1 FOREIGN KEY (V_CODE) REFERENCES vendor (V_CODE) ON UPDATE CASCADE 

đây là cách nó có thể là ... Em hãy nhìn vào phần cột tham khảo. (V_code)

3

Cũng có thể gặp lỗi này nếu khóa ngoại không phải là khóa chính trong bảng riêng của nó.

Tôi đã thực hiện ALTER TABLE và vô tình xóa trạng thái khóa chính của cột và nhận được lỗi này.

0

Chỉ cần thêm 'unsigned' cho ràng buộc NƯỚC NGOÀI

`FK` int(11) unsigned DEFAULT NULL, 
1

ERROR 1215 (HY000): Cannot add foreign key constraint

Nó cũng đáng chú ý là bạn nhận được lỗi này khi loại của cột đó là khóa ngoại trong một doesn thể không đối sánh rõ ràng cột trong bảng chính xác.

Ví dụ:

alter table schoolPersons 
     add index FKEF5AB5E532C8FBFA (student_id), 
     add constraint FKEF5AB5E532C8FBFA 
     foreign key (student_id) 
     references student (id); 
ERROR 1215 (HY000): Cannot add foreign key constraint 

này là do lĩnh vực student_id được định nghĩa là:

mysql> desc schoolPersons; 
+--------------------+------------+------+-----+---------+----------------+ 
| Field    | Type  | Null | Key | Default | Extra   | 
+--------------------+------------+------+-----+---------+----------------+ 
| student_id   | bigint(20) | YES |  | NULL |    | 

trong khi id lĩnh vực trong bảng student được định nghĩa là:

mysql> desc persons; 
+--------------+----------------------+------+-----+-------------------+-----------------+ 
| Field  | Type     | Null | Key | Default   | Extra   | 
+--------------+----------------------+------+-----+-------------------+-----------------+ 
| id   | int(10) unsigned  | NO | PRI | NULL    | auto_increment | 

bigint(20) (chi ted từ Java long bởi hibernate) không tương thích với int(10) unsigned (Java int).

0

Dưới đây đang làm việc cho tôi

set @@foreign_key_checks=0; 
ALTER TABLE `table1` ADD CONSTRAINT `table1_fk1` FOREIGN KEY (`coloumn`) REFERENCES `table2` (`id`) ON DELETE CASCADE; 
0

I don't meet the problem as you. But I get the same ERROR Message. So I mark it down here for others' convience.

Kiểm tra charset của hai bảng nếu loại cột là char hoặc varchar. Tôi sử dụng charset=gbk nhưng tôi tạo bảng mới có mặc định là charset=utf8. Vì vậy bộ ký tự không giống nhau.

ERROR 1215 (HY000): Cannot add foreign key constraint 

Để giải quyết nó là sử dụng cùng một bộ ký tự. Ví dụ: utf8.

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