Birincil anahtarların işletme alanınızın bir parçası olmadığı gerçeğini ele almak


25

Neredeyse her durumda, birincil anahtarlar işletme alan adınızın bir parçası değildir. Elbette, benzersiz endekslere sahip, kullanıcılara yönelik bazı önemli nesnelere sahip olabilirsiniz ( UserNamekullanıcılar veya OrderNumbersiparişler için), ancak çoğu durumda, etki alanı nesnelerini tek bir değer veya değer grubuyla açıkça tanımlamak gerekmez ; yönetici kullanıcı. Bu istisnai durumlarda bile, özellikle global benzersiz tanımlayıcıları (GUID) kullanıyorsanız, birincil anahtarın kendisini göstermek yerine alternatif bir anahtar kullanmak isteyeceksiniz veya kullanmak isteyeceksiniz.

Bu nedenle, etki alanı odaklı tasarım anlayışım doğruysa, birincil anahtarların açığa çıkması gerekmez ve bu nedenle açıklığa kavuşturulmamalıdır. Çirkin ve stilimi bozuyorlar. Ancak, etki alanı modeline birincil anahtarlar eklememeyi seçersek, bunun sonuçları vardır:

  1. Doğal olarak, yalnızca etki alanı modellerinin kombinasyonlarından türetilen veri aktarma nesneleri (DTO) birincil anahtarlara sahip olmayacaktır.
  2. Gelen DTO'ların birincil anahtarı olmayacak

Öyleyse, gerçekten saf kalacaksanız ve etki alanı modelinizdeki birincil anahtarları elimine edecekseniz, her isteği bu birincil anahtardaki benzersiz dizinler açısından ele almaya hazır olmanız gerektiğini söylemek güvenli midir?

Başka bir deyişle, aşağıdaki çözümlerden hangisi etki alanı modellerinde PK kaldırıldıktan sonra belirli nesneleri tanımlamakla başa çıkmak için doğru yaklaşımdır?

  1. Diğer özelliklerle uğraşmanız gereken nesneleri tanımlayabilmek
  2. Birincil anahtarı DTO'ya geri alma; yani, kalıcılıktan etki alanına eşleme yaparken PK'nin elimine edilmesi, ardından etki alanından DTO'ya eşleme yaparken PK'nin yeniden birleştirilmesi?

EDIT: Bu somut yapalım.

Alan adı modelidir Say VoIPProvidergibi alanları içeren Name, Description, URL, referanslar gibi yanı sıra ProviderType, PhysicalAddressve Transactions.

Şimdi ayrıcalıklı kullanıcıların yönetimi yönetmesine izin verecek bir web servisi oluşturmak istediğimi VoIPProvidervarsayalım.

Belki de kullanıcı dostu bir kimlik bu durumda işe yaramaz; Sonuçta, VoIP sağlayıcıları, isimleri bilgisayar anlamında ve hatta insani nedenlerden dolayı, ticari nedenlerden dolayı yeterince belirgin olan şirketlerdir. Bu nedenle, benzersiz VoIPProviderolanın tamamen belirlendiğini söylemek yeterli olabilir (Name, URL). Şimdi PUT api/providers/voipayrıcalıklı kullanıcıların VoIPsağlayıcıları güncelleyebilmesi için bir yönteme ihtiyacım olduğunu varsayalım . Potansiyel olarak bazı düzleştirmeler de dahil olmak üzere VoIPProviderDTO, alanların birçoğunun tamamını içermeyen bir alan gönderir VoIPProvider. Ancak, onların akıllarını okuyamıyorum ve hala hangi sağlayıcıdan bahsettiğimizi söylemeleri gerekiyor.

2 (belki 3) seçeneğim var gibi görünüyor:

  1. Etki alanı modelime bir birincil anahtar veya alternatif anahtar ekleyin ve bunu DTO’ya gönderin;
  2. Değer verdiğimiz sağlayıcıyı benzersiz dizin aracılığıyla belirle (Name, Url)
  3. Kalıcılık katmanı, etki alanı ve DTO arasında her zaman kalıcılık katmanı ile ilgili uygulama ayrıntılarını göstermeyecek şekilde eşleştirilebilecek bir tür ara nesne tanıtın;

