2015-03-25 16 views
7

Tôi đang cố gắng tạo cơ sở dữ liệu cho hệ thống quản lý phòng tập thể dục, nhưng tôi không thể hiểu tại sao tôi gặp phải lỗi này. Tôi đã cố gắng tìm kiếm câu trả lời ở đây, nhưng tôi không thể tìm thấy nó.Không thể thêm ràng buộc khóa ngoài - MySQL ERROR 1215 (HY000)

ERROR 1215 (HY000): Cannot add foreign key constraint 

CREATE TABLE sales(
    saleId int(100) NOT NULL AUTO_INCREMENT, 
    accountNo int(100) NOT NULL, 
    payName VARCHAR(100) NOT NULL, 
    nextPayment DATE, 
    supplementName VARCHAR(250), 
    qty int(11), 
    workoutName VARCHAR(100), 
    sDate datetime NOT NULL DEFAULT NOW(), 
    totalAmount DECIMAL(11,2) NOT NULL, 
    CONSTRAINT PRIMARY KEY(saleId, accountNo, payName), 
    CONSTRAINT FOREIGN KEY(accountNo) REFERENCES accounts(accountNo) ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT FOREIGN KEY(payName) REFERENCES paymentFor(payName) ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT FOREIGN KEY(supplementName) REFERENCES supplements(supplementName) ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT FOREIGN KEY(workoutName) REFERENCES workouts(workoutName) ON DELETE CASCADE ON UPDATE CASCADE 
); 
    ALTER TABLE sales AUTO_INCREMENT = 2001; 

Đây là bảng cha.

CREATE TABLE accounts(
    accountNo int(100) NOT NULL AUTO_INCREMENT, 
    accountType VARCHAR(100) NOT NULL, 
    firstName VARCHAR(50) NOT NULL, 
    lastName VARCHAR(60) NOT NULL, 
    birthdate DATE NOT NULL, 
    gender VARCHAR(7), 
    city VARCHAR(50) NOT NULL, 
    street VARCHAR(50), 
    cellPhone VARCHAR(10), 
    emergencyPhone VARCHAR(10), 
    email VARCHAR(150) NOT NULL, 
    description VARCHAR(350), 
    occupation VARCHAR(50), 
    createdOn datetime NOT NULL DEFAULT NOW(), 
    CONSTRAINT PRIMARY KEY(accountNo) 
); 
    ALTER TABLE accounts AUTO_INCREMENT = 1001; 


CREATE TABLE supplements(
    supplementId int(100) NOT NULL AUTO_INCREMENT, 
    supplementName VARCHAR(250) NOT NULL, 
    manufacture VARCHAR(100), 
    description VARCHAR(150), 
    qtyOnHand INT(5), 
    unitPrice DECIMAL(11,2), 
    manufactureDate DATE, 
    expirationDate DATE, 
    CONSTRAINT PRIMARY KEY(supplementId, supplementName) 
); 
    ALTER TABLE supplements AUTO_INCREMENT = 3001; 

CREATE TABLE workouts(
    workoutId int(100) NOT NULL AUTO_INCREMENT, 
    workoutName VARCHAR(100) NOT NULL, 
    description VARCHAR(7500) NOT NULL, 
    duration VARCHAR(30), 
    CONSTRAINT PRIMARY KEY(workoutId, workoutName) 
); 
    ALTER TABLE workouts AUTO_INCREMENT = 4001; 



CREATE TABLE paymentFor(
    payId int(100) NOT NULL AUTO_INCREMENT, 
    payName VARCHAR(100) NOT NULL, 
    amount DECIMAL(11,2), 
    CONSTRAINT PRIMARY KEY(payId, payName) 
); 
    ALTER TABLE paymentFor AUTO_INCREMENT = 5001; 

Các bạn có thể giúp tôi giải quyết vấn đề này không? Cảm ơn.

+1

Không chắc nếu đây là nó, nhưng trong 'sales', không phải' additionalName' cũng không 'workoutName' là NOT NULL giống như các cột mà chúng đang tham chiếu trong bảng' workouts' và bảng 'bổ sung'. Tôi đang ngân hàng trên lý thuyết rằng các cột liên quan đến các khóa ngoại phải khớp chính xác. – MingShun

