mysql Ràng buộc khóa ngoài là lỗi hình thành không chính xác


173

Tôi có hai bảng, table1là bảng cha với một cột IDtable2với một cột IDFromTable1(không phải tên thật) khi tôi đặt một FK trên IDFromTable1để IDtable1Tôi nhận được lỗi Foreign key constraint is incorrectly formed error. Tôi muốn xóa bản ghi bảng 2 nếu table1bản ghi bị xóa. Cảm ơn vì bất kì sự giúp đỡ

ALTER TABLE `table2`  
   ADD CONSTRAINT `FK1` 
      FOREIGN KEY (`IDFromTable1`) REFERENCES `table1` (`ID`) 
      ON UPDATE CASCADE 
      ON DELETE CASCADE;

Hãy cho tôi biết nếu có thông tin khác là cần thiết. Tôi chưa quen với mysql


4
Bạn đang sử dụng công cụ gì cho các bảng của bạn? Loại nào table2.IDFromTable1table1.ID?
Romain

5
Ngoài ra, kiểm tra xem các bộ ký tự cho cả hai bảng có giống nhau không.
Carsten

Cả hai công cụ bảng là innoDB. không chắc chắn nơi tìm bộ ký tự và cả hai đều là kiểu char. ID là khóa chính trong
bảng1

2
Vui lòng cung cấp định nghĩa bảng cho bảng1 và bảng2. Làm thế nào bạn nhận được lỗi này? Bạn có sử dụng một công cụ để tạo khóa ngoại? Có vẻ như đó không phải là lỗi bản địa của MySQL.
Devart

@ user516883 - Bạn có cần trợ giúp để có được định nghĩa bảng không? Trong HeidiSQL bạn chỉ cần nhấp vào tab mã TẠO .
Álvaro González

Câu trả lời:


422

Tôi gặp vấn đề tương tự với HeidiSQL. Lỗi bạn nhận được rất khó hiểu. Vấn đề của tôi cuối cùng là cột khóa ngoại và cột tham chiếu không cùng loại hoặc độ dài.

Cột khóa ngoại là SMALLINT(5) UNSIGNEDvà cột được tham chiếu là INT(10) UNSIGNED. Khi tôi tạo cho cả hai cùng một loại chính xác, việc tạo khóa ngoại hoạt động hoàn hảo.


58
Hoặc có thể là cột được tham chiếu không phải là khóa chính
nawfal

9
Một vấn đề tương tự đối với tôi - bảng tham chiếu chưa tồn tại. Rất tiếc.
Amalgovinus

5
Tôi đã hoàn toàn trải nghiệm những gì Jake đã làm, nhưng tôi đã gặp phải một vấn đề FK khác (loại khác) trên HeidiQuery. FK trên varchars cần phải được đối chiếu giống nhau. Hy vọng rằng sẽ giúp người khác trong tương lai!
cbloss793

10
Trong trường hợp của tôi, đó là do Mã hóa và Đối chiếu khác nhau.
Khatri

1
@nawfal - Tôi tin rằng nó không nhất thiết phải là khóa chính, nhưng nó PHẢI có một chỉ mục. Khóa chính tự động được lập chỉ mục.
Itai

48

Tôi gặp vấn đề tương tự khi bảng cha được tạo bằng MyISAMengine. Đó là một sai lầm ngớ ngẩn, mà tôi đã sửa chữa:

ALTER TABLE parent_table ENGINE=InnoDB;

Cảm ơn bạn rất nhiều, tôi đã phát điên với điều này. Bất cứ ý tưởng tại sao cơ sở dữ liệu sẽ đột nhiên chuyển động cơ cho các bảng?
Robert Franklin

28

đảm bảo các cột giống hệt nhau (cùng loại) và nếu cột tham chiếu thì không primary_key, hãy chắc chắn rằng đó là cột INDEXED.


Nó thậm chí đã xảy ra với tôi rằng, không có lỗi, nhưng khóa ngoại không được thêm vào (1 và 1 không thực sự), nhưng sau khi thêm đơn giản KEY referencing_column(referencing_column) TRƯỚC cả hai định nghĩa khóa ngoại, cả hai đều được thêm thành công :)
jave.web

2
Khóa không được lập chỉ mục là vấn đề của tôi.
Neil Masters

1
Tôi gặp vấn đề này và vấn đề là tôi có khóa chính cột kép và bạn không thể sử dụng cột thứ 2 của khóa chính làm khóa ngoại. Vì vậy, tôi chỉ cần thêm chỉ mục riêng cho cột thứ 2 của khóa chính và sau đó nó hoạt động.
Firze

