Yabancı anahtar otomatik olarak bir dizin oluşturur mu?


389

Ben iki tablo yabancı anahtar, bu SQL Server alt tablodaki bir dizine benzer bir şey yaratacak söylendi. Bunun doğru olduğuna inanmakta zorlanıyorum, ancak özellikle bununla ilgili çok fazla şey bulamıyorum.

Bunu sormamın gerçek sebebi, muhtemelen 15 ilişkili tabloya sahip bir tabloya karşı silme ifadesinde çok yavaş yanıt süresi yaşamamızdır. Bizim veritabanı adam sordum ve o alanlarda yabancı bir anahtar varsa, o zaman bir dizin gibi davranıyor diyor. Bu konudaki deneyiminiz nedir? Tüm yabancı anahtar alanlarına indeks eklemeli miyim yoksa bunlar gereksiz bir ek yük mü?


Ben DB adam aynı anlayış var - FKs aslında bir dizin oluşturmak.
Vinnie

9
Hayır - Bir FK gelmez DEĞİL otomatik bir dizin oluşturun. Bu bir tane oluşturmak için mantıklı - ama edilmektedir DEĞİL , SQL Server tarafından otomatik olarak yapılır.
marc_s

47
bunu sormak aptal değil!
marc_s

5
Yavaş siler alıyorsanız ve diğer tablolar tarafından başvurulan tabloyu silerseniz, muhtemelen diğer tablolardaki yabancı anahtarları dizine ekleyerek performans artışı elde edersiniz . Çünkü SQL bir satırı silerken, satırdaki referans bütünlüğünü kontrol etmesi gerekir. Bunu yapmak için, sildiğiniz satıra referansta bulunan başka bir satır bulunmadığını kontrol etmek gerekir.
Noel Kennedy

3
Bunun bilmeyen bir veritabanı adamının ciddi eğitime ihtiyacı olduğunu söyleyebilirim. Veritabanı çalışanları performanstan sorumludur, bu tür şeyleri bilmek onların görevidir. Bu büyük bir yetersizlik olduğunu göstermektedir.
HLGEM

Yanıtlar:


343

Yabancı anahtar bir kısıtlamadır, iki tablo arasındaki ilişkidir - kendi başına bir dizinle ilgisi yoktur.

Ancak, herhangi bir yabancı anahtar ilişkisinin parçası olan tüm sütunları dizine eklemenin çok mantıklı olduğu bilinen bir gerçektir, çünkü bir FK ilişkisi aracılığıyla, genellikle ilgili bir tabloya bakmanız ve belirli satırları tek bir değer veya bir değer aralığı.

Bu nedenle, bir FK'de yer alan herhangi bir sütunu dizine eklemek iyi olur, ancak FK kendi başına bir dizin değildir.

Kimberly Tripp'in "SQL Server Yabancı Anahtar sütunlarına dizin eklemeyi ne zaman bıraktı?" .


Evet. PostgreSQL'in bir indeks oluşturduğuna inanıyorum. Eminim ki MySQL bunu yapar. Endeks yapmak bir anlam ifade eder, ancak GEREKLİ DEĞİLDİR. Sonuçta, DB her aramaya gittiğinde neden bir tablo taraması gerekiyorsa, neden bir şeye başvuruyorsunuz?
MBCook

Yukarıda belirtilen bu makale biraz karışıktır çünkü SQL sunucusu veya başka bir veritabanı FK'ye hiçbir zaman bir dizin koymaz.
vsingh

7
@vsingh: makale çalışır iletmek tam olarak ne olduğunu - bir yaygındır yanlış kanı bir FK otomatik bir dizin oluşturur - bu mu değil bunu.
marc_s

5
@MBCook Resim PostgreSQL etmez olmayan (9.2 veya daha önceki bir sürümünde az) ile otomatik olarak tanımlanan bir dış anahtar ilişkisi referans tarafındaki bir dizin oluşturmak REFERENCES. UNIQUEBir PRIMARY KEYveya UNIQUEkısıtlama için otomatik olarak bir dizin oluşturur ve yabancı anahtar ilişkisinin başvurulan sonu UNIQUEiçin bir dizin bulunmasını gerektirir , ancak başvuru yapmak için otomatik olarak hiçbir şey yapmaz, ancak genellikle kendiniz yapmak iyi bir fikirdir. Bkz. Stackoverflow.com/questions/970562/…
Craig Ringer

16
Bu karışıklık olabilir, çünkü yabancı anahtar eklediğinizde MySQL InnoDB hem gerektirir ve otomatik olarak bir dizin oluşturur - dev.mysql.com/doc/refman/5.5/en/…
humbads 18:12

42

Vay, cevaplar haritanın her yerinde. Yani Belgeler diyor ki:

FOREIGN KEY kısıtlaması bir dizin için adaydır çünkü:

  • PRIMARY KEY kısıtlamalarındaki değişiklikler, ilgili tablolardaki FOREIGN KEY kısıtlamaları ile kontrol edilir.

  • İlişkili tablolardaki veriler, bir tablonun FOREIGN KEY kısıtlamasındaki sütun (lar) diğer tablodaki birincil veya benzersiz anahtar sütun (lar) ile eşleştirilerek birleştirildiğinde, birleşim ölçütlerinde genellikle yabancı anahtar sütunları kullanılır. Bir dizin, Microsoft® SQL Server ™ 2000'in yabancı anahtar tablosundaki ilgili verileri hızlı bir şekilde bulmasını sağlar. Ancak, bu dizinin oluşturulması bir zorunluluk değildir. Tablolar arasında PRIMARY KEY veya FOREIGN KEY kısıtlaması tanımlanmamış olsa bile, ilişkili iki tablodaki veriler birleştirilebilir, ancak iki tablo arasındaki yabancı anahtar ilişkisi, iki tablonun anahtarları kullanan bir sorguda birleştirilmek üzere optimize edildiğini gösterir. kriterleri.