1
Düşünmek: genellikle iyi bir iş anahtarı olduğunda vekil PK kullanıldığında etki alanı uzmanlarıyla iletişim bozulmaya başlar. Görünüşe göre ORM çerçevesi için çalışıyoruz, tersi yerine.
Tulains Córdova

@ user61852, ORM'den bağımsız olarak, gerçekten düşük seviyeli olsanız bile, veritabanı katmanının uygulanmasında hala birincil bir anahtara ihtiyacınız vardır. Bu nedenle, vekil PK'nin size belirli bir sebat mekanizması tarafından kullanılan fiili PK'ye göre avantajlar sağladığını kabul ediyorum, ancak eğer PK gerçekten anlamlı olan bir iş nesnesini temsil ediyorsa, mutlaka benzersizdir ve bu nedenle en az bir benzersiz işle ilgili özelliği tanımlayan Değil?
tacos_tacos_tacos 27:14

1
Vekillerin tüm avantajları bilgisayarla ilgilidir ve insanla ilgili değildir.
Tulains Córdova

2
@ user61852:% 100 kabul ediyorum (farklı bir şey mi yazdım?). İletişim için bir "iş anahtarı" kullanın. Herhangi bir işletme anahtarı için de benzersiz sınırlamalar ekleyin. Ancak, aslında veritabanı referanslarınızı uygulamak için iş anahtarlarının kullanılmasından kaçının.
Doktor Brown

2
iş anahtarları sonsuza dek eşsizdir - olmadıkça. Bu durumda iş tuşlarını birincil olarak kullanıyorsanız, iş kurallarındaki değişiklik daha fazla şeyi kırar.
psr

Yanıtlar:


31

Bunu nasıl çözdüğümüzün yolu budur (15 yıldan beri, "etki alanına dayalı tasarım" teriminin bile bulunmadığı zamanlarda):

  • etki alanı modelini bir veritabanı uygulamasına veya belirli bir programlama dilinde bir sınıf modeline eşlerken, ilişkisel bir tabloya eşlenen her etki alanı nesnesi için "gibi basit, tutarlı bir kuralınız olur; birincil anahtar" TablenameID "olur.
  • Bu ana anahtar tamamen yapaydır, daima aynı tiptedir ve iş anlamı yoktur - yalnızca bir yedek anahtar
  • etki alanı modelinizin (etki alanı uzmanlarınızla konuşmak için kullandığınız) "grafik sürümü" birincil anahtarlar içermez. Onları doğrudan uzmanlara maruz bırakmazsınız (ancak onları sistem kodunu gerçekten uygulayan herhangi birine maruz bırakırsınız).

Bu nedenle, teknik amaçlar için bir birincil anahtara (ne zaman bir veritabanıyla ilişkileri eşlemek gibi) ihtiyaç duyduğunuzda) bir tane elinizde bulunur, ancak “görmek” istemediğiniz sürece, soyutlama seviyenizi “etki alanı uzmanları modeli” olarak değiştirin ". Ve "iki modeli" sürdürmek zorunda değilsiniz (biri PK'lı, biri olmayan); bunun yerine, sadece PK olmayan bir model bulundurun ve DB'niz için DDL'yi oluşturmak için bir kod oluşturucu kullanın, bu da PK'yi eşleme kurallarına göre otomatik olarak ekler.

Bunun, vekilin yanı sıra ek bir "OrderNumber" gibi herhangi bir "iş anahtarını" eklemeyi yasaklamadığını unutmayın OrderID. Teknik olarak bu işletme anahtarları, veritabanınızla eşleştirirken alternatif anahtarlar haline gelir. Bunları başka tablolara referanslar oluşturmak için kullanmaktan kaçının, mümkünse vekil anahtarların kullanılması her zaman tercih edilir, bu işleri çok daha kolay hale getirir.

