mysql Batasan kunci asing adalah kesalahan pembentukan yang salah

173

Saya punya dua tabel, table1adalah tabel induk dengan kolom IDdan table2dengan kolom IDFromTable1(bukan nama sebenarnya) ketika saya memasukkan FK IDFromTable1ke IDdalam table1saya mendapatkan kesalahan Foreign key constraint is incorrectly formed error. Saya ingin menghapus catatan tabel 2 jika table1catatan dihapus. Terima kasih atas bantuannya

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

Beri tahu saya jika ada informasi lain yang diperlukan. Saya baru di mysql

pengguna516883
sumber
4
Mesin apa yang Anda gunakan untuk meja Anda? Apa jenis table2.IDFromTable1dan table1.ID?
Romain
5
Juga, periksa bahwa set karakter untuk kedua tabel sama.
Carsten
Kedua mesin tabel adalah innoDB. tidak yakin di mana menemukan set karakter, dan keduanya adalah tipe char. ID adalah kunci utama dalam table1
user516883
2
Harap berikan definisi tabel untuk table1 dan table2. Bagaimana Anda mendapatkan kesalahan ini? Apakah Anda menggunakan alat untuk membuat kunci asing? Tampaknya itu bukan kesalahan asli MySQL.
Devart
@ user516883 - Apakah Anda memerlukan bantuan untuk mendapatkan definisi tabel? Di HeidiSQL Anda cukup mengklik tab CREATE code .
Álvaro González

Jawaban:

422

Saya mengalami masalah yang sama dengan HeidiSQL. Kesalahan yang Anda terima sangat samar. Masalah saya akhirnya adalah bahwa kolom kunci asing dan kolom referensi tidak dari jenis atau panjang yang sama.

Kolom kunci asing adalah SMALLINT(5) UNSIGNEDdan kolom referensi adalah INT(10) UNSIGNED. Setelah saya membuat keduanya sama persis, penciptaan kunci asing bekerja dengan sempurna.

Jake Wilson
sumber
58
Atau mungkin kolom yang direferensikan bukan kunci utama
nawfal
9
Agak masalah yang sama bagi saya - tabel referensi belum ada. Aduh.
Amalgovinus
5
Saya sudah benar-benar mengalami apa yang Jake lakukan, tetapi saya telah mengalami masalah FK lain (tipe berbeda) pada HeidiSQL. FK pada varchars harus memiliki susunan yang sama. Semoga itu bisa membantu orang lain di masa depan!
cbloss793
10
Dalam kasus saya itu karena Encoding dan Collation berbeda.
Khatri
1
@nawfal - Saya percaya itu tidak harus menjadi kunci utama, tetapi HARUS memiliki indeks. Kunci primer secara otomatis diindeks.
Itai
48

Saya memiliki masalah yang sama ketika tabel induk dibuat menggunakan MyISAMmesin. Ini kesalahan konyol, yang saya perbaiki:

ALTER TABLE parent_table ENGINE=InnoDB;
Denis Malinovsky
sumber
Terima kasih banyak, saya sudah gila dengan ini. Tahu mengapa basis data tiba-tiba mengganti mesin untuk tabel?
Robert Franklin
28

pastikan kolom identik (dengan tipe yang sama) dan jika kolom referensi tidak primary_key, pastikan kolomnya sama INDEXED.

Santosh
sumber
Bahkan terjadi pada saya bahwa, tidak ada kesalahan, tetapi kunci asing tidak ditambahkan (1 adalah dan 1 sebenarnya tidak), tetapi setelah menambahkan sederhana KEY referencing_column(referencing_column) SEBELUM kedua definisi kunci asing mereka berdua berhasil ditambahkan :)
jave.web
2
Kunci yang tidak diindeks adalah masalah saya.
Neil Masters
1
Saya memiliki masalah ini dan masalahnya adalah saya memiliki kunci primer dua kolom dan Anda tidak dapat menggunakan kolom ke-2 dari kunci primer sebagai kunci asing. Jadi saya hanya menambahkan indeks sendiri untuk kolom ke-2 dari kunci utama dan kemudian berhasil.
Firze
21

Sintaks untuk mendefinisikan kunci asing sangat memaafkan, tetapi bagi siapa pun yang tersandung pada ini, fakta bahwa kunci asing harus "dari jenis yang sama" berlaku bahkan untuk pengumpulan, bukan hanya tipe data dan penandatanganan panjang dan bit.

Bukannya Anda akan mencampur collation dalam model Anda (kan?) Tetapi jika Anda melakukannya, pastikan bidang kunci utama dan asing Anda memiliki tipe collation yang sama dalam phpmyadmin atau Heidi SQL atau apa pun yang Anda gunakan.

