Hata 1022 - Yazamıyorum; tabloda yinelenen anahtar


218

Tablo oluşturma komutunda yinelenen anahtarlarla ilgili 1022 hatası alıyorum. Sorguya baktıktan sonra, çoğaltmanın nerede gerçekleştiğini anlayamıyorum. Başka kimse görebilir mi?

SQL query:

-- -----------------------------------------------------
-- Table `apptwo`.`usercircle`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS  `apptwo`.`usercircle` (

 `idUserCircle` MEDIUMINT NOT NULL ,
 `userId` MEDIUMINT NULL ,
 `circleId` MEDIUMINT NULL ,
 `authUser` BINARY NULL ,
 `authOwner` BINARY NULL ,
 `startDate` DATETIME NULL ,
 `endDate` DATETIME NULL ,
PRIMARY KEY (  `idUserCircle` ) ,
INDEX  `iduser_idx` (  `userId` ASC ) ,
INDEX  `idcategory_idx` (  `circleId` ASC ) ,
CONSTRAINT  `iduser` FOREIGN KEY (  `userId` ) REFERENCES  `apptwo`.`user` (
`idUser`
) ON DELETE NO ACTION ON UPDATE NO ACTION ,
CONSTRAINT  `idcategory` FOREIGN KEY (  `circleId` ) REFERENCES  `apptwo`.`circle` (
`idCircle`
) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = INNODB;

MySQL said: Documentation

#1022 - Can't write; duplicate key in table 'usercircle' 

4
Eğer doğru hatırlıyorsam, birincil anahtar her zaman bir BENZERSİZ INDEX, bu yüzden benzersiz dizin deyimi bırakmak gerekir?
Bay47

1
ON DELETE NO ACTIONsadece yabancı anahtarın tüm kullanımını bırakacaktı. Bunu yapmak için çok spesifik nedenleriniz olmadıkça.
AmazingDreams

4
@AmazingDreams Neden? Halen referans bütünlüğünü zorunlu kılmaktadır. Sadece çocukları kendiniz silmelisiniz. Bu, yanlış bir anahtar kelimeyi silerek yanlışlıkla birçok veriyi silebileceğiniz basamaklı bir silme işleminden daha güvenlidir.
GolezTrol

1
stackoverflow.com/a/5810024/1567737 'Aliased' kullanırken neden takma ad kullanmanız amacı hemen netleştirir?
AmazingDreams

@AmazingDreams Bahşiş için teşekkürler. Etrafındaki tartışmayı da seviyorum - artıları ve eksileri öğrenmeme yardımcı oluyor.
Git mümkün

Yanıtlar:


534

Büyük olasılıkla, adınızla iduserveya idcategoryveritabanınızda zaten bir kısıtınız vardır . Sadece öyleyse kısıtlamaları yeniden adlandırın.

Kısıtlamalar, yalnızca oluşturduğunuz / değiştirdiğiniz tablo için değil, tüm veritabanı için benzersiz olmalıdır.

Şu anda kullanımda olan kısıtlamaları öğrenmek için aşağıdaki sorguyu kullanabilirsiniz:

SELECT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`KEY_COLUMN_USAGE`
WHERE `CONSTRAINT_NAME` IN ('iduser', 'idcategory');

15
Aynen dediğin gibi. CREATE sorgusunun geri kalanında aynı idcategory iduser adlarıyla birçok kısıtlama otomatik olarak oluşturuldu - yardımınız için teşekkürler!
Git mümkün

1
Ben MySQL Workbench oluşturma komut dosyası verirken bu düzeltmek olacağını düşündüm, ama ben projeyi açtığınızda bu tür bir şey hakkında uyarı "Yoksaymak" için ne olsun.
SnowInferno

Teşekkür ederim dostum :) Bu bana çok yardımcı oluyor ve şimdi yabancı anahtarlar için benim konvansiyonum farklı ve bu sorunu tekrar karşılayamıyorum :)

