Oracle'da yabancı anahtarlarda dizin oluşturmam gerekir mi?


121

Bir masam Ave masam var B. ABir yabancı anahtar vardır Büzerinde B, bireyin birincil anahtar B_ID.

Bazı nedenlerden dolayı (meşru sebepler olduğunu biliyorum) bu iki tabloyu anahtarda birleştirdiğimde bir dizin kullanmıyor.

Ayrı ayrı bir dizin oluşturmam gerekir mi A.B_IDyoksa yabancı anahtarın varlığı bunu sağlamalı mı?

Yanıtlar:


138

Yabancı anahtar kısıtlaması tek başına Oracle üzerinde indeksi sağlamaz - biri yaratılmalıdır (ve yapılmalıdır).


11
Bazı veritabanlarında yabancı anahtar kısıtlaması oluşturmak da bir dizin oluşturur ... yani Jet Engine (MSAccess dosyaları, Firebird ve MySQL)
bubi

17
Bu yanıt, belirli bir veritabanı uygulamasına açıkça atıfta bulunulmadan anlamsızdır. Sorunun etiketlendiğinden oracleemin olun, ancak bir google aramasından buraya geldiğinizde bu hemen anlaşılmaz.
developerbmw

5
PostgreSQL'in - en azından bu yazı sırasında - bunu otomatik olarak yapmadığını onaylayabilirim.
The Dembinski

Bildiğim kadarıyla SQL Server (2016, Azure ...) için aynı cevap.
Pac0

Oracle ile bir yabancı anahtar üzerinde neden indeks oluşturulmalı? Bunu yapmamanın sonuçları ne lütfen?
Đỗ Công Bằng

46

Yabancı anahtar oluşturmak, A.B_ID üzerinde otomatik olarak bir indeks oluşturmaz. Bu nedenle, A.B_ID üzerinde ayrı bir dizin oluşturmak genellikle bir sorgu performansı açısından mantıklı olacaktır.

B'deki satırları silerseniz, kesinlikle A.B_ID'nin indekslenmesini istersiniz. Aksi takdirde, artık kayıt olmadığından emin olmak için B'den bir satırı sildiğiniz her seferinde Oracle'ın A'da tam bir tablo taraması yapması gerekecektir (Oracle sürümüne bağlı olarak, ek kilitleme etkileri de olabilir, ancak bunlar azalır. daha yeni Oracle sürümlerinde).


1
Peki ya PFK sütunları? örneğin, çoktan çoğa ilişki için bir ara tablom varsa, bu tablonun iki PFK sütunu için bir dizin oluşturmam gerekir mi?
Clamari

3
@Clamari - C'nin birincil anahtarı (A_ID, B_ID) ise, birincil anahtar A'dan silmeye özen gösterir. Ayrıca B'den verimli bir şekilde silebilmek istiyorsanız, üzerinde bir indeks isteyebilirsiniz B_ID.
Justin Cave

25

Daha fazla bilgi için: Oracle, (benzersiz kısıtlamalar için yaptığı gibi) otomatik olarak bir dizin oluşturmaz çünkü (a) kısıtlamayı uygulamanız gerekmez ve (b) bazı durumlarda buna ihtiyacınız yoktur.

Ancak çoğu zaman bir dizin oluşturmak isteyeceksiniz (aslında Oracle Apex'te "dizine eklenmemiş yabancı anahtarlar" raporu var).

Uygulamanın üst tablodaki bir satırı silmesi veya PK değerini (daha nadir olan) güncellemesi gerektiğinde, dizin yoksa DML zarar görür, çünkü tüm alt tabloyu kilitlemesi gerekecektir.

Genellikle tercih olgusu değil FK, bir "statik verileri" tablosuna olduğu bir dizin eklemek olduğunu ebeveyn masaya güncelleştirme ve silme yapmadım olan bir sütunun tanımlar alanı (durum kodları örneğin bir tablo), doğrudan uygulama tarafından. Bununla birlikte, sütuna bir dizin eklemek uygulamadaki önemli sorgulara fayda sağlıyorsa, dizin yine de iyi bir fikir olacaktır.


14

SQL Server hiçbir zaman yabancı anahtar sütunlarına otomatik olarak dizin koymadı - Kim Tripp'in bu şehir efsanesinin geçmişi ve geçmişi hakkındaki mükemmel blog gönderisine bakın .

Yabancı anahtar sütunlarınızı indekslemek genellikle iyi bir fikirdir, bu yüzden evet, her FK sütununun bir indeks tarafından yedeklendiğinden emin olmanızı tavsiye ederim; tek başına o sütunda olması gerekmez - belki de FK sütunu ilk sırada olacak şekilde iki veya üç sütun üzerinde bir dizin oluşturmak mantıklı olabilir. Senaryonuza ve verilerinize bağlıdır.


8

Performans nedenleriyle bir dizin oluşturulmalıdır. Birincil tablodaki silme işlemlerinde (sildiğiniz kaydın kullanılmadığını kontrol etmek için) ve genellikle bir yabancı anahtarın dahil olduğu birleştirmelerde kullanılır. Yalnızca birkaç tablo (bunları günlüklerde oluşturmuyorum), dizine ihtiyaç duymayan olabilir, ancak muhtemelen, bu durumlarda muhtemelen yabancı anahtar kısıtlamasına da ihtiyacınız yoktur.

FAKAT

Yabancı Anahtarlarda otomatik olarak dizin oluşturan bazı veritabanları vardır. Jet Engine (Microsoft Access Dosyaları) Firebird MySQL

KESİNLİKLE

SQL Sunucusu Oracle

DEĞİL


3
FIrebird SQL'in bunu otomatik olarak yaptığından bahsettiğim için teşekkürler. Tam da aradığım nokta buydu.
user424855

1

Performansla ilgili herhangi bir şeyde olduğu gibi, pek çok faktöre bağlıdır ve hiçbir silve madde yoktur, örneğin çok yüksek aktivite ortamında bir endeksin sürdürülmesi kabul edilemez olabilir.

Buradaki en dikkat çekici nokta seçicilik olarak görünecektir: eğer indeksteki değerler yüksek oranda tekrarlanırsa, indeksi düşürmek (mümkünse) ve bir tablo taramasına izin vermek daha iyi bir performans sağlayabilir.


1

UNIQUE, PRIMARY KEY ve FOREIGN KEY kısıtlamaları, kısıtlamayı uygulayan veya "geri" getiren (ve bazen destek dizinleri olarak adlandırılır) dizinler oluşturur. PRIMARY KEY kısıtlamaları benzersiz dizinler oluşturur. FOREIGN KEY kısıtlamaları benzersiz olmayan dizinler oluşturur. UNIQUE kısıtlamaları, tüm sütunlar boş değer atanamazsa benzersiz dizinler oluşturur ve bir veya daha fazla sütun boş değer atanabilirse benzersiz olmayan dizinler oluşturur. Bu nedenle, bir sütun veya sütun kümesinde UNIQUE, PRIMARY KEY veya FOREIGN KEY kısıtlaması varsa, performans için bu sütunlarda bir dizin oluşturmanız gerekmez.



Bağlandığınız dokümanlar, Oracle için değil, gömülü Java veritabanı olan Derby içindir.
Davos
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.