21

Cú pháp để xác định khóa ngoại là rất dễ tha thứ, nhưng đối với bất kỳ ai khác vấp phải điều này, thực tế là khóa ngoại phải "cùng loại" áp dụng ngay cả đối chiếu, không chỉ kiểu dữ liệu và độ dài và ký bit.

Không phải là bạn sẽ trộn đối chiếu trong mô hình của mình (phải không?) Nhưng nếu bạn làm vậy, hãy chắc chắn các trường khóa chính và ngoại khóa của bạn có cùng kiểu đối chiếu trong phpmyadmin hoặc Heidi SQL hoặc bất cứ điều gì bạn sử dụng.

Hy vọng điều này giúp bạn tiết kiệm bốn giờ dùng thử và lỗi nó làm tôi mất.


1
Cảm ơn! Hóa ra máy chủ trực tuyến của tôi sử dụng công cụ ISAM và đối với nhà phát triển địa phương tôi sử dụng InnoDB. Khi tôi sao lưu một bảng từ máy chủ đến địa phương ... bùng nổ.
Ben

Các phiên bản gần đây của MariaDB dường như sử dụng utf8_mb4 làm bộ ký tự mặc định (khi không được đặt rõ ràng trong cấu hình máy chủ), do đó, COLLATE utf8mb4_unicode_civấn đề (không mong muốn) của tôi (trên máy dev).
JonnyJD

13

Tôi đã có cùng một vấn đề, nhưng đã giải quyết nó.

Chỉ cần đảm bảo rằng cột 'ID' trong 'bảng1' có chỉ số ĐỘC ĐÁO !

Và tất nhiên, loại, độ dài của các cột 'ID' và 'IDFromTable1' trong hai bảng này phải giống nhau. Nhưng bạn đã biết về điều này.


Bạn làm cho ngày của tôi.
kevenlolo

1
Rất vui được giúp đỡ! ;)
Renat Gatin

Không chắc chắn về các chi tiết, nhưng tôi đã có một khóa tổng hợp với lỗi này đã được sửa bằng cách thêm các chỉ mục duy nhất cho các cột.
Halvor Holsten Strand

Cột được tham chiếu phải được lập chỉ mục, nó không phải là duy nhất (mặc dù đó là trường hợp thông thường).
Barmar

10

Chỉ cần hoàn thành.

Lỗi này cũng có thể xảy ra nếu bạn có khóa ngoại với VARCHAR (..) và bộ ký tự của bảng được tham chiếu khác với bảng tham chiếu nó.

ví dụ VARCHAR (50) trong Bảng Latin1 khác với VARCHAR (50) trong Bảng UTF8.


1
Ngay cả utf8_unicode_ci và utf8_general_ci cũng gây ra lỗi
leuchtdiode

10

Các văn bản lỗi mysql không giúp được gì nhiều, trong trường hợp của tôi, cột có ràng buộc "không null", vì vậy "không xóa tập hợp null" không được phép


7

Nếu mọi thứ đều ổn, chỉ cần thêm ->unsigned();vào cuối foregin key.

nếu nó không hoạt động, hãy kiểm tra kiểu dữ liệu của cả hai trường. họ phải giống nhau


5

Tôi có cùng một vấn đề, cả hai cột là INT (11) KHÔNG NULL nhưng tôi không thể tạo khóa ngoại. Tôi đã phải vô hiệu hóa kiểm tra khóa ngoại để chạy thành công:

SET FOREIGN_KEY_CHECKS=OFF;
ALTER TABLE ... ADD CONSTRAINT ...
SET FOREIGN_KEY_CHECKS=ON;

Hy vọng điều này sẽ giúp được ai đó.


4
Trên thực tế, đó là FOREIGN_KEY_CHECKS
Xmanoux

Điều này đã giúp tôi vượt qua hơn nữa, nhưng vấn đề của tôi là thiếu chỉ số nguyên thủy trong cột
bumerang

4

Thêm một nguyên nhân có thể xảy ra cho việc hiển thị lỗi này. Thứ tự mà tôi đang tạo bảng là sai. Tôi đã cố gắng tham chiếu một khóa từ một bảng chưa được tạo.


4

(Lần gửi lại cuối cùng) Ngay cả khi tên trường và kiểu dữ liệu giống nhau nhưng đối chiếu không giống nhau, nó cũng sẽ dẫn đến vấn đề đó.