Yorumunuza: tanımlayan kayıtlar için bir vekil tuşunu kullanarak ise hiçbir o tamamen teknik bir işlem olduğunu, işle ilgili çalışma. Bunu açıklığa kavuşturmak için, örneğinize bakın: ek benzersiz çelişkiler tanımlamadığınız sürece, aynı VoIPProvider nesnesiyle aynı adda (ad, url), ancak farklı VoIPProviderID öğelerinin bulunması mümkün olabilir.


Etki alanı nesnesini döndürülen kalıcılık nesnesinden alma (varlık veya tablo satırı modeli ya da her neyse), DTO'ya gidip geri alma ve kalıcılık durumuna geri dönme aşamasına ne dersiniz? Bu, her bir sebat etme işlemi için bir çözüm gerektiren bir yedek anahtar (yani, iş odaklı benzersizliğin tanımı) yoluyla mı yapılıyor?
tacos_tacos_tacos 27:14

1
@tacos_tacos_tacos: VoIPProvider örneğinize bağlı kalalım. Aslında DTO'nuza bir "VoIPProviderID" ekleyeceğim, en azından "uygulama tarafında" (etki alanı uzmanlarınız için grafiksel bir sürümünüz varsa, muhtemelen orada göstermeyeceğim). Güncelleme amacıyla, belirli bir VoIPProvider'ı tanımlamanın standart yolu, veriyi veritabanından çekerken aldığınız "VoIPProviderID" olmalıdır. API'nizin kullanıcıları tarafından (ad, URL) tanımlamayı tercih ederse, ek olarak bunu sağlayın. ...
Doc Brown

... ve performans gerçek, ölçülebilir bir sorun gibi görünüyorsa, eşlemeyi (name, url) bir yerde VoIPProviderID olarak önbelleğe almayı da düşünebilirsiniz. Ancak, önceden böyle bir optimizasyonun yapılmasını tavsiye etmem.
Doktor Brown,

1
Doğal anahtarlar bazen gerçekten zorlayıcı görünebilir ancak yanmak çok kolaydır (örneğin, "ağlar, şimdi birden fazla kiracım var ve bu artık benzersiz değil").
Casey,

1
@corsiKa: OP'nin sorduğu şey bağlamında, tamamen otomatikleştirilmiş bir "Sipariş Kimliği" anahtarına sahip olmanızı şiddetle tavsiye ederim (herhangi bir makbuzda yazdırılmayan, ancak yalnızca veritabanı referansları gibi dahili şeyler için kullanılır) ve ayrı bir işletme anahtarı "Sipariş Numarası" (örneğin, mevcut yıl gibi, sıralama ve filtreleme için kullanılabilen, daha sonra değiştirilebilen / düzeltilebilen ve faturalara yazdırılabilen bir şey içerebilir). OP, "Domain Driven Design" ı istedi, "OrderNumber" etki alanı modelinin bir parçası iken "OrderID" sadece bir uygulama detayıydı.
Doktor Brown,

4

Birçok nesneyi benzersiz bir dizinle tanımlayabilmeniz gerekir ve birincil anahtarın ne olduğu (veya en azından birinin mevcut olduğu anlamına gelmez ) değildir.

Benzersiz dizinler mevcuttur, böylece PK şemalarınızı toptan olarak değiştirmek yerine DB şemasını daha da kısıtlayabilirsiniz. Eğer PK’leri teşhir edemiyorsanız, çirkinsiniz ama onun yerine benzersiz bir anahtar ifşa ediyorsunuz ... aslında farklı bir şey yapmıyorsunuz. (Bir PK ve burada bir kimlik sütunu alamadığınızı varsayıyorum?)


Kalıcı olan bir etki alanı nesnesinin belirli bir örneğini içeren bir işlem yapmak istediğimde, DTO’ya açıkça (birincil veya alternatif kullanıcı dostu bir kimlik anahtarıyla bir tür anahtarla dahil edilebilir) ekleyebilmem gerekir. bu tabloya ve tablodaki bir indeks olabilir) veya dolaylı olarak (değerleri belirli bir kaydı özel olarak tanımlayan alanların bir kısmı aracılığıyla) ... ve ayrıca pratik anlamda DTO’ya göndermem gerekecek. başka bir yolla yapsaydım, değişim izlemenin bir şekli (kaydı tanımlayan tüm alanlar için OriginalVal - NewVal), hayır?
tacos_tacos_tacos 27:14

