Birincil anahtar değişmez mi olmalı?


26

Bir stackoverflow son soru birincil anahtarlar değişmezliği hakkında bir tartışma yarattı. Birincil kuralın değiştirilemez olması bir tür kural olduğunu düşünmüştüm. Bir gün birincil anahtarın güncellenme şansı varsa, bir yedek anahtar kullanmanız gerektiğini düşündüm. Ancak, SQL standardında değildir ve bazı RDBMS '"cascade update" özelliği, bir birincil anahtarın değişmesine izin verir.

Öyleyse sorum şu: değişebilecek birincil bir anahtara sahip olmak hala kötü bir uygulama mı? Varsa değiştirilebilir bir birincil anahtara sahip olmanın eksileri nelerdir?

Yanıtlar:


25

Sadece ihtiyaç yabancı anahtar bağlıysa değişmez olduğu birincil anahtar, ya da (öğe için bir sayfaya bir URL işaret eden örneğin) veritabanından dışında bir tanımlayıcı olarak kullanılır eğer.

Öte yandan, değişebilecek bazı bilgiler taşırsa , yalnızca değiştirilebilir bir anahtara sahip olmanız gerekir . Kaydın anahtar olarak kullanılabilecek basit, değişmez bir tanımlayıcısı yoksa, her zaman bir yedek anahtar kullanırım.


7
Neden "do gerek yabancı anahtar bağlıysa değişmez olduğu birincil anahtar"? OP'nin belirttiği gibi, çoğu RDBMS'nin "kaskad" güncelleme özelliği vardır.
Thanatos

1
@Thanatos en çok (aslında karşılaştığım hepsi) rdbms, değiştirilebilir birincil anahtarlara izin vermeyecek, ancak basamaklı güncellemelere sahip olacak. Genel olarak kabul edilen dba bilgeliğinde bir birincil anahtar hiçbir bilgi içermemelidir, yalnızca benzersiz bir kayıt tanımlayıcı olmalıdır (yani bir zaman damgası, hatta ertelenen kayıt aralığı, vb.).
32'de jwenting

5
@jwenting: Aynı şeyden mi bahsediyoruz? "çoğu rdbms en değişken anahtarlara izin vermez" ne içerir? MySQL ve PostgreSQL, değişken birincil anahtarlara izin verir ve basamaklı güncellemeleri onurlandırır ... standart SQL’in yapması gerektiğini söylediği gibi. Ayrıca, "genel kabul gören dba bilgeliği"? Taşıyıcı anahtarlara karşı çıkan birçok DBA ve doğal anahtarlara karşı çıkan birçok DBA ile tanıştım.
Thanatos

2
@Thanatos "Tüm masaların vekili olması gerekir" lehindeki argümanlar bibliyografik kaynaklardan yoksundur, "genel olarak dba bilgeliğini kabul eder", fakat asla bir kitaptan alıntı yapmadılar. Kanonik kitaplar şu durumlarda vekil kullanmanız gerektiğini söylüyor: A. hiçbir doğal anahtar yok, B. multicolumn anahtar excedes 3 sütun, veya C ise. Anahtarı her zaman değiştireceksiniz. Yani: uyduklarında doğal, doğal uyuşmadığında vekiller.
Tulains Córdova

4
@ user61852: Ne?
Guffa

15

Birincil anahtar , benzersizliği belirlemek için gerekli olan herhangi bir tübülerden oluşmalıdır. Verilerin değişip değişmemesi önemli değildir. Sadece kaydın benzersizliği önemlidir. Veritabanının kavramsal tasarımı budur.

Uygulama alanına girdiğimizde yapılacak en güvenli şey basitçe bir anahtar kullanmaktır.


15

Evet, bence birincil anahtar değişmez olmalı.

Belirgin aday anahtarlar olsa bile, her zaman bir yedek anahtar kullanırım. Birkaç kez bunu yapmadım, neredeyse her zaman pişman oldum. Anahtarın ne kadar değişmez olduğunu düşünürseniz düşünün, veri girişi hatalarına karşı koruma sağlayamazsınız - kullanıcılara bu bilgi parçasını düzenleyemeyeceklerini söyleyin, çünkü birincil anahtar ne yazık ki yıkanmaz.


Veri girişi hataları hakkında iyi bir nokta
Tim Goodman

Richeym, neden anahtarların değişmez olması gerekmediğini ortaya koyuyor gibi görünüyorsunuz: kullanıcılar onları değiştirmek isteyebilir.
nvogel

4
@dportas - Benim açımdan PK'nın değişmez olmasını seviyorum, bu yüzden tablo verilerinden türetilebilecek açık bir anahtar olduğunu düşünmeme rağmen her zaman vekil anahtarlar kullanın (ör. e-posta, kullanıcı adı).
richeym

2

Birincil anahtarlar değişirse veritabanı ve kullanıcı arasındaki önbellekleme mekanizmaları etkinliği kaybeder.


2

Neden olmasın? Çünkü bir sütunu silmek istiyorsun?