Ví dụ

    TÊN TBL | LOẠI DỮ LIỆU | THU THẬP        

    Hoạt độngID | INT |         Latin1_general_ci     Hoạt độngID | INT |         utf8_general_ci

Hãy thử thay đổi nó thành

    TÊN TBL | LOẠI DỮ LIỆU | THU THẬP        

    Hoạt độngID | INT |         Latin1_general_ci     Hoạt độngID | INT |         Latin1_general_ci

....

Điều này làm việc cho tôi.


3

Kiểm tra công cụ bảng, cả hai bảng phải là cùng một công cụ, điều đó đã giúp tôi rất nhiều.


Điểm tốt! Tôi đang xử lý cơ sở dữ liệu Zen Cart trong MySQL có các bảng đều nằm trong công cụ MyISAM theo mặc định. Tôi đã thêm một bảng bằng cách sử dụng công cụ InnoDB và cố gắng thêm một ràng buộc khóa ngoại từ bảng của tôi vào bảng Zen Cart lõi. Nó đã thất bại với lỗi 'hình thành không chính xác' tối nghĩa này. Bạn có thể thấy động cơ cho mỗi bảng vớiSHOW TABLE STATUS LIKE 'table_name';
Neek

2

Tôi cũng có những vấn đề tương tự.

Vấn đề là cột tham chiếu không phải là khóa chính.

Làm cho nó một chìa khóa chính và vấn đề được giải quyết.


Nó không cần phải là PK, nó cũng có thể KHÔNG ĐỘC ĐÁO.
philipxy

Trên thực tế ... trong trường hợp của tôi chỉ đơn giản là đặt nó thành một loại chỉ mục hoạt động bình thường.
hendr1x

2

Mặc dù các câu trả lời khác khá hữu ích, nhưng chỉ muốn chia sẻ kinh nghiệm của tôi.

Tôi gặp phải vấn đề khi tôi đã xóa một bảng idđã được tham chiếu là khóa ngoại trong các bảng khác ( có dữ liệu ) và cố gắng tạo lại / nhập bảng với một số cột bổ sung.

Truy vấn để giải trí (được tạo bằng phpMyAdmin) trông giống như sau:

CREATE TABLE `the_table` (
  `id` int(11) NOT NULL,            /* No PRIMARY KEY index */  
  `name` varchar(255) NOT NULL,
  `name_fa` varchar(255) NOT NULL,
  `name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

... /* SOME DATA DUMP OPERATION */

ALTER TABLE `the_table`
  ADD PRIMARY KEY (`id`), /* PRIMARY KEY INDEX */
  ADD UNIQUE KEY `uk_acu_donor_name` (`name`);

Như bạn có thể nhận thấy, PRIMARY KEYchỉ mục được đặt sau khi tạo ( và chèn dữ liệu ) gây ra sự cố.

Giải pháp

Giải pháp là thêm PRIMARY KEYchỉ mục vào truy vấn định nghĩa bảng cho idcái được tham chiếu là khóa ngoại, đồng thời xóa nó khỏi ALTER TABLEphần mà chỉ mục đang được đặt:

CREATE TABLE `the_table` (
  `id` int(11) NOT NULL PRIMARY KEY,            /* <<== PRIMARY KEY INDEX ON CREATION */  
  `name` varchar(255) NOT NULL,
  `name_fa` varchar(255) NOT NULL,
  `name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Nó làm việc cho tôi. Tôi đã lo lắng rằng tôi cần phải cài đặt lại phần mềm của mình;)
Dewlance

2

Tôi đã mất hàng giờ vì điều đó!

PK ở một bàn là utf8ở bàn khác utf8_unicode_ci!


1

Hãy thử chạy như sau:

hiển thị tạo bảng Phụ huynh

// và kiểm tra xem loại cho cả hai bảng có giống nhau không, như myISAM hoặc innoDB, v.v.
// Các khía cạnh khác để kiểm tra với thông báo lỗi này: các cột được sử dụng như nước ngoài 
các khóa phải được lập chỉ mục, chúng phải cùng loại 
(nếu tức là một loại thuộc loại nhỏ (5) và loại kia thuộc loại nhỏ (6), 
nó sẽ không hoạt động) và, nếu chúng là số nguyên, chúng sẽ không được ký.

// hoặc kiểm tra bộ ký tự
hiển thị các biến như "character_set_database";
hiển thị các biến như "collation_database";