Açık v örtülü soru aynı fark değil midir? Tıpkı benzersiz bir dizin gibi, birden çok sütun içeren bir PK’niz olabilir. Amaçlarınız arasında aralarında bir fark olduğunu görmüyorum.
gbjbaanb

Elbette, örneğin birden çok sütunda bir PK olabilir. Ama bana göre, iş dünyasında yürek ve ruhla hiçbir ilgisi olmayan veri bankası (depolama) hakkında bir şeyler sızdırıyor. Eğer bir miktar işletme varlık alanı DB için PK'yi kapsıyorsa, o zaman harika. Fakat mutlaka tam tersi olması gerekmiyor, değil mi?
tacos_tacos_tacos 27:14

Üzerini düşünüyorsun. Benzersiz bir dizin, bir PK kadar DB şemasının bir eseridir. Bunu bu şekilde düşünün - bir PK sadece ilk (veya birincil) benzersiz endekstir. 'özel' çünkü sadece 1 böyle indekse ihtiyacınız var.
gbjbaanb

Doğru, ancak anlamlı herhangi bir etki alanı nesnesinin, kesinlikle işle ilgili alanlarından en az bir tanesinden tanımlanabilir olması gerekir, değil mi? Bunun DB'deki bir dizini tanımlaması, DB'yi kolayca sorgulamak için kullanılmak yerine performans nedeniyle daha fazladır ... 6 sütunlu benzersiz bir dizine tek sütunlu bir PK tercih ederim ve gerçekten farklı amaçlara hizmet ediyorlar - DBA / DBD'nin rahatlığı için bir PK (veya az sayıda alan içeren dizin) de bulunur, değil mi?
tacos_tacos_tacos 27:14

4

Ön uçtaki birincil anahtarlar olmadan, arka uç için ne gönderdiğinizi bilmenin kolay bir yolu yoktur. Verileri ayrıştırmak için bir ton fazladan çalışmaya ihtiyaç duyacağınızı düzeltmek için, performansa zarar verecek ve muhtemelen her bir öğeye anahtar eklemekten daha fazla zaman ve çirkin kalacaktır.

Örnek olarak, bir uygulamadaki bir mesajı düzenlemek istediğimi söyleyelim; Uygulamaya, ek bir anahtar ekli olmadan hangi mesajı düzenlemek istediğimi nasıl bileyim? Nesneleri düzenlemek her zaman olur ve bunu anahtarsız yapmak hemen hemen imkansızdır. Ancak düzenlenmemesi gereken nesneleriniz varsa, dikkat dağıtıcı olduğunu düşünüyorsanız, ancak birincil tuşlara sahip olmak buradaki performansı artırabilirse anahtarı atlayın.


Eh, mesaj uç bir örnektir, ama o zaman bile biz bilemez MessageSender, MessageRecipient, TimeSent- o benzersiz olmalıdır.
tacos_tacos_tacos 27:14

1
@tacos_tacos_tacos, o zaman diğer tablolara FK'ları nasıl yaratırsınız? Bu, muhtemelen UserId'deki Kullanıcılar tablosuna eşlenen MessageSenderId olmalıdır. KullanıcıAdı'nı tablolar arasında bir anahtar olarak kullanmak istemezsiniz, çünkü bunlar değişebilir ve bakım kabusu olur. Bu nedenle genellikle yalnızca Birincil Anahtarlar kullanarak tablolara katılırsınız, başka bir sütun değil (kesinlikle istisnalar vardır). Bu db yapısı hala uygulanmalıdır. Artık her zaman uygulamanız için bir CQRS modeline gidebilirsiniz ... bu durumda kurallar değişebilir. Özellikle Event Sourcing kullanıyorsanız.
CaffGeek

4

İşle ilgili olmayan bir PK kullanmamızın nedeni, sistemimizin, kullanıcının ne istediğini belirlemenin kolay ve tutarlı bir yöntemine sahip olmasını sağlamaktır.

