Saya mencoba membuat tabel di MySQL dengan dua kunci asing, yang mereferensikan kunci utama di 2 tabel lainnya, tetapi saya mendapatkan kesalahan errno: 150 dan itu tidak akan membuat tabel.
Berikut adalah SQL untuk ketiga tabel tersebut:
CREATE TABLE role_groups (
`role_group_id` int(11) NOT NULL `AUTO_INCREMENT`,
`name` varchar(20),
`description` varchar(200),
PRIMARY KEY (`role_group_id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `roles` (
`role_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50),
`description` varchar(200),
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB;
create table role_map (
`role_map_id` int not null `auto_increment`,
`role_id` int not null,
`role_group_id` int not null,
primary key(`role_map_id`),
foreign key(`role_id`) references roles(`role_id`),
foreign key(`role_group_id`) references role_groups(`role_group_id`)
) engine=InnoDB;
Bantuan apa pun akan sangat dihargai.
mysql
foreign-keys
mysql-error-150
Bill Karwin
sumber
sumber
auto_increment
? Itu tidak valid. Auto_increment adalah kata kunci, bukan pengenal.Jawaban:
Saya memiliki masalah yang sama dengan
ALTER TABLE ADD FOREIGN KEY
.Setelah satu jam, saya menemukan bahwa kondisi ini harus dipenuhi agar tidak mendapatkan kesalahan 150:
Tabel Induk harus ada sebelum Anda menentukan kunci asing sebagai referensi. Anda harus menentukan tabel dalam urutan yang benar: Tabel induk terlebih dahulu, lalu tabel Anak. Jika kedua tabel mereferensikan satu sama lain, Anda harus membuat satu tabel tanpa batasan FK, lalu membuat tabel kedua, lalu menambahkan batasan FK ke tabel pertama dengan
ALTER TABLE
.Kedua tabel tersebut harus mendukung batasan kunci asing, yaitu
ENGINE=InnoDB
. Mesin penyimpanan lain diam-diam mengabaikan definisi kunci asing, sehingga tidak ada kesalahan atau peringatan, tetapi batasan FK tidak disimpan.Kolom yang direferensikan di tabel Induk harus merupakan kolom paling kiri dari sebuah kunci. Paling baik jika kunci di Induk adalah
PRIMARY KEY
atauUNIQUE KEY
.Definisi FK harus mengacu pada kolom PK dalam urutan yang sama dengan definisi PK. Misalnya, jika FK
REFERENCES Parent(a,b,c)
maka PK Induk tidak boleh ditentukan pada kolom secara berurutan(a,c,b)
.Kolom PK di tabel Induk harus memiliki tipe data yang sama dengan kolom FK di tabel Anak. Misalnya, jika kolom PK di tabel Induk
UNSIGNED
, pastikan untuk menentukanUNSIGNED
untuk kolom terkait di bidang tabel Anak.Pengecualian: panjang string mungkin berbeda. Misalnya
VARCHAR(10)
bisa referensiVARCHAR(20)
atau sebaliknya.Kolom FK tipe string apa pun harus memiliki kumpulan karakter dan pemeriksaan yang sama dengan kolom PK yang sesuai.
Jika sudah ada data di tabel Anak, setiap nilai di kolom FK harus sesuai dengan nilai di kolom PK tabel Induk. Periksa ini dengan pertanyaan seperti:
Ini harus mengembalikan nol (0) nilai yang tidak cocok. Jelas, kueri ini adalah contoh umum; Anda harus mengganti nama tabel dan nama kolom Anda.
Baik tabel Parent maupun tabel Child dapat berupa
TEMPORARY
tabel.Baik tabel Parent maupun tabel Child dapat berupa
PARTITIONED
tabel.Jika Anda mendeklarasikan FK dengan
ON DELETE SET NULL
opsi, maka kolom FK harus nihil.Jika Anda mendeklarasikan nama batasan untuk kunci asing, nama batasan harus unik di seluruh skema, tidak hanya dalam tabel tempat batasan ditentukan. Dua tabel mungkin tidak memiliki batasannya sendiri dengan nama yang sama.
Jika ada FK lain di tabel lain yang menunjuk ke bidang yang sama tempat Anda mencoba membuat FK baru, dan format tersebut salah (mis. Susunan berbeda), mereka harus dibuat konsisten terlebih dahulu. Ini mungkin hasil dari perubahan masa lalu di mana
SET FOREIGN_KEY_CHECKS = 0;
yang digunakan dengan hubungan yang tidak konsisten yang didefinisikan secara tidak sengaja. Lihat jawaban @ andrewdotn di bawah untuk instruksi bagaimana mengidentifikasi masalah FK ini.Semoga ini membantu.
sumber
int(11) unsigned NOT NULL
vsint(11) NOT NULL
.ON DELETE
aturan CONSTRAINT Anda adalahSET NULL
pastikan kunci asing benar-benar NULL! Saya menghabiskan 30 menit membaca jawaban ini berulang-ulang, memastikan tabel saya memenuhi syarat tetapi masih mendapatkan Error 150. Kemudian saya perhatikan bahwa FK saya adalah bidang NOT NULL yang berarti aturan tersebut tidak mungkin diterapkan.Pesan "errno 150" generik MySQL berarti bahwa batasan kunci asing tidak terbentuk dengan benar ." Seperti yang mungkin sudah Anda ketahui jika Anda membaca halaman ini, pesan kesalahan "errno: 150" generik benar-benar tidak membantu. Namun:
Anda bisa mendapatkan pesan kesalahan sebenarnya dengan menjalankan
SHOW ENGINE INNODB STATUS;
dan kemudian mencariLATEST FOREIGN KEY ERROR
di keluaran.Misalnya, upaya untuk membuat batasan kunci asing ini:
gagal dengan kesalahan
Can't create table 'test.t2' (errno: 150)
. Itu tidak memberi tahu siapa pun yang berguna selain itu masalah kunci asing. Tapi lariSHOW ENGINE INNODB STATUS;
dan itu akan berkata:Ia mengatakan bahwa masalahnya adalah tidak dapat menemukan indeks.
SHOW INDEX FROM t1
menunjukkan bahwa tidak ada indeks sama sekali untuk tabelt1
. Perbaiki dengan, katakanlah, mendefinisikan kunci utama padat1
, dan batasan kunci asing akan berhasil dibuat.sumber
SHOW ENGINE INNODB STATUS
membantu saya segera mengidentifikasi masalah yang telah saya coba diagnosis selama hampir satu jam. Terima kasih.SET FOREIGN_KEY_CHECKS = 0;
selama impor / perubahan yang salah format pada satu waktu atau lainnya. Bantuan besar, terima kasih.Pastikan properti dari dua kolom yang Anda coba tautkan dengan batasan sama persis.
Seringkali, properti 'unsigned' di kolom ID akan menarik perhatian Anda.
sumber
Apa status database Anda saat ini ketika Anda menjalankan skrip ini? Apakah itu benar-benar kosong? SQL Anda berjalan dengan baik untuk saya saat membuat database dari awal, tetapi errno 150 biasanya berkaitan dengan menjatuhkan & membuat ulang tabel yang merupakan bagian dari kunci asing. Saya merasa Anda tidak bekerja dengan database yang 100% segar dan baru.
Jika Anda error saat "source" -ing file SQL Anda, Anda harus dapat menjalankan perintah "SHOW ENGINE INNODB STATUS" dari prompt MySQL segera setelah perintah "source" untuk melihat info kesalahan yang lebih rinci.
Anda mungkin ingin melihat entri manual juga:
sumber
Untuk orang yang melihat utas ini dengan masalah yang sama:
Ada banyak alasan untuk mendapatkan error seperti ini. Untuk daftar penyebab dan solusi kesalahan kunci asing yang cukup lengkap di MySQL (termasuk yang dibahas di sini), lihat tautan ini:
Kesalahan MySQL Foreign Key dan Errno 150
sumber
Untuk orang lain yang menemukan entri SO ini melalui Google: Pastikan Anda tidak mencoba melakukan tindakan SET NULL pada kolom kunci asing (menjadi) yang didefinisikan sebagai "NOT NULL." Itu menyebabkan frustrasi besar sampai saya ingat untuk melakukan PERIKSA STATUS INNODB MESIN.
sumber
Jelas bukan itu masalahnya tetapi saya menemukan kesalahan ini cukup umum dan tidak jelas. Target dari sebuah
FOREIGN KEY
tidak mungkinPRIMARY KEY
. Jawaban yang bermanfaat bagi saya adalah:KUNCI ASING selalu harus diarahkan ke bidang benar PRIMARY KEY dari tabel lain.
sumber
Seperti yang ditunjukkan oleh @andrewdotn, cara terbaik adalah melihat kesalahan mendetail (
SHOW ENGINE INNODB STATUS;
), bukan hanya kode kesalahan.Salah satu alasannya bisa jadi indeks sudah ada dengan nama yang sama, mungkin ada di tabel lain. Sebagai praktik, saya merekomendasikan memberi awalan nama tabel sebelum nama indeks untuk menghindari benturan seperti itu. misalnya alih-alih
idx_userId
digunakanidx_userActionMapping_userId
.sumber
Harap pastikan pada awalnya
Saya mengalami masalah yang sama dan saya telah memperbaikinya. Saya memiliki INT unsigned untuk satu bidang dan hanya integer untuk bidang lainnya.
sumber
Tip bermanfaat, gunakan
SHOW WARNINGS;
setelah mencobaCREATE
kueri Anda dan Anda akan menerima kesalahan serta peringatan yang lebih rinci:Jadi dalam hal ini, saatnya membuat ulang tabel saya!
sumber
Ini biasanya terjadi ketika Anda mencoba untuk memasukkan file ke database yang sudah ada. Jatuhkan semua tabel terlebih dahulu (atau DB itu sendiri). Dan kemudian file sumber dengan
SET foreign_key_checks = 0;
di awal danSET foreign_key_checks = 1;
di akhir.sumber
Saya telah menemukan alasan lain ini gagal ... nama tabel case sensitive.
Untuk definisi tabel ini
Definisi tabel ini berfungsi
sedangkan yang ini gagal
Fakta bahwa itu bekerja di Windows dan gagal di Unix membutuhkan beberapa jam untuk saya mengetahuinya. Harapan yang membantu orang lain.
sumber
MySQL Workbench 6.3 untuk Mac OS.
Masalah: errno 150 pada tabel X ketika mencoba melakukan Teknik Maju pada diagram DB, 20 dari 21 berhasil, 1 gagal. Jika FK di tabel X dihapus, kesalahan dipindahkan ke tabel lain yang sebelumnya tidak gagal.
Mengubah semua mesin tabel ke myISAM dan berfungsi dengan baik.
sumber
Juga perlu diperiksa bahwa Anda tidak beroperasi pada database yang salah. Kesalahan ini akan terjadi jika tabel asing tidak ada. Mengapa MySQL harus begitu samar?
sumber
Pastikan bahwa kunci asing tidak terdaftar sebagai unik di induk. Saya memiliki masalah yang sama dan saya menyelesaikannya dengan membatasi sebagai tidak unik.
sumber
Dalam kasus saya, itu karena fakta bahwa field yang merupakan field kunci asing memiliki nama yang terlalu panjang, yaitu.
foreign key (some_other_table_with_long_name_id)
. Coba lebih pendek. Pesan kesalahan agak menyesatkan dalam kasus itu.Selain itu, seperti yang disebutkan @Jon sebelumnya - definisi kolom harus sama (hati-hati dengan
unsigned
subtipe).sumber
(Catatan sampingan terlalu besar untuk sebuah Komentar)
Tidak perlu
AUTO_INCREMENT
id dalam tabel pemetaan; singkirkan itu.Ubah
PRIMARY KEY
menjadi(role_id, role_group_id)
(dalam urutan apa pun). Ini akan membuat akses lebih cepat.Karena Anda mungkin ingin memetakan kedua arah, tambahkan juga
INDEX
dengan kedua kolom tersebut dalam urutan yang berlawanan. (Tidak perlu membuatnyaUNIQUE
.)Kiat lainnya: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta
sumber
Ketika batasan kunci asing didasarkan pada
varchar
jenis, maka di samping daftar yang disediakan olehmarv-el
para kolom target harus memiliki kendala unik.sumber
jalankan baris di bawah ini sebelum membuat tabel: SET FOREIGN_KEY_CHECKS = 0;
Opsi FOREIGN_KEY_CHECKS menentukan apakah akan memeriksa batasan kunci asing untuk tabel InnoDB atau tidak.
- Tentukan untuk memeriksa batasan kunci asing (ini adalah default)
- Jangan periksa kendala kunci asing
SETEL FOREIGN_KEY_CHECKS = 0;
Kapan Menggunakan: Menonaktifkan sementara batasan referensial (setel FOREIGN_KEY_CHECKS ke 0) berguna saat Anda perlu membuat ulang tabel dan memuat data dalam urutan induk-anak
sumber
Saya mengalami masalah yang sama, tetapi saya memeriksa bahwa saya tidak memiliki tabel induk. Jadi saya hanya mengedit migrasi orang tua di depan migrasi anak. Lakukan saja.
sumber