mysql Yabancı anahtar kısıtı yanlış biçimlendirilmiş hata


174

İki tablo var, table1bir sütun ile üst tablodur IDve table2bir sütun ile IDFromTable1ben bir FK koymak (değil gerçek ismi) IDFromTable1için IDde table1hatası alıyorum Foreign key constraint is incorrectly formed error. table1Kayıt silinirse tablo 2 kaydını silmek istiyorum . Herhangi bir yardım için teşekkürler

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

Başka bilgi gerekip gerekmediğini bana bildirin. Mysql için yeniyim


4
Masalarınız için hangi motoru kullanıyorsunuz? Ne tür table2.IDFromTable1ve table1.ID?
Romain

5
Ayrıca, her iki tablo için karakter kümelerinin aynı olup olmadığını kontrol edin.
Carsten

Her iki tablo motoru da innoDB'dir. karakter kümelerini nerede bulacağınızdan emin değilsiniz ve her ikisi de char tipindedir. Kimlik
tablo1'deki

2
Lütfen table1 ve table2 için tablo tanımlarını sağlayın. Bu hatayı nasıl aldınız? Yabancı anahtarı oluşturmak için bir araç kullanıyor musunuz? Görünüşe göre bu bir MySQL yerel hatası değil.
Devart

@ user516883 - Tablo tanımlarını almak için yardıma mı ihtiyacınız var? HeidiSQL'de CREATE code sekmesine tıklamanız yeterlidir .
Álvaro González

Yanıtlar:


424

HeidiSQL ile de aynı problemle karşılaştım. Aldığınız hata çok şifreli. Benim sorunum, yabancı anahtar sütun ve referans sütun aynı tür veya uzunlukta değildi oldu.

Yabancı anahtar sütunu oldu SMALLINT(5) UNSIGNEDve başvurulan sütun INT(10) UNSIGNED. Her ikisini de aynı tipte yaptığımda, yabancı anahtar yaratma mükemmel çalıştı.


58
Veya başvurulan sütunun birincil bir anahtar olmaması olabilir
nawfal

9
Benim için benzer bir sorun - referans verilen tablo henüz mevcut değildi. Whoops.
Amalgovinus

5
Jake'in yaptıklarını tamamen deneyimledim, ama HeidiSQL'de başka bir FK sorunuyla (farklı tür) karşılaştım. Varcharlardaki FK aynı harmanlama olmalıdır. Gelecekte başka birine yardımcı olacağını umuyoruz!
cbloss793

10
Benim durumumda farklı Kodlama ve Harmanlama nedeniyle oldu.
Khatri

1
@nawfal - Birincil anahtar olması gerekmediğine inanıyorum, ancak bir dizin olması ZORUNLUDUR. Birincil anahtarlar otomatik olarak dizine eklenir.
Itai

48

Üst tablo MyISAMmotor kullanılarak oluşturulduğunda da aynı sorunu yaşadım . Aşağıdakilerle düzelttiğim aptalca bir hata:

ALTER TABLE parent_table ENGINE=InnoDB;

Çok teşekkür ederim, bununla deliriyordum. Veritabanının neden motoru tablolar için değiştirdiğine dair bir fikriniz var mı?
Robert Franklin

28

sütunların aynı (aynı türden) olduğundan emin olun ve referans sütunu değilse primary_key, olduğundan emin olun INDEXED.


Hatta bana bir hata olmadığı, ancak yabancı anahtar eklenmedi (1 oldu ve 1 aslında değildi), ancak her iki yabancı anahtar tanımından KEY referencing_column(referencing_column) ÖNCE basit bir şekilde eklendikten sonra ikisi de başarıyla eklendi :)
jave.web

2
Dizine eklenmeyen anahtarlar benim sorunumdu.
Neil Masters

1
Bu sorunu yaşadım ve sorun çift sütunlu bir birincil anahtar vardı ve birincil anahtarın 2. sütununu yabancı anahtar olarak kullanamazsınız. Böylece birincil anahtarın 2. sütunu için kendi dizinini ekledim ve işe yaradı.
Firze

21

Yabancı anahtarları tanımlamak için sözdizimi çok bağışlayıcıdır, ancak bunu yapan herkes için yabancı anahtarların "aynı türden" olması gerektiği gerçeği, yalnızca veri türü ve uzunluğu ve bit imzalaması için değil, harmanlama için de geçerlidir.