Bir yorum ile cevaplandığını görüyorum: MessageSender, MessageRecipient, TimeSent (bir mesaj için). STILL bu şekilde belirsizliğe sahip olabilir (örneğin, sık sık olan bir şeyi tetikleyen sistem tarafından üretilen mesajlarla). Peki burada MessageSender ve MessageRecipient'ı nasıl doğrulayacaksınız? Onları FirstName, Soyadı, DateOfBirth kullanarak doğruladığınızı varsayalım, sonunda aynı günde aynı anda aynı isimde 2 kişinin doğduğu bir duruma rastlayacaksınız. Bir mesajın verildiği bir durumla karşılaşacağınızdan bahsetmiyorum bile tacostacostacos-America-1980-Doc Brown-France-1965-23/5/2014-11:43:54.003UTC+200. Bu bir adın canavarı ve hala bunlardan sadece 1'inin olacağının garantisi yok.

Bir birincil anahtar kullanmamızın nedeni, hangi verinin girildiğine bakılmaksızın yazılımın kullanım ömrü boyunca benzersiz olacağını bilmemiz ve bunun tahmin edilebilir bir format olacağını bilmemizdir (yukarıdaki anahtarınızda kısa çizgi varsa ne olur?) Bir kullanıcı adında mı?

Kimliğinizi kullanıcıya göstermeniz gerekmez. Bunu gizleyebilirsiniz (gerekirse, URL üzerinden görünürde).

Bir PK'nin bu kadar kullanışlı olmasının bir başka nedeni de, yukarıdan çıkartabileceğiniz bir şeydir: PK, bilgisayarı, kullanıcı tarafından oluşturulan kodu yorumlamaya zorlamanıza gerek kalmaması için yapar. Bir Çinli kullanıcı kodunuzu kullanıyorsa ve bir sürü Çince karakter girerse, kodunuzun aniden bunlarla dahili olarak çalışabilmesi gerekmez, ancak yalnızca sistemin oluşturduğu Guid'i kullanabilir. Arapça yazıya giren bir Arap kullanıcınız varsa, sisteminiz bununla içten baş etmek zorunda değildir, ancak orada olduklarını görmezden gelebilir.

Diğerlerinin dediği gibi, bir Rehber dahili olarak sabit bir boyutta saklanabilen bir şeydir. Ne ile çalıştığınızı biliyorsunuz ve bu evrensel olarak kullanılabilecek bir şey. Belirli bir tanımlayıcıyı nasıl oluşturduğunuza ve kaydettiğinize ilişkin tasarım kuralları oluşturmanıza gerek yoktur. Sisteminiz yalnızca bir ismin ilk 10 harfini alırsa, Michael Guggenheimer ve Michael Gugstein arasında bir fark görmez ve bunları karıştırır. Kullanıcı girişini sınırlandırırsanız, kullanıcı sınırlamaları ile ilgili sorunlarla karşılaşabilirsiniz.

Dynamics CRM gibi mevcut sistemlere baktığımda, kullanıcının tek bir kaydı çağırması için dahili anahtarı (PK) da kullanıyorlar. Bir kullanıcının kimliği içermeyen bir sorgusu varsa, olası cevapların bir dizisini döndürür ve kullanıcının ondan seçim yapmasına izin verir. Belirsizlik konusunda herhangi bir şans varsa, kullanıcıya seçim yapacaktır.

Son olarak, aynı zamanda gizlilik yoluyla güvenlik de abit. Kayıt kimliğini bilmiyorsanız, tek seçeneğiniz tahmin etmektir. Kimliğin tahmin edilmesi kolaydır (çünkü yaptığı bilgiler herkese açıktır), herkes onu değiştirebilir. Kullanıcının klasik CSRF veya XSS yöntemleri ile değiştirmesine bile varabilirsiniz. Şimdi, açıkçası, güvenliğiniz zaten canlı sürümü yayınlamadan önce hesaba katılmış ve azaltılmış olanlara sahip olmalıdır, ancak potansiyel kötüye kullanımın gerçekleşmesini zorlaştırmanız gerekir.


