MySQL yabancı anahtar sütunlarını otomatik olarak endeksliyor mu?


Yanıtlar:


229

Evet, ama sadece . Innodb şu anda yabancı anahtarların uygulandığı tek gönderilen tablo biçimidir.


1
MySQL'in başka herhangi bir tablo türü için dizine eklenmemiş sütunlarda yabancı anahtarlara izin vereceğine inanmak için herhangi bir nedeniniz var mı?
Robert Gamble

Buna gerçekten cevap veremedim. MySQL 6.0'da piyasaya sürülecek Maria ve Falcon depolama motorlarını aramak ve dizine eklenmemiş sütunlarda yabancı anahtarları destekleyip desteklemediklerini görmek isteyebilirsiniz.
Grant Limberg

Görünüşe göre bu doğru değil. Ben büyük bir tablo (1 milyon kayıt) ve sayısı (*) nerede fkey =? 15 saniye sürecekti. Fkey sütununa bir dizin eklendi ve işler artık bir saniyenin altına iniyor.
AbiusX

Başka bir tablo ve 10 milyon kayıtla aynı deney. Bu ofc MySQL 5.1 InnoDB'dir. Tablonun üç alanı vardır, biri birincil anahtar tamsayı, diğeri zaten dizine eklenmiş. Üçüncüsü, başka bir tablonun birincil anahtarının yabancı anahtarıdır. Açık bir dizin eklemeden aramalar burada birkaç saniye sürdü. Tablodaki dizini göster, üzerinde bir dizin göstermedi.
AbiusX

@AbiusX 5.1 muhtemelen çok eski, aşağıdaki MrAlexander'ın cevabına bakın.
e2-e4

131

Görünüşe göre robert'in gönderdiği bağlantıda belirtildiği gibi otomatik olarak bir dizin oluşturulur .

InnoDB, yabancı anahtar denetimlerinin hızlı olması ve tablo taraması gerektirmemesi için yabancı anahtarlarda ve başvurulan anahtarlarda dizinler gerektirir. Referans tablosunda, yabancı anahtar sütunlarının aynı sırada ilk sütun olarak listelendiği bir dizin olmalıdır. Böyle bir indeks, mevcut değilse referans tablosunda otomatik olarak oluşturulur. (Bu, dizinlerin açıkça oluşturulması gereken veya yabancı anahtar kısıtlamalarının oluşturulmasının başarısız olacağı bazı eski sürümlerin tersidir.) Verilmişse, dizin_adı daha önce açıklandığı gibi kullanılır.

InnoDB ve FOREIGN KEY Kısıtlamaları


9
Dokümanlar'dan kanıt sağlayan
seçenekten

6
Alıntılanan metin artık MySQL belgelerine dahil edilmiş gibi görünmüyor, bu hala doğru olup olmadığını netleştirmiyor.
Courtney Miles

7
@ user2045006 alıntı metin için doc 5.0 ve doc 5.6'ya
başvurabilirsiniz

1
Mevcut dokümanlarda, metinde sadece küçük bir değişiklik var (anlamın benzer olduğunu varsayıyorum):InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order.
Lucas Basquerotto


11

En azından dokümanlara göre bir ALTER TABLE (CREATE TABLE yerine) yaparsanız dizini otomatik olarak almazsınız (bağlantı 5.1 içindir, ancak 5.5 için aynıdır):

[...] ALTER TABLE kullanarak bir tabloya yabancı anahtar kısıtlaması eklediğinizde, önce gerekli dizinleri oluşturmayı unutmayın.


2
Ayrıca MySQL 5.6 üzerinde çalıştım ve MariaDB 10 ve ALTER TABLE bir endeks oluşturdu. Mysqlindexcheck'in bu dizinin bir "fazlalık dizin" olduğunu bildirmesi ilginçtir. Bırakmaya çalıştım ama şu hatayı aldım: "HATA 1553 (HY000): 'index_name' dizini bırakılamıyor: yabancı anahtar kısıtlamasında gerekli". Bu nedenle, bu dizini bırakmak ve yabancı anahtarı saklamak mümkün değildir.
Ciprian Stoica