Semoga ini menghemat waktu empat jam percobaan dan kesalahan itu membuat saya rugi.

pengguna2297047
sumber
1
Terima kasih! Ternyata host online saya menggunakan mesin ISAM dan untuk pengembang lokal saya menggunakan InnoDB. Ketika saya mencadangkan meja dari host ke lokal ... booming.
Ben
Versi terbaru dari MariaDB tampaknya menggunakan utf8_mb4 sebagai charset default (ketika tidak diset secara eksplisit di konfigurasi server) begitu COLLATE utf8mb4_unicode_cijuga masalah (tak terduga) saya (pada mesin dev).
JonnyJD
13

Saya memiliki masalah yang sama, tetapi menyelesaikannya.

Pastikan kolom 'ID' di 'table1' memiliki indeks UNIK !

Dan tentu saja jenis, panjang kolom 'ID' dan 'IDFromTable1' dalam dua tabel ini harus sama. Tapi Anda sudah tahu tentang ini.

Renat Gatin
sumber
Anda membuat hari saya.
kevenlolo
1
Senang untuk membantu! ;)
Renat Gatin
Tidak yakin akan detailnya, tetapi saya memiliki kunci komposit dengan kesalahan ini yang diperbaiki dengan menambahkan indeks unik individu untuk kolom.
Halvor Holsten Strand
Kolom yang direferensikan harus diindeks, tidak harus unik (walaupun itu adalah kasus yang biasa).
Barmar
10

Hanya untuk penyelesaian.

Kesalahan ini mungkin juga terjadi jika Anda memiliki kunci asing dengan VARCHAR (..) dan charset dari tabel referensi berbeda dari tabel referensi itu.

misalnya VARCHAR (50) dalam Tabel Latin1 berbeda dari VARCHAR (50) dalam Tabel UTF8.

S Doering
sumber
1
Bahkan utf8_unicode_ci dan utf8_general_ci menyebabkan kesalahan
leuchtdiode
10

teks kesalahan mysql tidak banyak membantu, dalam kasus saya, kolom memiliki batasan "tidak nol", jadi "pada penghapusan set nol" tidak diizinkan

Luca C.
sumber
7

jika semuanya ok, tambahkan saja ->unsigned();di akhir foregin key.

jika tidak berhasil, periksa tipe data dari kedua bidang. mereka harus sama.

Josef
sumber
5

Saya memiliki masalah yang sama, kedua kolom INT (11) TIDAK NULL tapi saya tidak bisa membuat kunci asing. Saya harus menonaktifkan pemeriksaan kunci asing untuk menjalankannya dengan sukses:

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

Semoga ini bisa membantu seseorang.

Takman
sumber
4
Sebenarnya itu adalah FOREIGN_KEY_CHECKS
Xmanoux
Ini memang membantu saya untuk melangkah lebih jauh, tetapi masalah saya tidak ada indeks primer di kolom
bumerang
4

Satu lagi kemungkinan penyebab untuk tampilan kesalahan ini. Urutan tempat saya membuat tabel salah. Saya mencoba untuk referensi kunci dari tabel yang belum dibuat.

Kaya Toast
sumber
4

(Resent Terakhir) Bahkan jika nama bidang dan tipe data sama tetapi susunannya tidak sama, itu juga akan mengakibatkan masalah itu.

Sebagai contoh

    NAMA TBL | JENIS DATA | PEMERIKSAAN        

    ActivityID | INT |         latin1_general_ci     ActivityID | INT |         utf8_general_ci

Coba ubah menjadi

    NAMA TBL | JENIS DATA | PEMERIKSAAN        

    ActivityID | INT |         latin1_general_ci     ActivityID | INT |         latin1_general_ci

....

Ini berhasil untuk saya.

Jimwel Anobong
sumber
3

Periksa mesin tabel, kedua tabel harus mesin yang sama, yang sangat membantu saya.

mariobigboy
sumber
Poin bagus! Saya berurusan dengan basis data Zen Cart di MySQL yang semua tabelnya ada di mesin MyISAM secara default. Saya menambahkan tabel menggunakan mesin InnoDB, dan mencoba menambahkan batasan kunci asing dari meja saya ke inti Zen Cart. Gagal dengan kesalahan 'salah pembentukan' yang tidak jelas ini. Anda dapat melihat mesin untuk setiap meja denganSHOW TABLE STATUS LIKE 'table_name';
Neek
2

Saya memiliki masalah yang sama.

Masalahnya adalah kolom referensi bukan kunci utama.