Harmanlamayı modelinizde karıştıracağınızdan (değil mi?), Ancak yaparsanız, birincil ve yabancı anahtar alanlarınızın phpmyadmin veya Heidi SQL'de veya kullandığınız her türde aynı harmanlama türünde olduğundan emin olun.

Umarım bu size dört saatlik deneme süresi kazandırır ve hata bana mal olur.


1
Teşekkürler! Çevrimiçi sunucum ISAM motorunu kullanıyor ve yerel geliştiriciler için InnoDB kullanıyorum. Ne zaman bir tablo ana bilgisayardan yerel ... patlama yedekledi.
Ben

MariaDB'nin son sürümleri, utf8_mb4'ü varsayılan karakter kümesi olarak kullanıyor gibi görünüyor (sunucu yapılandırmasında açıkça ayarlanmadığında) COLLATE utf8mb4_unicode_ci, (dev makinede) benim (beklenmeyen) sorunum oldu.
JonnyJD

13

Aynı problemim vardı, ama çözdüm.

'Table1' sütunundaki 'ID' sütununun BENZERSİZ dizinine sahip olduğundan emin olun !

Ve elbette bu iki tablodaki 'ID' ve 'IDFromTable1' sütunlarının tipi, uzunluğu aynı olmalıdır. Ama bunu zaten biliyorsun.


Günümü gün ettin.
kevenlolo

1
Yardımcı olduğuma sevindim! ;)
Renat Gatin

Ayrıntılardan emin değilim, ancak sütunlar için tek tek benzersiz dizinler ekleyerek düzeltilen bu hatayla kompozit bir anahtarım vardı.
Halvor Holsten Strand

Başvurulan sütun dizine eklenmelidir, benzersiz olması gerekmez (her zamanki durum bu olsa da).
Barmar

10

Sadece tamamlamak için.

Bu hata, VARCHAR (..) ile yabancı bir anahtarınız varsa ve başvurulan tablonun karakter seti referans veren tablodan farklıysa da bu durum söz konusu olabilir.

örneğin, Latin1 Tablosundaki VARCHAR (50), UTF8 Tablosundaki VARCHAR (50) 'den farklıdır.



10

mysql hata metinleri o kadar yardımcı olmuyor, benim durumumda, sütun "boş değil" kısıtlaması vardı, bu nedenle "silme kümesinde boş" izin verilmedi


7

her şey yolundaysa, ->unsigned();sonuna ekleyin foregin key.

Eğer çalışmazsa, her iki alanın da veri tipini kontrol edin. aynı olmalılar.


5

Ben de aynı sorunu vardı, her iki sütun INT (11) NULL DEĞİLDİ ama yabancı anahtar oluşturmak mümkün değil. Başarıyla çalıştırmak için yabancı anahtar denetimlerini devre dışı bırakmak zorunda kaldım:

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

Umarım bu birine yardımcı olur.


4
Aslında FOREIGN_KEY_CHECKS
Xmanoux

Bu bana daha fazla geçmeme yardımcı oldu, ama benim sorunum sütunda primmary endeksi eksikti
bumerang

4

Bu hatanın görüntülenmesi için bir olası neden daha. Hangi tablolar oluşturma sırası yanlıştı. Henüz oluşturulmamış bir tablodan bir anahtara başvurmaya çalışıyordum.


4

(Son Yeniden Gönderme) Alan adı ve veri türü aynı, ancak harmanlama aynı olmasa bile, bu soruna da neden olacaktır.

Örneğin

    TBL ADI | VERİ TÜRÜ | COLLATION        

    Etkinlik Kimliği | INT |         latin1_general_ci     ActivityID | INT |         utf8_general_ci

Olarak değiştirmeyi deneyin

    TBL ADI | VERİ TÜRÜ | COLLATION        

    Etkinlik Kimliği | INT |         latin1_general_ci     ActivityID | INT |         latin1_general_ci

....

Bu benim için çalıştı.


3

Masa motorunu kontrol edin, her iki masa da aynı motor olmalı, bu da bana çok yardımcı oldu.


İyi bir nokta! Tabloları varsayılan olarak MyISAM motorunda olan MySQL'de bir Zen Cart veritabanı ile uğraşıyorum. InnoDB motorunu kullanarak bir tablo ekledim ve masamdan çekirdek Zen Cart'a bir yabancı anahtar kısıtlaması eklemeye çalıştım. Bu belirsiz 'yanlış biçimlendirilmiş' hatayla başarısız oldu. Her bir tablo için motoru SHOW TABLE STATUS LIKE 'table_name';
şurada

2

Aynı sorunları yaşadım.