Cevabınızı gözden geçirmek isteyebilirsiniz. MySQL , zaten yoksa yabancı anahtar kontrollerini hızlandırmak için her zaman bir dizin oluşturur . Dokümanlar size yabancı anahtar kısıtlamalarından önce dizin oluşturmanın işleri biraz hızlandırabileceğini söylemeye çalışıyor. Örneğin, yabancı anahtar denetimleri için dizin işlevi görebilen bir bileşik anahtar dizini, gereksiz bir dizin otomatik olarak oluşturmak yerine InnoDB tarafından kullanılabilir.
BMiner

7

5.7 Dokümanlardan teklif almak isteyenler için :

MySQL, yabancı anahtarlar ve başvurulan anahtarlar için dizinler gerektirir, böylece yabancı anahtar denetimleri hızlı olabilir ve tablo taraması gerektirmez. Referans tablosunda, yabancı anahtar sütunlarının aynı sırada ilk sütun olarak listelendiği bir dizin olmalıdır. Böyle bir indeks, mevcut değilse referans tablosunda otomatik olarak oluşturulur. Yabancı anahtar kısıtlamasını uygulamak için kullanılabilecek başka bir dizin oluşturursanız, bu dizin daha sonra sessizce bırakılabilir. Dizin_adı, belirtilmişse, daha önce açıklandığı gibi kullanılır.


4

Belirtildiği gibi InnoDB için yapar. İlk başta diğerlerinin (özellikle MS SQL ve DB2) yapmamasının garip olduğunu düşündüm. TableSpace taramaları, çok az sayıda tablo satırı olduğunda dizin taramalarından daha iyidir - bu nedenle, vakaların büyük çoğunluğu için yabancı bir anahtarın dizine alınması istenir. O zaman bu beni vurdu - bu mutlaka tek başına (bir sütun) endeksi olması gerektiği anlamına gelmez - burada MySQL'in otomatik FK Endeksi'nde. Yani, MS SQL, DB2 (Oracle emin değilim) vb DBA kadar bırakmak nedeni bu olabilir; büyük tablolardaki tüm birden çok dizin, performans ve alanla ilgili sorunlara neden olabilir.


Bileşik anahtar dizinleri hakkında iyi bir noktaya değinmiş olursunuz; ancak, yeni oluşturulan bir bileşik anahtar dizini, yabancı anahtar denetimlerini hızlı yapma zorunluluğunu yerine getirirse, MySQL otomatik olarak / sessizce otomatik olarak oluşturulan tek bir anahtar dizini bırakır. Dürüst olmak gerekirse, MS SQL, DB2 ve diğerlerinin neden bunu yapmadığı hakkında hiçbir fikrim yok. Çok az mazeretleri var. Yabancı anahtarlarda otomatik oluşturulan bir dizinin zararlı olacağı bir kullanım durumu düşünemiyorum.
BMiner

2

Evet, Innodbsağlayın. FOREIGN KEYMaddeden sonra bir yabancı anahtar adı koyabilir veya MySQL'in sizin için bir ad oluşturmasına izin vermek için bırakabilirsiniz. MySQL otomatik olarak foreign_key_nameadıyla bir dizin oluşturur .

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action

0

Evet, Mysql dizin yabancı anahtar otomatik olarak başka bir yabancı anahtar olan bir tablo oluşturduğunuzda.


-2

İndeks anahtarının otomatik olarak kullanılması mümkün değildir

ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)

Örneğin fotoğraflar ve örneğin YABANCI ANAHTAR oluşturduğunuz tablonun adı photograph_id. Kod şöyle olmalıdır

ALTER TABLE photographs ADD INDEX (photograph_id);
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.