+1

Có thể trùng lặp với [MySQL - Mã lỗi 1215, không thể thêm ràng buộc khóa ngoài] (http://stackoverflow.com/questions/22799001/mysql-error-code-1215-cannot-add-foreign-key-constraint) –

Trả lời

18

Để trường được xác định là foreign key, trường mẹ được tham chiếu phải có chỉ mục được xác định trên trường đó.

Theo tài liệu trên foreign key chế:

THAM KHẢO parent_tbl_name (index_col_name, ...)

Xác định một INDEX trên workouts.workoutName, paymentFor.paymentNamesupplements.supplementName tương ứng. Và đảm bảo rằng các định nghĩa cột con phải khớp với các định nghĩa cột mẹ của chúng.

nét

Thay đổi workouts bảng như sau:

CREATE TABLE workouts(
    workoutId int(100) NOT NULL AUTO_INCREMENT, 
    workoutName VARCHAR(100) NOT NULL, 
    description VARCHAR(7500) NOT NULL, 
    duration VARCHAR(30), 

    KEY (workoutName), -- <---- this is newly added index key 

    CONSTRAINT PRIMARY KEY(workoutId, workoutName) 
); 

Thay đổi supplements bảng định nghĩa như sau:

CREATE TABLE supplements(
    supplementId int(100) NOT NULL AUTO_INCREMENT, 
    supplementName VARCHAR(250) NOT NULL, 
    manufacture VARCHAR(100), 
    description VARCHAR(150), 
    qtyOnHand INT(5), 
    unitPrice DECIMAL(11,2), 
    manufactureDate DATE, 
    expirationDate DATE, 

    KEY (supplementName), -- <---- this is newly added index key 

    CONSTRAINT PRIMARY KEY(supplementId, supplementName) 
); 

Thay đổi paymentFor bảng định nghĩa như sau:

CREATE TABLE paymentFor(
    payId int(100) NOT NULL AUTO_INCREMENT, 
    payName VARCHAR(100) NOT NULL, 
    amount DECIMAL(11,2), 

    KEY (payName), -- <---- this is newly added index key 

    CONSTRAINT PRIMARY KEY(payId, payName) 
); 

Bây giờ, thay đổi con bảng định nghĩa là b elow:

CREATE TABLE sales(
    saleId int(100) NOT NULL AUTO_INCREMENT, 
    accountNo int(100) NOT NULL, 
    payName VARCHAR(100) NOT NULL, 
    nextPayment DATE, 
    supplementName VARCHAR(250) NOT NULL, 
    qty int(11), 
    workoutName VARCHAR(100) NOT NULL, 
    sDate datetime NOT NULL DEFAULT NOW(), 
    totalAmount DECIMAL(11,2) NOT NULL, 
    CONSTRAINT PRIMARY KEY(saleId, accountNo, payName), 
    CONSTRAINT FOREIGN KEY(accountNo) 
     REFERENCES accounts(accountNo) 
     ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT FOREIGN KEY(payName) 
     REFERENCES paymentFor(payName) 
     ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT FOREIGN KEY(supplementName) 
     REFERENCES supplements(supplementName) 
     ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT FOREIGN KEY(workoutName) 
     REFERENCES workouts(workoutName) 
     ON DELETE CASCADE ON UPDATE CASCADE 
); 

Tham khảo:

[CONSTRAINT [biểu tượng]] FOREIGN KEY
[INDEX_NAME] (index_col_name, ...)
TÀI LIỆU THAM KHẢO tbl_name (index_col_name, ...)
[ON DELETE reference_option]
[ON UPDATE reference_option]

reference_option:
GIỚI HẠN | CASCADE | SET NULL | NO ACTION

+0

Cảm ơn bạn rất nhiều! @Ravinder – dnuka

4

Phím ngoài là cách thực hiện mối quan hệ/ràng buộc giữa các cột trong các bảng khác nhau.

Có nhiều loại khác nhau của những hạn chế ảnh hưởng đến cách họ đang thực thi khi một hàng được cập nhật hoặc xóa khỏi bảng cha:

Cascade: Nếu một hàng sẽ bị xóa khỏi cha mẹ sau đó bất kỳ hàng ở trẻ em bảng có giá trị FK phù hợp cũng sẽ bị xóa. Tương tự cho các thay đổi đối với giá trị trong bảng cha.

Restrict: Không thể xóa hàng khỏi bảng cha nếu điều này sẽ phá vỡ ràng buộc FK với bảng con. Tương tự cho các thay đổi đối với giá trị trong bảng cha.

No Action: Rất giống với “Hạn chế” ngoại trừ bất kỳ sự kiện/trình kích hoạt nào trên bảng cha sẽ được thực thi trước khi thực thi ràng buộc - cung cấp cho người viết ứng dụng tùy chọn giải quyết bất kỳ xung đột ràng buộc FK nào bằng quy trình được lưu trữ.

Set NULL: Nếu NULL là một giá trị được phép cho cột FK trong bảng con sau đó nó sẽ được thiết lập để NULL nếu các dữ liệu liên quan trong bảng cha được cập nhật hoặc xóa.

Set Default: Nếu có giá trị mặc định cho cột FK trong bảng con thì nó sẽ được sử dụng nếu dữ liệu được liên kết trong bảng chính được cập nhật hoặc bị xóa. Lưu ý rằng điều này không được thực hiện trong phiên bản này - ràng buộc có thể được thêm vào lược đồ nhưng mọi xóa hoặc cập nhật tiếp theo cho cột trong bảng cha sẽ không thành công.

25

Nếu bạn đã bao giờ muốn tìm hiểu, tại sao lỗi được, tất cả các bạn phải làm là chạy dưới lệnh và tìm kiếm "MỚI NHẤT LỖI CHÍNH NƯỚC NGOÀI"

Command để chạy: -

mysql> SHOW ENGINE INNODB STATUS 

Bạn sẽ biết lý do cho các lỗi như vậy của mình.

+1

Cảm ơn, điều đó đã giúp ích rất nhiều! –

+1

@John Cargo Tôi tiếp tục làm điều này và làm điều này và làm điều này và không có gì xảy ra. Tôi không biết liệu tôi có đang chạy sai địa điểm hay gì đó không. – FrostyStraw

+0

Nó sẽ trả về thông điệp 'trạng thái'. Bạn có thể vui lòng cho tôi biết, ouput là gì, khi bạn chạy trên mã? –

0

Tôi không trả lời câu hỏi trên mà chỉ dành cho những người sẽ gặp lỗi mysql tương tự.

Tất cả những gì tôi làm là thay đổi công cụ bảng được tham chiếu thành innodb.

3

Một số lần bạn sẽ nhận được lỗi này "# 1215 - Không thể thêm ràng buộc khóa ngoài" vì bảng TYPE (InnoDB, MyISAM, ..) không khớp.

Vì vậy, thay đổi loại bảng của bạn vào cùng và thử áp dụng cho ràng buộc khoá ngoại

mysql> ALTER TABLE table_name ENGINE=InnoDB;

mysql> ALTER TABLE Orders ADD FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)