Sorun, referans sütununun birincil anahtar olmamasıdır.

Birincil anahtar yapın ve sorun çözüldü.


PK olması gerekmez, aynı zamanda benzersiz de olabilir NULL DEĞİL.
philipxy

Aslında ... benim durumumda normal bir dizin türüne ayarlamak normal çalıştı.
hendr1x

2

Diğer cevaplar oldukça yararlı olsa da, sadece deneyimimi paylaşmak istedim.

idZaten diğer tablolarda ( veri ile ) yabancı anahtar olarak başvurulmakta olan bir tablo sildi ve yeniden oluşturmak / bazı ek sütunlarla tablo almak çalıştı sorunla karşı karşıya .

(PhpMyAdmin'de oluşturulan) rekreasyon sorgusu aşağıdaki gibi görünüyordu:

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

Fark edebileceğiniz gibi, PRIMARY KEYdizin oluşturulduktan ( ve verilerin eklenmesinden sonra) soruna neden olan ) .

Çözüm

Çözüm, bunun için yabancı anahtar olarak başvurulan PRIMARY KEYtablo tanımı sorgusuna dizin eklemek ve idayrıca ALTER TABLEdizinlerin ayarlandığı kısımdan kaldırmaktı :

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;

Benim için çalıştı. Yazılımımı yeniden
yüklemem

2

Bunun için saatlerce kaybettim!

PK bir tabloda utf8diğer oldu utf8_unicode_ci!


1

Aşağıdakileri çalıştırmayı deneyin:

show create table Üst öğe

// ve her iki tablonun türünün myISAM veya innoDB gibi aynı olup olmadığını kontrol edin.
// Bu hata mesajıyla kontrol edilecek diğer hususlar: yabancı olarak kullanılan sütunlar 
anahtarlar dizine eklenmeli, aynı türde olmalıdır 
(yani biri smallint (5) ve diğeri smallint (6) tipindeyse, 
işe yaramaz) ve tamsayılarsa imzasız olmalıdırlar.

// veya karakter kümelerini kontrol et
"character_set_database" gibi değişkenleri göster;
"collation_database" gibi değişkenleri göster;

// düzenlendi: böyle bir şey deneyin
ALTER TABLE tablo2
CONSTRAINT EKLE fk_IdTable2
YABANCI ANAHTAR (Tablo1_Id)
REFERANSLAR Tablo1 (Tablo1_Id)
GÜNCELLEME KASKASINDA 
SİLİNDİR SİLİNDİRİNDE;

9
Hata hakkında daha fazla ayrıntı almak için SHOW ENGINE INNODB STATUS'u çalıştırmayı deneyin
Sudhir Bastakoti

@SudhirBastakoti - +1! Bunu benim için yaptı. Ayrıntılar yardımcı olur. Sorunu hızlı bir şekilde çözmeyi başardı.
Paul Carlton

1

Aynı sorunu Symfony 2.8 ile de yaşadım.

İlk başta anlayamadım, çünkü yabancı anahtarların int uzunluğunda benzer bir sorun yoktu.

Sonunda proje klasöründe aşağıdakileri yapmak zorunda kaldım. (Bir sunucunun yeniden başlatılması yardımcı olmadı!)

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


1

teşekkürler S Doerin:

"Tamamlanması için. VARCHAR (..) ile yabancı bir anahtarınız varsa ve başvurulan tablonun karakter kümesi referans veren tablodan farklıysa, bu hata da olabilir. Örneğin, Latin1 Tablosundaki VARCHAR (50) UTF8 Tablosundaki VARCHAR'dan (50) farklı. "

tablonun karakter türünü değiştirerek, bu sorunu çözdü. yaratılış latin1 ve doğru utf8.

sonraki satırı ekleyin. VARSAYILAN KARAKTER SETİ = utf8;


1

İki tablo arasında bir yabancı anahtar eklemek için Alter tablo kullanarak sorunları vardı ve bana yardımcı olan şey, ben bir yabancı anahtar ilişkisi eklemek çalışıyorum her sütun dizine emin olmak oldu. Bunu PHP myAdmin'de yapmak için: Tabloya gidin ve yapı sekmesine tıklayın. Ekran görüntüsünde gösterildiği gibi istenen sütunu dizine eklemek için dizin seçeneğini tıklayın:

resim açıklamasını buraya girin

Her iki sütunu da indeksledikten sonra yabancı anahtarlarımla başvurmaya çalışıyordum, değiştirme tablosunu başarılı bir şekilde kullanabildim ve yabancı anahtar ilişkisini oluşturabildim. Sütunların aşağıdaki ekran görüntüsünde olduğu gibi dizine eklendiğini göreceksiniz:

