Dikkate alınması gereken bir şey, Birincil Anahtar ve Kümelenmiş Bir Dizinin aynı şey olmadığıdır. Birincil Anahtar bir kısıttır ve verinin yaşadığı kurallarla (yani veri bütünlüğü) ilgilenir; verimlilik / performans ile ilgisi yoktur. Birincil Anahtar, anahtar sütun (lar) ın benzersiz (kombinasyon halinde) ve NOT NULL (ayrı ayrı) olmasını gerektirir. PK, Kümelenmiş veya Kümelenmemiş olabilmesine rağmen, Benzersiz bir Dizin yoluyla uygulanır.
Kümelenmiş Dizin, tablodaki verileri fiziksel olarak (yani diskte) sıralamak ve performansla ilgilenmek için kullanılan bir araçtır; veri bütünlüğü ile ilgisi yoktur. Bir kümelenmiş dizin kutuanahtar sütun (lar) ın benzersiz (birlikte) olmasını gerektirir, ancak buna gerek yoktur. Ancak, Kümelenmiş Dizin verilerin fiziksel sırası olduğundan, ne olursa olsun, her satırı benzersiz bir şekilde tanımlaması gerekir. Bu nedenle, benzersiz olmasını gerektirecek şekilde ayarlamazsanız, gizli 4 baytlık "benzersiz" sütun aracılığıyla kendi benzersizliğini oluşturur. Bu sütun, Benzersiz Kümelenmemiş Dizinlerde her zaman oradadır, ancak anahtar alanlar benzersiz olduğunda (birlikte) yer kaplamaz. Bu "benzersiz" sütunun nasıl çalıştığını ilk elden görmek için (hem Kümelenmiş Dizin'de hem de Kümelenmemiş Dizinler üzerindeki etki), Uniquifier boyutunu test etmek için PasteBin : T-SQL komut dosyasına gönderdiğim bu test komut dosyasına bakın .
Bu nedenle, ana soru:
bir otomatik artış id
alanı company_id
eklemek ve bunu birincil anahtar olarak birlikte kullanmak daha verimli olur mu yoksa gereksiz ek yük ekler mi
bu iki kavramı birleştiriyor, bu yüzden ayrı ayrı ele alınması gerekiyor, ancak kesinlikle bir çakışma var.
Bir IDENTITY
sütun eklenmeli mi yoksa gereksiz ek yük mü olurdu?
Bir INT IDENTITY
sütun ekleyip bir PK oluşturmak için kullanırsanız, her satıra 4 bayt ekleyen bir Kümelenmiş PK olacağını varsayarsak. Bu sütun sorgularda görülebilir ve kullanılabilir. Bu olabilir gerçi olmayacak bu özel durumda, bir yabancı anahtar olarak diğer tablolara eklenecektir.
INT IDENTITY
Sütunu eklemezseniz, bu tabloda bir PK oluşturamazsınız. Ancak, seçeneği kullanmadığınız sürece yine de bir Kümelenmiş Dizin oluşturabilirsiniz UNIQUE
. Bu durumda, SQL Server yukarıda açıklandığı gibi davranan "benzersiz" adlı gizli bir sütun ekleyecektir. Sütun gizlendiğinden, sorgularda veya Yabancı Anahtarlar için başvuru olarak kullanılamaz.
Verimlilik söz konusu olduğunda, bu seçenekler kabaca aynıdır. Evet, bazı satırların (ilk benzersiz anahtar değerlerine sahip olanlar) 0 bayt alması nedeniyle Benzersiz Kümelenmemiş Endeks'in 0 bayt alması nedeniyle biraz daha az yer kaplar, IDENTITY
/ PK'daki tüm satırlar 4 bayt alır. Ancak, 0 baytlık satırlardan (özellikle beklenen az miktarda satırla), ID
sütunu sorgularda kullanabilmenin rahatlığını daha da fazla bırakmak yerine, bir fark fark etmek için yeterli olmayacaktır .
INT IDENTITY sütunu mu yoksa org_path
kalıcı hesaplanmış sütun karma ?
org_path
Değerlere dayalı satırlara bakmayacağınız göz önüne alındığında , Kalıcı Hesaplanmış Sütun ek yükünü ve Hesaplanmış Sütunla eşleşmek için sorgulardaki bu karma değerini hesaplamanız gerekir. Buradaki revizyon geçmişinde mevcut olan orijinal öneri, Sorunun ilk ifadesine / ayrıntılarına dayanmaktadır). Bu özel durumda, INT IDENTITY
"ID" Sütunu muhtemelen en iyisidir.
Anahtar Sütun Sırası
Düşünüldüğünde ID
Kolon nadiren, if ever, sorgularda kullanılan, olacak ve iki ana kullanımın söz ya "tüm satırları" veya "belirli bir için tüm satırları almak olduğu göz önüne alındığında company_id
," Ben PK yaratacak company_id, id
. Ve bu, satırların sırayla eklenmediği için FILLFACTOR
, 90 değerini belirtirim . Parçalamayı azaltmak için düzenli dizin bakımı yaptığınızdan da emin olmanız gerekir.
İkinci soru
company_id'in başka bir tablodaki birincil anahtar olması, burada herhangi bir etkiye sahip mi?
Hayır.
tetik
A org_path
içindeki değerler company_id
benzersiz olduğundan, bunu INSERT, UPDATE
uygulamak için yine de bir Tetikleyici oluşturmanız gerekir . Tetikleyicide, IF EXISTS
muhtemelen bir COUNT(*)
ve yapan bir sorgu ile bir yapın GROUP BY company_id, org_path
. Bir şey bulunursa, ROLLBACK
DML işlemini iptal etmek için a ve ardından RAISERROR
yinelemeler olduğunu söyleyerek sorun yaşayın .
karşılaştırma
İlk cevabımda (sorunun orijinal ifadelerine / seyrek ayrıntılarına dayanarak ve burada düzeltme geçmişinde mevcut ), muhtemelen bir ikili (yani _BIN2
) Harmanlama kullanmanızı önermiştim . Şimdi tam olarak ne içgörü olması org_path
, ben ederim değil bir ikili harmanlama kullanılması önerilir. Ayırıcı işaretler söz konusu olacağı için, sen do dilsel eşdeğerlik faydalanmak istiyoruz.