Sadece gereksinimlerin benzersiz olması için üç sütun çağrısı yapması, birincil anahtar olması gerektiği anlamına gelmez. Bu kuralın sonsuza dek süreceğini düşünebilirsiniz (Pinhead departmanı yöneticisi asla değişmeyeceğine yemin ettiğinde toplantı sırasında unutmayın? Biliyorsunuz, kovulanı.), Ama olmayacak.

Uyguladığım her cascade güncelleme ve kendim kodlarsam bir bonus için para alamıyorum.

Bilgisayar bir anahtar için bir anlam gerektirmez; IMHO, anahtarlar bilgisayarlar içindir, insanların geri kalan verileri mahvetmesine izin verin.


1
"anahtarlar bilgisayarlar içindir, insanların kalan verileri mahvetmelerine izin verin." +1, güzel.

2

Değerleri değişebilen bir anahtara sahip olmak kötü bir uygulama değildir.

İyi bir anahtarın özellikleri stabiliteyi içerir. Taklit edilebilirlik idealdir ancak ön şart değildir. Değişmezlik uğruna yapay bir anahtarın tanıtılması kötü bir uygulamadır.

Uluslararası Standart Kitap Numarası (ISBN) örneğini alın . Çok istikrarlı fakat değişmez: bir zamanlar kitap yayıncıları hata yapıyor ve dehşet veriyor! - yinelenen ISBN numaraları oluşabilir. Bu, bilgisayarlı bir veritabanında ISBN’nin bir aday anahtar olarak kabul edilmemesi gerektiği anlamına mı geliyor? Tabii ki değil. ISBN’nin avantajlarından biri, tüm kullanıcılar için sorunları küresel olarak çözecek güvenilir bir kaynağa sahip olmasıdır.

İyi bir anahtarın başka özellikleri de vardır. ISBN’in, anlamsız bir otomatik artan tamsayı anahtarının, örneğin aşinalık (kitap ticaretindeki herkes bilir veya ISBN’ye aşina)), doğrulanabilir (ISBN’nin tüm modern kitaplara basılmış olması) DBMS referans alınarak doğrulanabilir (ISBN sabit genişliktedir ve sağlama toplamı içerir), vb.


3
ISBN, aksi belirtilmediği sürece sabitdir (bkz. ISBN-10 - ISBN-13).
17:11 CVn'de

Peki, yinelenen ISBN’leri yönetmeyi nasıl önerirsiniz? Farkında olduğum tüm RDBMS'lerde, birincil anahtar olarak kullanmak için alanda UNIQUE kısıtına sahip olmanız gerekir.
Joker

1

Muhtemelen değiştirilemez olan her şey olmalı. Doğruluğunu sağlamaya yardımcı olur ve uygulamanızı okuyuculu yapmak istediğinizde yardımcı olur.


1

Evet, bir birincil anahtar boş ve benzersiz olmasının yanı sıra değişmez olmalıdır. Ancak, henüz birincil anahtarların değişmezliğini zorlayan bir veritabanı bulamamıştım, böylece gerçekten devam edersiniz ve gerçekten isterseniz değerlerini değiştirirsiniz.


0

Bazı yorumlar zaten söylediği gibi, bir çözüm yeni bir birincil anahtar kullanmaktır.

Örneğin (@oneday örneğini izleyerek) diyelim ki , bir kitap listesi depolayan Kitaplar tablosunun var olduğunu ve ISBN'yi birincil anahtar olarak belirlemek için "kullandık" diyelim . Bununla birlikte, bazı yazarlar yanlış bir ISBN yazarak hata yaptılar, bu yüzden de ISBN’yi değiştirmek istediler, bir sonraki görevleri içeriyorlardı:

  • Kitaplar tablosunda yeni bir kayıt defteri oluşturmak
  • eski ISBN’den yeni ISBN’ye tüm referansları gösterin. (*)
  • Ve son olarak, eski kayıt defterini Kitaplar tablosundan silin.

(*) Yabancı Anahtarları kullanan ancak bazı modellerde bulunmayan bir veritabanı modeli için tüm referansları bulmak önemsiz olabilir.

Table Books
ISBN  is the primary key
NAME is a simple field.
etc.

Olarak değiştiririz

Table Books
InternalBookId as the primary key
ISBN as a simple field or an indexed field.
NAME is a simple field.
etc.

Yeni InternalBookId'nin otonum bir değer bile olduğu yerde.

Bu konuda eksileri:

  • daha fazla alan / kaynak kullanan yeni bir alan ekler.

  • tüm modelin tekrar yazılmasını gerektirebilir.

  • Yeni model daha az kendi kendine açıklanabilirdi.

Profesyonel

  • "Birincil anahtarı" değiştirmeyi sağlar.
  • "Birincil anahtarı" örneğin düşürmek veya yeniden düzenlemek, örneğin Kitapları ISBN-13 olarak değiştirmek, eski sütunu bırakmak ve yeni bir tane oluşturmak için basittir.

Yeni masa:

Table Books
InternalBookId as the primary key
ISBN13 is a new field.
NAME is a simple field.
etc.
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.