1

Harici bir sistem için bir tanımlayıcı verirken, veritabanı birincil anahtarını doğrudan açıklamak yerine, yalnızca URI'leri veya alternatif olarak URI ile aynı özelliklere sahip bir anahtarı veya bir anahtar kümesini vermelisiniz (buradan itibaren hem URI hem de bir anahtar veya sadece URI ile aynı özelliklere sahip bir anahtar kümesi, başka bir deyişle aşağıdaki URI, RFC 3986 URI anlamına gelmez).

Bir URI, nesnenin birincil anahtarını içerebilir veya içermeyebilir ve aslında alternatif anahtarlardan oluşabilir veya olmayabilir. Gerçekten önemli değil. Önemli olan, yalnızca URI'yi oluşturan sistemin, belirtilen nesnenin ne olduğunu anlamak için URI'yi bölmesine veya birleştirmesine izin verilmesidir. Harici sistemler URI'yi her zaman opak bir tanımlayıcı olarak kullanmalıdır. Bir insan kullanıcısı, URI'nin bir kısmının aslında bir veritabanı vekil anahtarı olduğunu veya bir araya getirilmiş birkaç işletme anahtarından oluşması veya aslında bu değerlerin bir temeli 64 olduğunu tespit edip etmemesi önemli değildir. Bunlar alakasız. Önemli olan, tanımlayıcının tanımlayıcıyı kullanmak için ne anlama geldiğini anlamak için harici sistemin gerekli olması gerekmemesidir. Tanımlayıcı içerisindeki bileşenleri ayrıştırmak veya sisteminizdeki bir şeye başvurmak için tanıtıcıyı diğer tanıtıcılarla birleştirmek için harici sistemler asla gerekli olmamalıdır.

GUID kullanımı bu kriterlerden bazılarını yerine getirir, ancak GUID gibi tanımlayıcı, sisteminiz dahilinde bile nesneye geri dönüşü zorlaştırabilir, bu nedenle sisteminiz bir GUID gibi düz bile olsa opak olan anahtarlar, yalnızca kullanıcı gerçekten URI / tanımlayıcıyı ayrıştırıyorsa kullanılmalıdır. güvenlik riski oluşturur.

VoIP örneğinize geri dönünce, bir VoIP sağlayıcısının (VoIPProviderID) veya (Ad, URL) veya (GUID) tarafından benzersiz bir şekilde belirlenebileceğini söyleyin. Harici bir sistemin VoIP sağlayıcısını güncellemesi gerektiğinde, sadece bir PUT / sağlayıcı / by-id / 1234'ü geçebilir PUT /provider/foo-voip/bar-domain.comveya PUT /3F2504E0-4F89-41D3-9A0C-0305E82C3301sisteminiz harici sistemin VoIPProvider'ı güncellemek istediğini anlar. Bu URI'ler sisteminiz tarafından üretilir ve yalnızca sizin sisteminizin tümünün aynı anlama geldiğini anlaması gerekir. Dış sistem yalnızca URI'de bulunanları temel olarak a olarak değerlendirmelidir PUT <whatever>.

Farklı şemalara sahip farklı tablolarda depolanan farklı VoIP sağlayıcıları için verilere sahip olduğunuzu varsayalım (bu nedenle, tamamen farklı anahtar dizileri, hangi tabloda depolandıklarına bağlı olarak her bir VoIP sağlayıcısını tanımlar). Bir URI'nız olduğunda, sisteminize belirli bir VoIP sağlayıcısını nasıl tanımladığına bakılmaksızın, harici sistem tarafından düzenli olarak erişilebilir. Dış sistem için hepsi sadece opak bir işaretçi.

Sisteminiz nesnelere böyle bir şekilde başvurmak için bir URI kullandığında, sisteminizi nasıl uyguladığınızla ilgili hiçbir şeyi sızdırmazsınız. URI'yi yaratırsınız ve müşteri bunu basitçe size geri iletir.


0

