MySQL: Tidak dapat membuat tabel (errno: 150)

156

Saya mencoba mengimpor file .sql dan gagal membuat tabel.

Inilah permintaan yang gagal:

CREATE TABLE `data` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`),
CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;    

Saya mengekspor .sql dari database yang sama, saya menjatuhkan semua tabel dan sekarang saya mencoba mengimpornya, mengapa gagal?

MySQL: Tidak dapat membuat tabel './dbname/data.frm' (errno: 150)

gtilx
sumber
1
Untuk dasarnya semua penyebab kesalahan ini, berikut ini adalah sumber yang lengkap untuk apa yang menyebabkan errno 150 (dan errno 121 / kesalahan kunci asing lainnya) di MySQL.
John Smith
21
Saya telah menemukan bahwa kolom harus identik (bahkan bendera yang belum ditandatangani harus cocok).
Justin Skiles
3
@ JohnSmith ... dimana?
Charles Wood
3
Saya sarankan membaca posting blog ini yang berisi daftar 10 kemungkinan penyebab: verysimple.com/2006/10/22/…
Mark Amery
@CharlesWood: " John Smith ... dilihat 6 April 13 jam 19:29 ", itu sekitar tiga bulan sebelum komentar Anda. Saya memiliki ketakutan, bahwa misteri "di mana" tidak akan terungkap sampai akhir dunia yang suram ini! :>
trejder

Jawaban:

167

Dari MySQL - Dokumentasi Kendala KUNCI ASING :

Jika Anda membuat kembali tabel yang dijatuhkan, itu harus memiliki definisi yang sesuai dengan batasan kunci asing yang merujuknya. Itu harus memiliki nama dan tipe kolom yang benar, dan harus memiliki indeks pada kunci yang direferensikan, seperti yang dinyatakan sebelumnya. Jika ini tidak puas, MySQL mengembalikan Kesalahan 1005 dan merujuk ke Kesalahan 150 dalam pesan kesalahan, yang berarti bahwa batasan kunci asing tidak dibentuk dengan benar. Demikian pula, jika ALTER TABLE gagal karena Kesalahan 150, ini berarti bahwa definisi kunci asing akan salah dibentuk untuk tabel yang diubah.

OMG Ponies
sumber
1
Bisakah dua kolom dari satu tabel merujuk satu kolom dari tabel lain, di mana itu PK?
Eugene
1
@Eugene: Masing-masing dari dua kolom dapat memiliki hubungan kunci asing ke PK di tabel lain - tidak kedua kolom sebagai hubungan kunci asing tunggal.
OMG Ponies
1
@OMGPonies: Terima kasih telah menjawab pertanyaan ini! .. Saya mencarinya ... Saya juga mengajukan pertanyaan di sini stackoverflow.com/questions/13487010/… .... Meskipun saya memiliki beberapa jawaban yang baik tetapi saya ingin menyesuaikan Whether its possible to write Nested Query for my problem? ..Aku akan meminta kamu untuk tolong jawab aku juga!
Grijesh Chauhan
19
Kesalahan saya adalah tabel master memiliki mesin MyISAM dan tabel anak InnoDB. Skrip create.sql saat ini menggunakan InnoDB untuk semua tabel, tetapi saya memiliki instalasi yang sangat lama di mana skrip pertama menggunakan MyISAM.
Siapa
2
@Whome - Yap, mengalami masalah yang sama di sini.
Agustus
96

Kesalahan 150 berarti Anda memiliki masalah dengan kunci asing Anda. Mungkin kunci di meja asing bukan jenis yang sama persis?

Dan McGrath
sumber
15
Terima kasih :) untuk saya, tipe datanya adalah INT tetapi yang satu tidak ditandatangani sementara yang lain tidak
Anh Nguyen
6
Saya sering berlari melintasi BIGINTvs INTketika menggunakan generator skema.
Xeoncross
Saya mengalami masalah yang sama ketika kunci asing bukan nilai INT. Kolom harus UNIK ketika kunci asing merujuknya.
PhatHV
62

Anda bisa mendapatkan pesan kesalahan yang sebenarnya dengan menjalankan SHOW ENGINE INNODB STATUS;dan kemudian mencari LATEST FOREIGN KEY ERRORdi output.

Sumber: jawaban dari pengguna lain dalam pertanyaan serupa

Denilson Sa Maia
sumber
7
Ini sebenarnya sangat berguna. Ini memberi tahu Anda kesalahan yang sebenarnya.
Csongor Fagyal
Terima kasih. Sayang sekali MySQL Workbench tidak menggunakan ini.
scipilot
Luar biasa. Ini sangat membantu. Memberitahu Anda kesalahan yang sebenarnya. Milik saya, telah membuat Kolom NULLABLE tetapi telah menetapkan "pada delete set null". Terima kasih banyak.
Abhishek Saini
Jika Anda memiliki hak istimewa di server Anda :(
Christopher Smit
30

Jenis data harus sama persis. Jika Anda berurusan dengan tipe varchar, tabel harus menggunakan susunan yang sama.

Esben Skov Pedersen
sumber
4
Terima kasih atas sedikit pemeriksaan.
Arahant
25

Saya pikir semua jawaban ini sementara yang benar menyesatkan pertanyaan itu.

Jawaban sebenarnya adalah ini sebelum Anda memulai pemulihan, jika Anda mengembalikan file dump dengan kunci asing:

SET FOREIGN_KEY_CHECKS=0;

karena secara alami pemulihan akan menciptakan beberapa kendala sebelum tabel asing bahkan ada.

colin
sumber
Melakukan ini tidak berhasil untuk saya, masih memberikan kesalahan. Ada ide?
Joseph Astrahan
24

Dalam beberapa kasus, Anda mungkin menemukan pesan kesalahan ini jika ada mesin yang berbeda antara tabel terkait. Misalnya, sebuah tabel mungkin menggunakan InnoDB sementara yang lain menggunakan MyISAM. Keduanya harus sama

pi.
sumber
Terima kasih - ini masalah saya.
scipilot
Itu masalah saya. Terima kasih
thed0ctor
Ini bisa terjadi jika Anda membuat file sql dari tabel innodb menggunakan mysqldump dan mereka diekspor sebagai myisam talbes sebagai gantinya.
Amado Martinez
11

Kesalahan no. 150 berarti kegagalan batasan kunci asing. Anda mungkin membuat tabel ini sebelum tabel bergantung pada kunci asing (tabel keywords). Buat tabel itu terlebih dahulu dan itu akan berfungsi dengan baik.

Jika tidak, hapus pernyataan kunci asing dan tambahkan setelah tabel dibuat - Anda akan mendapatkan pesan kesalahan yang lebih bermakna tentang kegagalan kendala spesifik.

Eran Galperin
sumber
10

Ada beberapa hal yang dapat menyebabkan errno 150, jadi bagi orang yang mencari topik ini, inilah yang menurut saya dekat dengan daftar lengkap (sumber Penyebab Errno 150 ):

Untuk errno 150 atau errno 121, cukup mengetik SHOW ENGINE INNODB STATUS, ada bagian yang disebut "KESALAHAN ASING TERBESAR KUNCI". Di bawah itu akan memberi Anda pesan kesalahan yang sangat membantu, yang biasanya akan memberi tahu Anda langsung apa masalahnya. Anda memerlukan hak SUPER untuk menjalankannya, jadi jika Anda tidak memilikinya, Anda hanya perlu menguji skenario berikut.

1) Jenis Data Tidak Cocok: Jenis kolom harus sama

2) Kolom Induk Tidak Diindeks (Atau Diindeks dengan Urutan Salah)

3) Kolom Kolom Tidak Cocok

4) Menggunakan SET NULL pada kolom NOT NULL

5) Table Collations Don't Match: bahkan jika collations kolom cocok, pada beberapa versi MySQL ini bisa menjadi masalah.

6) Kolom Induk Tidak Sebenarnya Ada di Tabel Induk. Periksa ejaan (dan mungkin spasi di awal atau akhir kolom)

7) Salah satu indeks pada salah satu kolom tidak lengkap, atau kolom terlalu panjang untuk indeks lengkap. Perhatikan bahwa MySQL (kecuali jika Anda mengubahnya) memiliki panjang kunci kolom tunggal maksimum 767 byte (ini sesuai dengan kolom UTF varchar (255))

Jika Anda mendapatkan errno 121, berikut adalah beberapa penyebab:

1) Nama kendala yang Anda pilih sudah diambil

2) Pada beberapa sistem jika ada perbedaan kasus dalam pernyataan dan nama tabel Anda. Ini dapat menggigit Anda jika Anda berpindah dari satu server ke server lain yang memiliki aturan penanganan kasus yang berbeda.

juacala
sumber
Dalam beberapa versi Anda mendapatkan errno 150 jika tabel tidak innodb, tetapi dalam beberapa versi hanya gagal diam-diam.
juacala
Terima kasih, ini hebat: | ------------------------ | KESALAHAN KUNCI ASING TERBARU | ------------------------ | Anda telah menetapkan kondisi SET NULL melalui beberapa | | kolom didefinisikan sebagai NOT NULL.
Sam Critchley
8

Kadang-kadang MySQL hanya super bodoh - saya bisa mengerti alasan penyebab kunci asing .. tetapi dalam kasus saya, saya baru saja menghapus seluruh database, dan saya masih mendapatkan kesalahan ... mengapa? maksud saya, tidak ada database lagi ... dan pengguna sql yang saya gunakan tidak memiliki akses ke db lain di server ... maksud saya, server "kosong" untuk pengguna saat ini dan saya masih mendapatkan kesalahan ini? Maaf, tapi saya kira MySQL berbohong kepada saya ... tetapi saya bisa mengatasinya :) Cukup tambahkan dua baris SQL ini di sekitar pernyataan Anda:

SET FOREIGN_KEY_CHECKS = 0;
# some code that gives you errno: 150
SET FOREIGN_KEY_CHECKS = 1;

Sekarang sql harus dieksekusi ... Jika Anda benar-benar memiliki masalah kunci asing, itu akan muncul kepada Anda dengan garis di mana Anda akan mengaktifkan pemeriksaan lagi - ini akan gagal maka .. tetapi server saya hanya sepi :)

jebbie
sumber
Ini dapat menyebabkan masalah jika sebenarnya ada perbedaan antara kolom dan kolom yang direferensikan. Misalnya. Katakanlah kolom yang direferensikan adalah varchar (200) dan pengarahnya adalah varchar (50), maka ketika kaskade diusahakan perilaku aneh mungkin terjadi. Saya belum mengalami masalah di mana errno 150 dikeluarkan karena ketidakcocokan data.
juacala
Wawasan menarik @juacala :) Lucu bagi saya hanya, setiap kali saya mengalami ini, pendekatan saya selalu memperbaikinya ... sampai hari ini setidaknya: D Tapi kami tidak pernah berhenti belajar, kan;)
jebbie
Ini sebenarnya membantu saya dengan skrip liquibase yang dihasilkan. Script berjalan dengan sempurna di MySQL> 5.5, tetapi gagal untuk versi 5.1.
delbertooo
4

Setelah menjelajahi jawaban di atas, dan bereksperimen sedikit, ini adalah cara yang efektif untuk menyelesaikan kesalahan kunci asing di MySQL (1005 - kesalahan 150).

Agar kunci asing dibuat dengan benar, semua yang diminta MySQL adalah:

  • Semua kunci yang direferensikan HARUS memiliki indeks PRIMARY atau UNIK.
  • Kolom Referensi lagi HARUS memiliki tipe data yang identik dengan kolom Referensi.

Memenuhi persyaratan ini dan semuanya akan baik-baik saja.

Davies Malesi
sumber
4

Saya mengalami kesalahan ini ketika telah mem-port aplikasi Windows ke Linux. Di Windows, nama tabel database tidak case-sensitive, dan di Linux mereka case-sensitive, mungkin karena perbedaan sistem file. Jadi, di atas meja Windows Table1adalah sama dengan table1, dan dalam REFERENCESkedua table1dan Table1karya. Di Linux, ketika aplikasi digunakan table1alih-alih Table1ketika itu membuat struktur database saya melihat kesalahan # 150; ketika saya membuat case case yang benar dalam Table1referensi, itu mulai bekerja di Linux juga. Jadi, jika tidak ada yang membantu, pastikan REFERENCESAnda menggunakan huruf besar yang benar dalam nama tabel saat Anda menggunakan Linux.

Vitalii
sumber
Ini juga kasus saya! Memindahkan script dari case-insensitive (OS X) ke versi mysql case-sensitive (Debian).
mircealungu
3

Ubah mesin tabel Anda, hanya innoDB yang mendukung kunci asing

Lappies
sumber
3

Jika tabel PK dibuat dalam satu CHARSET dan kemudian Anda membuat tabel FK di CHARSET lain .. maka Anda juga mungkin mendapatkan kesalahan ini ... Saya juga mendapatkan kesalahan ini tetapi setelah mengubah charset ke PK charset kemudian dieksekusi tanpa kesalahan

create table users
(
------------
-------------
)DEFAULT CHARSET=latin1;


create table Emp
(
---------
---------
---------
FOREIGN KEY (userid) REFERENCES users(id) on update cascade on delete cascade)ENGINE=InnoDB, DEFAULT CHARSET=latin1;
tinku
sumber
3

Kesalahan ini dapat terjadi jika dua tabel memiliki referensi, misalnya, satu tabel adalah Siswa dan tabel lainnya adalah Pendidikan, dan kami ingin tabel Pendidikan memiliki referensi kunci asing dari tabel Siswa. Dalam hal ini tipe data kolom untuk kedua tabel harus sama, jika tidak maka akan menghasilkan kesalahan.

manzarul haque
sumber
3

Dalam sebagian besar kasus masalahnya adalah karena perbedaan ENGINE. Jika orang tua dibuat oleh InnoDB maka tabel yang direferensikan seharusnya dibuat oleh MyISAM & sebaliknya

Sunil Kumar Mohanty
sumber
3

Dalam kasus saya. Saya mempunyai masalah dengan engine dan charset karena pengaturan perubahan server Hosting saya dan tabel baru saya adalah MyISAM tetapi tabel lama saya adalah InnoDB. Baru saja saya berubah.

Ignacio Hernández
sumber
Ini tepat untuk saya, karena saya mengubah database yang tidak saya buat.
FonzTech
3

biasanya, ketidakcocokan antara kunci asing & kunci utama menyebabkan kesalahan: 150.

The kunci asing harus memiliki sama datatype sebagai kunci utama . Juga, jika kunci utama tidak ditandatangani maka kunci asing juga harus tidak ditandatangani .

Rakesh
sumber
3

Saya memiliki masalah yang sama. Itu terkait dengan Kolom kolom Collation dan Character Set . Pastikan Character Set dan Collation harus sama untuk kedua kolom pada dua tabel. Jika Anda ingin mengatur kunci asing itu. Contoh- Jika Anda meletakkan kunci asing pada kolom userID dari tabel userImage yang mereferensikan kolom userID dari tabel users. Kemudian Collation harus sama yaitu utf8_general_ci dan Character set utf8 untuk kedua kolom tabel. Umumnya ketika Anda membuat tabel mysql mengambil dua konfigurasi ini dari pengaturan server.

Sushilkumar
sumber
Kenapa aku tidak melihat puisi ini sebelumnya !? Saya menghabiskan satu jam mencari tahu akar penyebabnya. Itu charset dalam kasus saya. Tabel referensi dan referensi harus memiliki charset yang sama.
Sujit Joshi
2

Pastikan kolom kunci utama dan kolom referensi Anda memiliki tipe data dan atribut yang sama (unsigned, binary, unsigned zerofill, dll.).

Basit
sumber
2

Kasing tepi nyata adalah di mana Anda telah menggunakan alat MySQL, (Sekuel Pro dalam kasus saya) untuk mengubah nama database. Kemudian dibuat database dengan nama yang sama.

Ini menjaga batasan kunci asing ke nama database yang sama, sehingga database yang diubah namanya (misalnya my_db_renamed) memiliki batasan kunci asing di database yang baru dibuat (my_db)

Tidak yakin apakah ini bug di Sequel Pro, atau jika ada kasus penggunaan yang memerlukan perilaku ini, tetapi saya harus menghabiskan sebagian besar waktu pagi ini: /

chim
sumber
2

Saya memiliki kesalahan yang sama. Dalam kasus saya alasan untuk kesalahan adalah bahwa saya memiliki pernyataan ON DELETE SET NULL dalam kendala sementara bidang di mana saya meletakkan kendala dalam definisi memiliki pernyataan TIDAK NULL. Membiarkan NULL di lapangan menyelesaikan masalah.

Wilbert van Diemen
sumber
2

Saya menghadapi masalah seperti ini saat membuat DB dari textfile.

mysql -uroot -padmin < E:\important\sampdb\createdb.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\insert_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\insert_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\load_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\load_absence.sql 

Saya baru saja menulis baris di atas Create.bat dan menjalankan file bat.

Kesalahan saya adalah urutan eksekusi dalam file sql saya. Saya mencoba membuat tabel dengan kunci utama dan juga kunci asing. Ketika sedang berjalan itu akan mencari tabel referensi tetapi tabel tidak ada. Jadi itu akan mengembalikan kesalahan semacam itu.

Jika Anda membuat tabel dengan kunci asing maka periksa tabel referensi ada atau tidak. Dan juga periksa nama tabel referensi dan bidang.

Dharani Dharan
sumber
Dengan kata lain, Anda mencoba membuat tabel dengan kunci asing yang menunjuk ke tabel lain yang belum ada. Buat tabel dalam urutan yang benar untuk menyelesaikan masalah.
Vincent
2

Saya memiliki masalah yang sama tetapi masalah saya adalah karena saya menambahkan bidang baru ke tabel yang sudah ada yang memiliki data, dan bidang baru merujuk bidang lain dari tabel induk dan juga memiliki Defination NOT NULL dan tanpa NILAI DEFAULT. - Saya menemukan alasan mengapa hal-hal tidak berfungsi adalah karena

  1. Bidang baru saya perlu untuk mengisi ulang bidang kosong dengan nilai dari tabel induk pada setiap catatan, sebelum kendala dapat diterapkan. Setiap kali kendala diterapkan itu perlu untuk menjaga Integritas data tabel utuh. Menerapkan Kendala (Kunci Asing) namun ada beberapa catatan database yang tidak memiliki nilai dari tabel induk akan berarti data rusak sehingga MySQL TIDAK AKAN PERNAH MENERAPKAN KONSTRA ANDA

Penting untuk diingat bahwa dalam keadaan normal jika Anda merencanakan basis data jauh sebelumnya, dan menerapkan kendala sebelum penyisipan data, skenario khusus ini akan dihindari

Pendekatan yang lebih mudah untuk menghindari gotcha ini adalah dengan

  • Simpan data tabel basis data Anda
  • Memotong data tabel (dan artefak tabel yaitu indeks dll)
  • Terapkan Kendalanya
  • Impor Data Anda

Saya harap ini membantu seseorang

chitwarnold
sumber
1

Mungkin ini akan membantu? Definisi kolom kunci utama harus persis sama dengan kolom kunci asing.

Mukus
sumber
1

Pastikan semua tabel dapat mendukung kunci asing - mesin InnoDB

joksy82
sumber
1

Kolom tabel PARENT yang Anda maksud dari tabel anak harus unik. Jika tidak, menyebabkan kesalahan no 150.

Dila Ram Gurung
sumber
Anda mungkin perlu menambahkan sedikit lebih detail - misalnya kolom dan nama tabel tertentu
Jonathan
1

Saya memiliki masalah yang sama ketika membuang database mysql Django dengan satu tabel. Saya dapat memperbaiki masalah dengan membuang database ke file teks, memindahkan tabel yang dimaksud ke akhir file menggunakan emacs dan mengimpor file dump sql yang dimodifikasi ke dalam instance baru.

HTH Uwe

alat pengisap debu
sumber
1

Saya telah memperbaiki masalah dengan membuat variabel menerima null

ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL
Fahmi
sumber
1

Saya mendapat masalah yang sama ketika menjalankan serangkaian perintah MySQL. Milik saya muncul saat membuat tabel ketika merujuk kunci asing ke tabel lain yang belum dibuat. Ini urutan keberadaan tabel sebelum referensi.

Solusinya: Buat tabel induk terlebih dahulu sebelum membuat tabel anak yang memiliki kunci asing.

rONIT
sumber
1

Buat tabel tanpa kunci asing, lalu atur kunci asing secara terpisah.

macet
sumber