1

tôi đã nhận được báo lỗi tương tự. Lý do là tôi đã đề cập đến một cột trong một bảng được tạo bằng bộ chữ utf8 từ một bảng được tạo bằng cách sử dụng bộ ký tự latin.

Các bảng được tạo bằng cách sử dụng bàn làm việc mySQL tạo tiện ích bảng có ký tự mặc định là latin.

Cách tiếp cận dễ dàng để tìm ra điều này nếu bạn đang sử dụng bàn làm việc là để xem bảng tạo bảng sao kê của bất kỳ bảng nào. Bạn sẽ có chuỗi ký tự mặc định ở cuối.

2

Điều này có thể phù hợp với một số người.Chỉ cần thêm bộ ký tự mặc định là utf8

DEFAULT CHARACTER SET = utf8; 
+0

+1 - đây là vấn đề đối với tôi. Lý do là nếu bạn có một trường kiểu chuỗi tham chiếu một trường kiểu chuỗi, nó chỉ có thể liên kết hai chỉ mục với nhau nếu chúng đang sử dụng cùng một bộ ký tự. Trong trường hợp của tôi, một trong các bảng đã sử dụng utf8 và cái kia là latin1, vì vậy việc thay đổi nó thành utf8 đã khắc phục vấn đề này. – Jules

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