Bunu teyit edebilir. Ancak başvurulan tablo zaten bırakılmış olmasına rağmen adlandırılmış kısıtlama varsa ne yapabilirim? Varolmayan bir tablodan bir kısıtlama bırakabilir miyim? Sanırım MySQL 5.6'dan güncel MariaDB'ye güncellemeliyim.
Anse

4
Bunun için teşekkür ederim: Kısıtlamalar tüm veritabanı için benzersiz olmalıdır
sebasira

31

MySQL'de Yabancı anahtar adını değiştirin. Veritabanı tablolarında aynı yabancı anahtar adlarına sahip olamazsınız.

Tüm tablolarınızı ve tüm yabancı anahtarlarınızı kontrol edin ve aynı ada sahip iki yabancı anahtar bulundurmaktan kaçının.


Benim durumumda sorun buydu. Bunu asla tahmin edemezdim ve sen benim günümü kurtardın. Şimdi fk_id_1, fk_id_2 vb. Teşekkürler.
JackLeEmmerdeur

15

Başarıyla Çözülen iki bağlantıdan ve Adlandırma Sözleşmesinden , karşılaştığım aynı sorunu kolayca çözdüm. yani, yabancı anahtar adı için fk _colName_ TableName olarak verin . Bu adlandırma kuralı belirsiz değildir ve DB Modelinizdeki her ForeignKey'i benzersiz kılar ve bu hatayı asla alamazsınız.

Hata 1022: Yazamıyorum; tabloda yinelenen anahtar


6

Diğerlerinin de belirttiği gibi, kısıtlamanızın adının DB'nizdeki başka bir tablo tarafından zaten kullanılıyor olması mümkündür . Veritabanında benzersiz olmalıdırlar.

Yabancı anahtar kısıtlamalarını adlandırmak için iyi bir kural:

fk_TableName_ColumnName

Olası bir çakışma olup olmadığını araştırmak için, veritabanınız tarafından kullanılan tüm kısıtlamaları bu sorgu ile listeleyebilirsiniz:

SELECT * FROM information_schema.table_constraints WHERE constraint_schema = 'YOUR_DB';

Bu sorguyu çalıştırdığımda, daha önce bir tablonun geçici bir kopyasını yaptığımı keşfettim ve bu kopya zaten kullanmaya çalıştığım kısıtlama adını kullanıyordu.


4

Sadece son 4 saatini aynı konuyla geçirdim. Yaptığım sadece kısıtlamaların benzersiz isimlere sahip olmasını sağlamaktı.

Kısıtlamaları yeniden adlandırabilirsiniz. Benimkine bir sayı ekledim, böylece olay sayısını kolayca izleyebildim.

Misal

Tablodaki bir kısıtlamaya yabancı anahtar X ile bir çocuk adı verilirse Yabancı anahtar X ile bir sonraki kısıtlama boy1 olarak adlandırılabilir

Eminim benden daha iyi isimler bulursun. 🙂


3

Bu, Percona Toolkit'in çevrimiçi şema değiştirme aracının belirli sürümlerindeki bir hata ile bağlantılı olarak da ortaya çıkabilir. Büyük bir tabloyu değiştirmek için, pt-osc önce yinelenen bir tablo oluşturur ve tüm kayıtları tabloya kopyalar. Bazı durumlarda, bazı pt-osc 2.2.x sürümleri yeni tablodaki kısıtlamalara eski tablodaki sınırlamalarla aynı adları vermeye çalışacaktır.

2.3.0'da bir düzeltme yayınlandı.

Daha fazla bilgi için https://bugs.launchpad.net/percona-toolkit/+bug/1498128 adresine bakın.


1

Ayrıca bu problemle de karşılaştım. Mysql'de veritabanı adının mevcut olup olmadığını kontrol edin ve eskisini yeniden adlandırın.


1

Yeni bir tablo oluştururken bu sorunu yaşadım. Verdiğim Yabancı Anahtar adı zaten kullanılıyor. Anahtarı yeniden adlandırmak sorunu düzeltti.

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.