// đã chỉnh sửa: hãy thử một cái gì đó như thế này
Bảng BẢNG2
THÊM CONSTRAINT fk_IdTable2
KHOẢN NGOẠI TỆ (Bảng1_Id)
TÀI LIỆU THAM KHẢO Bảng1 (Bảng1_Id)
TRÊN CẬP NHẬT CASCADE 
TRÊN CASCADE XÓA;

9
Hãy thử chạy TÌNH TRẠNG SHOW Engine INNODB để biết thêm chi tiết về lỗi
Sudhir Bastakoti

@SudhirBastakoti - +1! Điều đó đã làm nó cho tôi. Các chi tiết rất hữu ích. Đã có thể khắc phục vấn đề nhanh chóng.
Paul Carlton

1

Tôi gặp vấn đề tương tự với Symfony 2.8.

Tôi đã không nhận được nó lúc đầu, vì không có vấn đề tương tự với độ dài int của khóa ngoại, v.v.

Cuối cùng tôi phải làm như sau trong thư mục dự án. (Khởi động lại máy chủ không giúp được!)

app/console doctrine:cache:clear-metadata app/console doctrine:cache:clear-query app/console doctrine:cache:clear-result


1

cảm ơn S Doerin:

"Chỉ để hoàn thành. Lỗi này cũng có thể xảy ra nếu bạn có khóa ngoại với VARCHAR (..) và bộ ký tự của bảng được tham chiếu khác với bảng tham chiếu đến nó. Ví dụ: VARCHAR (50) trong Bảng Latin1 là khác với VARCHAR (50) trong Bảng UTF8. "

tôi đã giải quyết vấn đề này, thay đổi loại ký tự của bảng. sáng tạo có latin1 và đúng là utf8.

thêm dòng tiếp theo. THIẾT BỊ DEFAULT = utf8;


1

Tôi gặp vấn đề khi sử dụng bảng Alter để thêm khóa ngoại giữa hai bảng và điều giúp tôi đảm bảo mỗi cột mà tôi đang cố gắng thêm mối quan hệ khóa ngoại được lập chỉ mục. Để thực hiện điều này trong PHP myAdmin: Chuyển đến bảng và nhấp vào tab cấu trúc. Nhấp vào tùy chọn chỉ mục để lập chỉ mục cột mong muốn như trong ảnh chụp màn hình:

nhập mô tả hình ảnh ở đây

Khi tôi đã lập chỉ mục cả hai cột mà tôi đang cố gắng tham chiếu với các khóa ngoại của mình, tôi có thể sử dụng thành công bảng thay đổi và tạo mối quan hệ khóa ngoại. Bạn sẽ thấy các cột được lập chỉ mục như trong ảnh chụp màn hình bên dưới:

nhập mô tả hình ảnh ở đây

chú ý cách zip_code hiển thị trong cả hai bảng.


1

Bạn cần kiểm tra xem cả hai đều giống nhau trong tất cả các thuộc tính của nó, bao gồm trong "Đối chiếu"


1

Tôi đã sử dụng HeidiSQL và để giải quyết vấn đề này, tôi đã phải tạo một chỉ mục trong bảng được tham chiếu với tất cả các cột được tham chiếu.

thêm chỉ mục vào bảng Heidisql


Tương tự đối với tôi trong mysql: InnoDB yêu cầu lập chỉ mục trên khóa ngoại và khóa được tham chiếu để kiểm tra khóa ngoại có thể nhanh và không yêu cầu quét bảng.
hendr1x

1

Tôi gặp vấn đề tương tự vừa rồi. Trong trường hợp của tôi, tất cả những gì tôi phải làm là đảm bảo rằng bảng tôi đang tham chiếu trong khóa ngoại phải được tạo trước bảng hiện tại (trước đó trong mã). Vì vậy, nếu bạn đang tham chiếu một biến (x * 5), hệ thống sẽ biết x là gì (x phải được khai báo trong các dòng mã trước đó). Điều này giải quyết vấn đề của tôi, hy vọng nó sẽ giúp người khác.


Tôi đã gặp vấn đề tương tự trong MariaDB v10.3.18. Chúng tôi đã sử dụng MySQL trước đó và nó đã cảnh báo rằng một khóa ngoại được chỉ vào một bảng không tồn tại.
MarthyM

0

Tôi gặp vấn đề tương tự với Trình tạo lược đồ di chuyển của Laravel 5.1 với MariaDB 10.1.

Vấn đề là tôi đã gõ unignedthay vì unsigned(s chữ bị thiếu) trong khi đặt cột.