Bu yüzden (dokümantasyon biraz karışık olmasına rağmen) aslında bir dizin oluşturmadığı oldukça açık görünüyor.


5
Tam olarak - bir dizin için bir ADAY - ancak otomatik olarak bir dizin olarak oluşturulmaz! Oldukça açık aslında, IMHO :-)
marc_s

4
Bu kısmı karışık buldum: "iki tablo arasındaki bir yabancı anahtar ilişkisi, iki tablo anahtarları ölçüt olarak kullanan bir sorguda birleştirilmek üzere optimize edildiğini gösterir." Bu "... iki tablo optimize edilmelidir ..."
Yishai

18

Hayır, yabancı anahtar alanlarında örtük bir dizin yoktur, aksi halde Microsoft neden "Yabancı anahtarda dizin oluşturmak genellikle yararlıdır" derdi . Birincil anahtarlar - Arkadaşınız sevk-Tablodaki birincil anahtarla atıfta tablodaki yabancı anahtar alanını kafa karıştırıcı olabilir mi örtük bir dizin oluşturun.


"Örtük bir dizin" nedir? sadece oluşturmadan ab * ağacı olduğunu ima ediyor mu?
Stephanie Sayfa

1
@Stephanie Page: Bu cevap için yeni oluşturduğum, otomatik olarak oluşturulan bir dizin anlamına gelen bir ifade. Birincil anahtar bildirirseniz, SQL sunucusu otomatik olarak anahtar oluşturur ve dizine ekler. Ancak, yabancı bir anahtar bildirmezseniz (diğer bazı DB sistemleri yapar).
Michael Borgwardt

7

SQL Server, Birincil Anahtarlar için dizin oluşturur, ancak Yabancı Anahtarlar için değil. Yabancı Anahtarlar için dizin oluşturun. Muhtemelen ek yüke değer.


6

Siparişler adında büyük bir tablonuz ve müşteriler adında küçük bir tablonuz olduğunu varsayalım. Bir siparişten müşteriye yabancı bir anahtar var. Şimdi bir müşteriyi silerseniz, Sql Server'ın artık yetim siparişi olup olmadığını kontrol etmesi gerekir; varsa, bir hata oluşturur.

Herhangi bir sipariş olup olmadığını kontrol etmek için, Sql Server büyük siparişler tablosunda arama yapmak zorundadır. Şimdi bir dizin varsa, arama hızlı olacaktır; yoksa arama yavaş olur.

Bu durumda, yavaş silme, bir dizin olmamasıyla açıklanabilir. Özellikle Sql Server bir dizin olmadan 15 büyük tablo aramak zorunda kalacaktı.

PS Yabancı anahtar AÇIK SİLİNDİR SİLME varsa, Sql Server hala sipariş tablosunu aramak zorundadır, ancak daha sonra silinmiş müşteriye başvuruda bulunan tüm siparişleri kaldırmak zorundadır.


Tam olarak - bir FK'deki bir endeksin çok mantıklı olmasının nedeni budur (çoğu zaman)
marc_s

1
Çoğu zaman? Bir ebeveynin silinmesi için durum böyle görünüyor. Çoğu zaman ebeveynlerden sildiğinizde, sanırım bu doğrudur.
Stephanie Sayfa

6

Yabancı anahtarlar dizin oluşturmaz. Yalnızca alternatif anahtar kısıtlamaları (UNIQUE) ve birincil anahtar kısıtlamaları dizin oluşturur. Bu Oracle ve SQL Server için geçerlidir.


3

Bildiğim kadarıyla değil. Yabancı anahtar yalnızca alt anahtardaki değerin üst sütunda bir yerde temsil edileceğine dair bir kısıtlama ekler. Veritabanına alt anahtarın da dizine eklenmesi gerektiğini söylemez, yalnızca kısıtlanır.


3

Açıkçası, yabancı anahtarların dizinlerle kesinlikle bir ilgisi yoktur, evet. Ancak, üstümdeki konuşmacıların da işaret ettiği gibi, FK aramalarını hızlandırmak için bir tane oluşturmak mantıklı. Aslında, MySQL'de, FK bildiriminizde bir dizin belirtmezseniz, motor (InnoDB) bunu sizin için otomatik olarak oluşturur.


3

PostgeSql'de \ d tablename tuşuna basarsanız dizinleri kendiniz kontrol edebilirsiniz

Btree dizinlerinin birincil anahtar ve benzersiz kısıtlamaları olan sütunlarda otomatik olarak oluşturulduğunu, ancak yabancı anahtarların bulunduğu sütunlarda oluşturulmadığını göreceksiniz.

Bunun en azından postgres için sorunuzu cevapladığını düşünüyorum.


Üzgünüz, sorunun MS SQL Server ile ilgili olduğunu fark etmedim ama cevabı gönderdikten sonra. Muhtemelen birisine hala yardımcı olabilir ...
Gregor

2

MSSQL'e işaret eden Entity Framework 6.1'in yabancı anahtarlara otomatik olarak dizinler eklediğini fark ettim.


Sütunu bir dizinin bir parçası olarak el ile işaretlerseniz (ör. Birkaç üye üzerinde bir bileşik dizin oluşturuyorsanız) inanmıyorum
Rowland Shaw

0

InnoDB'nin gerektirir endeksler üzerinde yabancı anahtarları böylece ve başvurulan tuşları yabancı anahtar kontroller hızlı olmalı ve bir tablo taraması gerektiren olamaz. Referans tablosunda, bir olmalı endeksi yabancı anahtar sütunları aynı sırada ilk sütun olarak listelenmektedir.

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.