Thêm khóa ngoại vào bảng hiện có


324

Tôi muốn thêm Khóa ngoài vào bảng có tên là "katalog".

ALTER TABLE katalog 
ADD CONSTRAINT `fk_katalog_sprache` 
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

Khi tôi cố gắng làm điều này, tôi nhận được thông báo lỗi này:

Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150)

Lỗi trong Trạng thái INNODB:

120405 14:02:57 Lỗi trong ràng buộc khóa ngoài của bảng mytable. # Sll-7fb1_7d3a:

FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL:
Cannot resolve table name close to:
(`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL

Khi tôi sử dụng truy vấn này, nó hoạt động, nhưng với hành động "xóa" sai:

ALTER TABLE `katalog` 
ADD FOREIGN KEY (`Sprache` ) REFERENCES `sprache` (`ID` )

Cả hai bảng là InnoDB và cả hai trường là "INT (11) không null". Tôi đang sử dụng MySQL 5.1.61. Đang cố gắng thực hiện Truy vấn ALTER này với MySQL Workbench (mới nhất) trên MacBook Pro.

Bảng tạo báo cáo:

CREATE TABLE `katalog` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`AnzahlSeiten` int(4) unsigned NOT NULL,
`Sprache` int(11) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `katalogname_uq` (`Name`)
 ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC$$

CREATE TABLE `sprache` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
 `Bezeichnung` varchar(45) NOT NULL,
 PRIMARY KEY (`ID`),
 UNIQUE KEY `Bezeichnung_UNIQUE` (`Bezeichnung`),
KEY `ix_sprache_id` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

1
Vì bạn không đăng kết quả đầu ra SHOW CREATE TABLE, tôi chỉ có thể hỏi - tên cột có thực sự là ID không, có phải là chữ hoa không?
NB

Vâng, bây giờ dễ dàng hơn để phát hiện - katalogint(11) unsigned. sprachekhông có usignedphần, do đó hai cột không giống nhau.
NB

Ý bạn là, cả hai trường Chính phải cùng kiểu dữ liệu?
frgtv10

2
Đây là vấn đề với thiết kế của bạn: đầu tiên, bạn đang tham khảo hai auto_incrementcột không tốt. Ngoài ra, hướng dẫn sử dụng MySQL nói : Corresponding columns in the foreign key and the referenced key must have similar internal data types inside InnoDB so that they can be compared without a type conversion. The size and sign of integer types must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.. Do đó, có, loại dữ liệu tương tự và cùng một dấu hiệu.
NB

2
Tôi không tham khảo hai trường auto_increment. katalog.Sprache (không tự động) -> spache.ID (tự động)
frgtv10

Câu trả lời:


560

Để thêm khóa ngoại (class_id) vào bảng hiện có (người dùng), hãy làm theo các bước sau:

ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE users ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

12
Lý do giúp tôi hiểu và ghi nhớ. Điều này là do bạn không thể thêm khóa ngoại vào trường không dấu, đúng không?
PixMach

8
@PixMach, câu trả lời là không. Bạn có thể đã ký số nguyên dưới dạng khóa ngoại. Như NB đã lưu ý về câu hỏi, loại và dấu hiệu của các trường cần khớp. Vì vậy, nếu khóa chính của bạn trong bảng tra cứu là KHÔNG ĐƯỢC KÝ, thì trường khóa ngoài cũng phải được CHẤP NHẬN. Nếu trường khóa chính được ký, thì trường khóa ngoài cũng phải được ký. Hãy nghĩ về nó theo cách này: bất cứ điều gì cột trong một bảng được định nghĩa như trong BẢNG TẠO SHOW, nó cần phải có cùng định nghĩa trong bảng khác.
Ben Keene

1
Lưu ý rằng điều này cũng có thể được thực hiện với một truy vấn duy nhất (có thể tốt hơn trong trường hợp thất bại, v.v.)
Stijn de Witt

6
Tôi đã phải chạy "SET FOREIGN_KEY_CHECKS = 0;" trước khi chạy lệnh ADD CONSTRAINT hoặc SQL sẽ phàn nàn "Không thể thêm hoặc cập nhật một hàng con: một ràng buộc khóa ngoại không thành công".
Erin Geyer

2
Đừng không chỉ chạy "SET FOREIGN_KEY_CHECKS = 0;" nếu bạn gặp lỗi "một ràng buộc khóa ngoại thất bại", rõ ràng bạn có dữ liệu xấu mà bạn phải sửa nếu không bạn sẽ gặp vấn đề lớn hơn.
Mê cungChaZer

72

Chỉ cần sử dụng truy vấn này, tôi đã thử nó theo kịch bản của tôi và nó hoạt động tốt

ALTER TABLE katalog ADD FOREIGN KEY (`Sprache`) REFERENCES Sprache(`ID`);

25

Các bước đơn giản ...

ALTER TABLE t_name1 ADD FOREIGN KEY (column_name) REFERENCES t_name2(column_name)

15

kiểm tra liên kết này. Nó đã giúp tôi với errno 150: http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/

Trên đỉnh đầu tôi có hai điều tôi nghĩ đến.

  • Chỉ mục khóa ngoại của bạn có phải là một tên duy nhất trong toàn bộ cơ sở dữ liệu (số 3 trong danh sách) không?
  • Bạn đang cố gắng đặt PK bảng thành NULL khi cập nhật (số 5 trong danh sách)?

Tôi đoán vấn đề là do bộ NULL được cập nhật (nếu bộ não của tôi không bị lạc hậu ngày hôm nay vì chúng thường như vậy ...).

Chỉnh sửa: Tôi đã bỏ lỡ các ý kiến ​​về bài viết gốc của bạn. Các cột int không dấu / không dấu có thể giải quyết trường hợp của bạn. Hy vọng liên kết của tôi sẽ giúp ai đó trong tương lai suy nghĩ.


13
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

Nhưng bảng của bạn có:

CREATE TABLE `katalog` (
`Sprache` int(11) NOT NULL,

không thể đặt cột Sprache thành NULL vì nó được định nghĩa là KHÔNG NULL.


5

MySQL sẽ thực hiện truy vấn này:

ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

Chúc mừng!


5

Làm thế nào để khắc phục Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150) in mysql.

  1. thay đổi bảng của bạn và thêm một chỉ mục cho nó ..

    ALTER TABLE users ADD INDEX index_name (index_column)
  2. Bây giờ thêm các ràng buộc

    ALTER TABLE foreign_key_table
    ADD CONSTRAINT foreign_key_name FOREIGN KEY (foreign_key_column)
    REFERENCES primary_key_table (primary_key_column) ON DELETE NO ACTION
    ON UPDATE CASCADE;

Lưu ý nếu bạn không thêm chỉ mục thì nó sẽ không hoạt động.

Sau khi chiến đấu với nó trong khoảng 6 giờ, tôi đã đưa ra giải pháp, tôi hy vọng điều này sẽ cứu một linh hồn.


4

Khi bạn thêm một ràng buộc khóa ngoài vào bảng bằng ALTER TABLE, hãy nhớ tạo các chỉ mục cần thiết trước tiên.

  1. Tạo chỉ mục
  2. Bảng thay đổi

Tôi đã tạo chỉ mục cho cả hai. Khi tôi cố chạy tôi nhận được thông báo lỗi như trước. Khi tôi từ chối phần "bật xóa khi cập nhật", nó hoạt động nhưng với hành động "xóa" sai;)
frgtv10

@ frgtv10 rất có thể các dữ liệu bảng xung đột với "khi xóa".
Maksym Polshcha

3

thử tất cả trong một truy vấn

  ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0,
      ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

0

điều này về cơ bản là xảy ra vì các bảng của bạn nằm trong hai bảng mã khác nhau. như một ví dụ, một bảng được tạo trong charset = utf-8 và các bảng khác được tạo trong CHARSET = latin1 để bạn có thể thêm khóa foriegn vào các bảng này. sử dụng cùng một bảng mã trong cả hai bảng sau đó bạn sẽ có thể thêm các khóa foriegn. lỗi 1005 ràng buộc khóa foriegn hình thành không chính xác có thể giải quyết từ điều này


0

tôi đã vượt qua cùng một vấn đề. Tôi là trường hợp bảng của tôi đã có dữ liệu và có khóa trong bảng này không có trong bảng tham chiếu. Vì vậy, tôi đã phải xóa các hàng này không tôn trọng các ràng buộc và mọi thứ đã làm việc.


0

bước 1: chạy tập lệnh này

SET FOREIGN_KEY_CHECKS=0;

bước 2: thêm cột

ALTER TABLE mileage_unit ADD COLUMN COMPANY_ID BIGINT(20) NOT NULL

Bước 3: thêm khóa ngoại vào cột đã thêm

ALTER TABLE mileage_unit
ADD FOREIGN KEY (COMPANY_ID) REFERENCES company_mst(COMPANY_ID);

Bước 4: chạy tập lệnh này

SET FOREIGN_KEY_CHECKS=1;

-1
 ALTER TABLE TABLENAME ADD FOREIGN KEY (Column Name) REFERENCES TableName(column name)

Thí dụ:-

ALTER TABLE Department ADD FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId)

1
Vui lòng thêm một số lời giải thích vào mã của bạn để những người khác có thể học hỏi từ nó
Nico Haase
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.