Bu çılgınca yanlış ve saf ifadeyi hedeflemek zorunda kalacağım:

Belki de kullanıcı dostu bir kimlik bu durumda işe yaramaz; Sonuçta, VoIP sağlayıcıları, isimleri bilgisayar anlamında ve hatta insani nedenlerden dolayı, ticari nedenlerden dolayı yeterince belirgin olan şirketlerdir.

Adlar sıklıkla değiştiğinden, anahtar olarak korkunç . Bir şirketin ömrü boyunca birçok adı olabilir, şirket birleştirme, ayrılma, tekrar birleştirme, 0 çalışanı olan belirli vergi amaçları için farklı bir iştiraki olan ancak müşterileri işe alan tüm müşterileri için ayrı bir bağlı kuruluş oluşturabilir.

Ardından, Apple ve Apple'ın işaret ettiği gibi, şirket adlarının uzaktan bile benzersiz olmadığı gerçeğine giriyoruz .

İyi bir nesne ilişkisel eşleyici veya çerçeve gerektiğini onlar orada birincil anahtarlar uzak soyut ve bu görünmez yapmak, ancak, ve genellikle olacak tek veritabanınızda benzersiz bir nesneyi tanımlamak için bir yol.

Başvuru için django'nun bunu nasıl idare edeceğini tercih ederim :

class VoipProvider(models.Model):
    name=fields.TextField()
    address=fields.TextField()

class Customer(models.Model):
    name=fields.TextField()
    address=fields.TextField()
    voipProvider=fields.ForeignKeyField(VoipProvider)

Bu şekilde, bir müşteri sağlayıcısının detaylarına aşağıdakileri kullanarak kodda erişebilirsiniz:

myCustomer.voipProvider.name #returns the name of the customers VOIP Provider.

Birincil / Yabancı anahtarlar görünmese de, oradalar ve öğelere erişmek için kullanılabilirler, ancak soyutlanırlar.


Kesinlikle haklısın, ama sanırım "bazı alanlarda, her zaman benzersiz olan doğal bir değer dizisi vardır" demiştim. Eğer değişirlerse, ama yine de benzersizlerse, yine de tek bir rekor belirlediler.
tacos_tacos_tacos 28:14

0

Bence genellikle bu konuya DB perspektifinden yanlış bakıyoruz: oh, doğal bir anahtar yok, bu yüzden bir vekil anahtar yaratmamız gerekiyor. Oh hayır, vekil anahtarını etki alanı nesnelerine geri getiremiyoruz, bu sızdıran vs.

Bununla birlikte, bazen daha iyi bir tutum şudur: Bir işletme (etki alanı) nesnesinin doğal bir anahtarı yoksa, o zaman belki bir tane verilmelidir. Bu iki yönlü bir iş alanı sorunudur: Birincisi, veritabanlarının yokluğunda bile, her şey bir kimliğe ihtiyaç duyar. İkincisi, sebat etmeye çalışmamıza rağmen, etki alanı için görünmez olan soyut bir fikir olsa da, gerçekte sebat hala bir iş kavramıdır. Açıkçası, seçilen doğal anahtarın DB tarafından birincil anahtar olarak desteklenmediği (örneğin bazı sistemlerde GUID'ler) sorunlar vardır - bu durumda bir yedek anahtar eklemeniz gerekir.

Böylece, çok benzer bir yere sahip olursunuz, örneğin müşteriniz bir tamsayı kimliğine sahiptir, ancak DB'den etki alanına sızdığı için hasta hissetmek yerine, kendinizi mutlu hissedersiniz, çünkü işletme tüm müşterilerin atanacağını kabul etti. Kimlik, ve bunu gerektiği gibi DB'ye devam ettiriyorsun. Bir vekil tanıtmak, örneğin müşteri kimliğini yeniden adlandırmayı desteklemek için hala özgürsünüz.

Bu yaklaşım ayrıca, eğer bir etki alanı nesnesi kalıcılık katmanına çarparsa ve bir kimliği yoksa, o zaman muhtemelen bir tür değer nesnesidir, yani bir kimliğe ihtiyaç duymaz.

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.