Jadikan itu sebagai kunci utama dan masalah terpecahkan.

longluffy
sumber
Tidak perlu menjadi PK, itu juga bisa UNIK BUKAN NULL.
philipxy
Sebenarnya ... dalam kasus saya hanya mengaturnya ke tipe indeks normal bekerja.
hendr1x
2

Meskipun jawaban lain cukup membantu, hanya ingin berbagi pengalaman saya juga.

Saya menghadapi masalah ketika saya telah menghapus tabel yang idsudah direferensikan sebagai kunci asing di tabel lain ( dengan data ) dan mencoba untuk membuat ulang / mengimpor tabel dengan beberapa kolom tambahan.

Permintaan untuk rekreasi (dibuat dalam phpMyAdmin) tampak seperti berikut:

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`);

Seperti yang Anda perhatikan, PRIMARY KEYindeks ditetapkan setelah pembuatan ( dan penyisipan data ) yang menyebabkan masalah.

Larutan

Solusinya adalah menambahkan PRIMARY KEYindeks pada permintaan definisi tabel untuk idyang dirujuk sebagai kunci asing, sementara juga menghapusnya dari ALTER TABLEbagian di mana indeks sedang ditetapkan:

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;
Ahmad Baktash Hayeri
sumber
Ini bekerja untuk saya. Saya khawatir bahwa saya harus menginstal ulang perangkat lunak saya;)
Dewlance
2

Saya kehilangan berjam-jam untuk itu!

PK di satu meja berada utf8di meja lainnya adalah utf8_unicode_ci!

LukaszTaraszka
sumber
1

Coba jalankan sebagai berikut:

tampilkan buat tabel Induk

// dan periksa apakah tipe kedua tabel sama, seperti myISAM atau innoDB, dll
// Aspek lain yang perlu diperiksa dengan pesan kesalahan ini: kolom yang digunakan sebagai asing 
kunci harus diindeks, mereka harus dari jenis yang sama 
(Jika salah satunya adalah tipe smallint (5) dan yang lain dari type smallint (6), 
itu tidak akan berfungsi), dan, jika bilangan bulat, mereka harus ditandatangani.

// atau periksa untuk rangkaian karakter
tampilkan variabel seperti "character_set_database";
tampilkan variabel seperti "collation_database";

// diedit: coba sesuatu seperti ini
Tabel ALTER TABEL2
TAMBAHKAN CONSTRAINT fk_IdTable2
KUNCI ASING (Table1_Id)
REFERENSI Table1 (Table1_Id)
PADA PEMBARUAN CASCADE 
HAPUS CASCADE;
Sudhir Bastakoti
sumber
9
Coba jalankan SHOW ENGINE INNODB STATUS untuk mendapatkan rincian lebih lanjut tentang kesalahan
Sudhir Bastakoti
@SudhirBastakoti - +1! Itu berhasil untuk saya. Detailnya sangat membantu. Mampu memperbaiki masalah dengan cepat.
Paul Carlton
1

Saya memiliki masalah yang sama dengan Symfony 2.8.

Awalnya saya tidak mengerti, karena tidak ada masalah yang sama dengan panjang kunci asing dll.

Akhirnya saya harus melakukan hal berikut dalam folder proyek. (Server restart tidak membantu!)

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

rogaa
sumber
1

terima kasih S Doerin:

"Hanya untuk penyelesaian. Kesalahan ini mungkin juga terjadi jika Anda memiliki kunci asing dengan VARCHAR (..) dan charset dari tabel yang direferensikan berbeda dari tabel yang mereferensikannya. Mis. VARCHAR (50) dalam Tabel Latin1 adalah berbeda dari VARCHAR (50) di Tabel UTF8. "

saya memecahkan masalah ini, mengubah jenis karakter dari tabel. ciptaan memiliki latin1 dan yang benar adalah utf8.

tambahkan baris berikutnya. SET KARAKTER DEFAULT = utf8;

Bladimir Arias Sabogal
sumber
1

Saya memiliki masalah menggunakan tabel Alter untuk menambahkan kunci asing antara dua tabel dan hal yang membantu saya memastikan setiap kolom yang saya coba tambahkan hubungan kunci asing diindeks. Untuk melakukannya di PHP myAdmin: Buka tabel dan klik pada tab struktur. Klik opsi indeks untuk mengindeks kolom yang diinginkan seperti yang ditunjukkan pada tangkapan layar:

masukkan deskripsi gambar di sini

Setelah saya mengindeks kedua kolom yang saya coba referensi dengan kunci asing saya, saya berhasil menggunakan tabel alter dan membuat hubungan kunci asing. Anda akan melihat bahwa kolom diindeks seperti pada tangkapan layar di bawah ini:

masukkan deskripsi gambar di sini

perhatikan bagaimana zip_code muncul di kedua tabel.

Chris Adams
sumber
1

Anda perlu memeriksa bahwa keduanya sama di semua propertinya, termasuk dalam "Collation"

CrsCaballero
sumber
1

Saya menggunakan HeidiSQL dan untuk mengatasi masalah ini saya harus membuat indeks di tabel yang direferensikan dengan semua kolom yang direferensikan.

menambahkan indeks ke tabel Heidisql

Doug
sumber
Sama bagi saya di mysql: InnoDB membutuhkan indeks pada kunci asing dan kunci referensi sehingga pemeriksaan kunci asing dapat cepat dan tidak memerlukan pemindaian tabel.
hendr1x
1

Saya mengalami masalah yang sama tadi. Dalam kasus saya, yang harus saya lakukan adalah memastikan bahwa tabel yang saya rujuk dalam kunci asing harus dibuat sebelum tabel saat ini (sebelumnya dalam kode). Jadi jika Anda mereferensikan variabel (x * 5) sistem harus tahu apa itu x (x harus dideklarasikan di baris kode sebelumnya). Ini menyelesaikan masalah saya, semoga akan membantu orang lain.

Alexander Nenartovich
sumber
Saya punya masalah yang sama di MariaDB v10.3.18. Kami menggunakan MySQL sebelumnya dan memperingatkan bahwa kunci asing menunjuk ke tabel yang tidak ada.
MarthyM
0

Saya memiliki masalah yang sama dengan Pembuat skema migrasi Laravel 5.1 dengan MariaDB 10.1.

Masalahnya adalah bahwa saya telah mengetik unignedalih-alih unsigned( ssurat itu hilang) saat mengatur kolom.

Setelah memperbaiki kesalahan ketik diperbaiki untuk saya.

Arda
sumber
0

Bahkan saya mengalami masalah yang sama dengan mysql dan liquibase. Jadi inilah masalahnya: Tabel dari mana Anda ingin mereferensikan kolom tabel lain berbeda baik dalam hal tipe data atau dalam hal ukuran tipe data.

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.
kathait ashish
sumber
0

Pastikan Anda telah menentukan nama tabel dalam case yang sesuai (jika nama tabel peka huruf besar-kecil di database Anda). Dalam kasus saya, saya harus berubah

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

untuk

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

perhatikan customerperubahan ke CUSTOMER.

izogfif
sumber
0

Atau Anda dapat menggunakan DBDesigner4 yang memiliki antarmuka grafis untuk membuat database Anda dan menghubungkannya menggunakan FK. Klik kanan pada tabel Anda dan pilih 'Salin Tabel SQL Buat' yang membuat kode.

masukkan deskripsi gambar di sini

Dexter
sumber
0

Itu subjek lama tapi saya menemukan sesuatu. Saat membangun meja kerja MySQL, ia juga mendapatkan hubungan dari tabel lainnya. tinggalkan saja pilar-pilar yang berhubungan dengan Anda. Bersihkan kolom lain yang ditambahkan secara otomatis. Ini bekerja untuk saya.

Muhammed Alper Uslu
sumber
0

Kasus saya adalah saya salah ketik pada kolom yang dirujuk:

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")

Pesan kesalahannya cukup samar dan saya sudah mencoba semuanya - memverifikasi jenis kolom, susunan, mesin, dll.

Butuh beberapa saat untuk mencatat kesalahan ketik dan setelah memperbaiki semuanya bekerja dengan baik:

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
Delian Krustev
sumber
0

Saya menghadapi masalah ini kesalahan datang ketika Anda meletakkan kunci utama di tipe data yang berbeda seperti:

Tabel 1:

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

Meja 2:

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

tipe data untuk id dari tabel kedua harus bertahap

shaher11
sumber
0

Masalahnya sangat sederhana untuk dipecahkan

misalnya: Anda memiliki dua tabel dengan nama pengguna dan posting dan Anda ingin membuat kunci asing di tabel posting dan Anda menggunakan phpMyAdmin

1) di tabel posting tambahkan kolom baru ( nama : use_id | ketik : seperti id di tabel pengguna | Panjang : seperti id di tabel pengguna | Default : NULL | Atribut : unsigned | index: INDEX)

2) pada tab Struktur buka tampilan relasi ( Nama kendala : atur otomatis oleh phpmyAdmin | nama kolom : pilih user_id | tabel : pengguna | kunci : id, ...)

Itu hanya diselesaikan

javad mosavi iran / urmia

Javad mosavi
sumber