resim açıklamasını buraya girin

zip_code'un her iki tabloda nasıl göründüğüne dikkat edin.


1

"Harmanlama" da dahil olmak üzere her ikisinin de tüm özelliklerinde aynı olup olmadığını kontrol etmeniz gerekir.


1

HeidiSQL kullanıyordum ve bu sorunu çözmek için başvurulan tabloda tüm sütunların başvuruda bulunduğu bir dizin oluşturmak zorunda kaldım .

tabloya dizin ekleme Heidisql


MySQL'de benim için aynı: InnoDB, yabancı anahtarlar ve başvurulan anahtarlar üzerinde dizinler gerektirir, böylece yabancı anahtar denetimleri hızlı olabilir ve tablo taraması gerektirmez.
hendr1x

1

Ben de şimdi aynı konuya girdim. Benim durumumda, tek yapmam gereken yabancı anahtarda referans verdiğim tablonun geçerli tablonun (kodun başlarında) öncesinde oluşturulmasını sağlamaktır. Dolayısıyla, bir değişkene (x * 5) başvuruyorsanız, sistem x'in ne olduğunu bilmelidir (x önceki kod satırlarında bildirilmelidir). Bu sorunumu çözdü, umarım başka birine yardım eder.


Aynı sorunu MariaDB v10.3.18'de de yaşadım. Daha önce MySQL kullandık ve yabancı bir anahtarın var olmayan bir tabloya işaret ettiği konusunda uyardı.
MarthyM

0

MariaDB 10.1 ile Laravel 5.1 geçiş Schema Builder ile de aynı sorunu yaşadım.

Sorunum yazmışsınız olmasıydı unignedyerine unsigned(s sütun ayarlarken harf eksik) yazmıştı.

Düzelttikten sonra yazım hatası düzeltildi.


0

Hatta mysql ve liquibase ile aynı konuya rastladım. Yani sorun budur: Başka bir tablonun sütununa başvurmak istediğiniz tablo, veri tipi durumunda veya veri tipinin boyutu açısından farklıdır.

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

Uygun durumda tablonun adını belirttiğinizden emin olun (tablo adları veritabanınızda büyük / küçük harfe duyarlıysa). Benim durumumda değiştirmek zorunda kaldım

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

için

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

olarak customerdeğiştirildiğine dikkat edin CUSTOMER.


0

Veya veritabanınızı oluşturmak ve bunları FK kullanarak bağlamak için grafiksel bir arayüze sahip DBDesigner4'ü kullanabilirsiniz. Tablonuza sağ tıklayın ve kodu oluşturan 'Tablo SQL Oluşturma Kopyala'yı seçin.

resim açıklamasını buraya girin


0

Bu eski bir konu ama bir şey keşfettim. Bir MySQL çalışma tezgahı oluştururken, diğer tablonun ilişkilerini de alır. sadece ilgili sütunları bırakın. Otomatik olarak eklenen diğer sütunları temizleyin. Bu benim için çalışıyor.


0

Benim durumum, belirtilen sütunda bir yazım hatası vardı:

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

Hata mesajı oldukça şifreli ve her şeyi denedim - sütun türlerini, harmanlamaları, motorları vb.

Yazım hatası not etmek biraz zaman aldı ve düzelttikten sonra hepsi iyi çalış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

Birincil anahtarı aşağıdaki gibi farklı veri türüne koyduğunuzda hata geldi bu sorunla karşı karşıya:

tablo 1:

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

Tablo 2:

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

ikinci tablonun kimliği için veri türü artımlı olmalıdır


0

Sorunu çözmek çok basit

Örneğin: Eğer isimleri ile iki tablo var kullanıcılar ve mesajların ve oluşturmak istediğiniz yabancı anahtar içinde mesajlar masa ve kullandığınız phpMyAdmin'i

1) 'de sonrası masaya eklemek yeni sütun ( isim | use_id: türü : gibi id içinde kullanıcı tablosu | Uzunluk : gibi id içinde kullanıcı tablosu | Varsayılan : NULL | Nitelikler : işaretsiz | index: INDEX)

2) Yapı sekmesinde ilişki görünümüne gidin ( Kısıtlama adı : phpmyAdmin | sütun adı tarafından otomatik olarak ayarlanır : select user_id | table : users | key : id, ...)

Basitçe çözüldü

javad mosavi iran / urmia

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.