Sau khi sửa lỗi đánh máy đã được sửa cho tôi.


0

Ngay cả tôi cũng gặp vấn đề tương tự với mysql và liquidibase. Vì vậy, đây là vấn đề là: Bảng mà bạn muốn tham chiếu một cột của bảng khác là khác nhau trong trường hợp của kiểu dữ liệu hoặc về kích thước của kiểu dữ liệu.

Error appears in below scenario:
Scenario 1:
Table A has column id, type=bigint
Table B column referenced_id type varchar(this column gets the value from the id column of Table A.)
Liquibase changeset for table B:

    <changeset id="XXXXXXXXXXX-1" author="xyz">
            <column name="referenced_id" **type="varchar"**>
        </column>
            </changeset>
    <changeSet id="XXXXXXXXXXX-2" author="xyz">
                <addForeignKeyConstraint constraintName="FK_table_A"
                    referencedTableName="A" **baseColumnNames="referenced_id**"
                    referencedColumnNames="id" baseTableName="B" />
    </changeSet>

Table A changeSet:

    <changeSet id="YYYYYYYYYY" author="xyz">
     <column **name="id"** **type="bigint"** autoIncrement="${autoIncrement}">
                    <constraints primaryKey="true" nullable="false"/>
                </column>
    </changeSet>

Solution: 
correct the type of table B to bigint because the referenced table has type bigint.

Scenrario 2:
The type might be correct but the size might not.
e.g. :
Table B : referenced column type="varchar 50"
Table A : base column type ="varchar 255"

Solution change the size of referenced column to that of base table's column size.

0

Kiểm tra xem bạn đã chỉ định tên của bảng trong trường hợp thích hợp chưa (nếu tên bảng có phân biệt chữ hoa chữ thường trong cơ sở dữ liệu của bạn). Trong trường hợp của tôi, tôi đã phải thay đổi

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

đến

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `CUSTOMER` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

lưu ý customerthay đổi thành CUSTOMER.


0

Hoặc bạn có thể sử dụng DBDesigner4 có giao diện đồ họa để tạo cơ sở dữ liệu của bạn và liên kết chúng bằng FK. Nhấp chuột phải vào bảng của bạn và chọn 'Sao chép bảng SQL Tạo' để tạo mã.

nhập mô tả hình ảnh ở đây


0

Đó là một chủ đề cũ nhưng tôi đã khám phá ra một cái gì đó. Trong khi xây dựng một bàn làm việc MySQL, nó cũng có được các mối quan hệ của bảng khác. chỉ cần để lại các trụ cột bạn liên quan đến. Xóa các cột được thêm tự động khác. Điều này làm việc cho tôi.


0

Trường hợp của tôi là tôi đã có một lỗi đánh máy trên cột được giới thiệu:

MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( coutry_code );
ERROR 1005 (HY000): Can't create table `blog`.`t_user` (errno: 150 "Foreign key constraint is incorrectly formed")

Thông báo lỗi khá khó hiểu và tôi đã thử mọi cách - xác minh các loại cột, đối chiếu, động cơ, v.v.

Tôi đã mất một lúc để ghi chú lỗi đánh máy và sau khi sửa xong, tất cả đều hoạt động tốt:

MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( country_code );
Query OK, 2 rows affected (0.039 sec)              
Records: 2  Duplicates: 0  Warnings: 0

0

Tôi gặp phải vấn đề này, lỗi xuất hiện khi bạn đặt khóa chính ở các loại dữ liệu khác nhau như:

Bảng 1:

 Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('product_name');
        });

ban 2:

Schema::create('brands', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('brand_name');
        });

kiểu dữ liệu cho id của bảng thứ hai phải là số gia


0

Vấn đề rất đơn giản để giải quyết

ví dụ: bạn có hai bảng có tên người dùngbài đăng và bạn muốn tạo khóa ngoại trong bảng bài đăng và bạn sử dụng phpMyAdmin

1) trong bảng bài đăng thêm cột mới ( tên : use_id | type : like id trong bảng người dùng | Độ dài : như id trong bảng người dùng | Mặc định : NULL | Thuộc tính : unsign | index: INDEX)

2) trên tab Cấu trúc đi đến chế độ xem quan hệ ( Tên ràng buộc : tự động được đặt bởi phpmyAdmin | tên cột : chọn user_id | bảng : users | key : id, ...)

Nó đã được giải quyết đơn giản

javad mosavi iran / urmia

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.