SORU
26 AĞUSTOS 2010, PERŞEMBE


Nasıl bir veritabanı mirası temsil edebilir mi?

SQL Server veritabanında karmaşık bir yapıyı temsil etmek için nasıl hakkında düşünüyorum.

Bazı öznitelikleri paylaşan nesnelerin bir aile, saklaması gereken bir uygulama düşünün, ama diğerleri yaygın değildir. Örneğin, Ticari sigorta paketi sorumluluk, motor, mülkiyet ve tazminat aynı ilke kaydın içinde bir kapak olabilir.

Bölüm kapağı çeşitli türleri için gerekli olan kalıtsal olduğu Bölümler, koleksiyonu ile bir İlke oluşturabilirsiniz olarak C#, vb, bunu uygulamak için önemsiz. Ancak, ilişkisel veritabanları bu kadar kolay izin verecek gibi görünmüyorlar.

İki ana seçenek olduğunu görebiliyorum:

  1. Tüm alanları gerekli Politika tablosu, Bölüm tablosu oluşturmak, boş olurdu en olası tüm varyasyonları için.

  2. Politika bir tablo ve çok sayıda Bölüm tabloları, kapak her tür için bir tane oluşturun.

Bu alternatiflerin her ikisi de özellikle çok sayıda kapsayacak tüm Bölümler, katılır genelinde sorguları yazmak için gerekli olduğu gibi tatmin edici gibi görünüyor, ya da çok sayıda kontrol null.

Bu senaryo için en iyi uygulama nedir?

CEVAP
26 AĞUSTOS 2010, PERŞEMBE


@Bill Karwin Entity-Attribute-Value SQL antipattern çözümler getirilmesi SQL Antipatterns kitabı, üç miras modelleri açıklar. Bu kısa bir özet

(Hiyerarşi Miras Başına aka Tablo) tek Tablo Devralma:

İlk seçenek olarak tek bir tablo kullanarak muhtemelen en basit tasarım. Sizin de bahsettiğiniz gibi, alt-özgü birçok özellikleri bu öznitelikler geçerli olmayan satırları üzerinde NULL bir değer verilmesi gerekecek. Bu model ile benzer olan bir politikaları tablo olurdu:

 ------ --------------------- ---------- ---------------- ------------------ 
| id   | date_issued         | type     | vehicle_reg_no | property_address |
 ------ --------------------- ---------- ---------------- ------------------ 
|    1 | 2010-08-20 12:00:00 | MOTOR    | 01-A-04004     | NULL             |
|    2 | 2010-08-20 13:00:00 | MOTOR    | 02-B-01010     | NULL             |
|    3 | 2010-08-20 14:00:00 | PROPERTY | NULL           | Oxford Street    |
|    4 | 2010-08-20 15:00:00 | MOTOR    | 03-C-02020     | NULL             |
 ------ --------------------- ---------- ---------------- ------------------ 

\------ COMMON FIELDS -------/          \----- SUBTYPE SPECIFIC FIELDS -----/

Tasarım basit tutmak bir artı olduğunu, ancak bu yaklaşım ile temel sorunlar şunlardır:

  • Yeni alt ekleyerek söz konusu olduğunda, bu yeni nesneleri tanımlayan öznitelikleri yerleştirmek için tabloyu değiştirmek gerek. Bu hızlı bir şekilde çok sayıda alt tipi var, ya da eğer düzenli olarak alt eklemek için planlıyorsanız sorunlu olabilir.

  • Veritabanı geçerli öznitelikleri ve alt türlerinden olan ait tanımlamak için meta veri yoktur bu yana, don olan uygulamak mümkün olmayacaktır.

  • Sen de zorunlu olması gereken bir alt tür özellikleri NOT NULL zorlamak. Genel olarak ideal olan uygulama, bu işlemek gerekir.

Beton Masa Mirası:

Miras çözmek için başka bir yaklaşım, her bir alt tür için yeni bir tablo, her tabloda bütün ortak niteliklerini tekrar oluşturmaktır. Örneğin:

--// Table: policies_motor
 ------ --------------------- ---------------- 
| id   | date_issued         | vehicle_reg_no |
 ------ --------------------- ---------------- 
|    1 | 2010-08-20 12:00:00 | 01-A-04004     |
|    2 | 2010-08-20 13:00:00 | 02-B-01010     |
|    3 | 2010-08-20 15:00:00 | 03-C-02020     |
 ------ --------------------- ---------------- 

--// Table: policies_property    
 ------ --------------------- ------------------ 
| id   | date_issued         | property_address |
 ------ --------------------- ------------------ 
|    1 | 2010-08-20 14:00:00 | Oxford Street    |   
 ------ --------------------- ------------------ 

Bu tasarım temelde sorunları tek tablo yöntemi için tespit çözecek:

  • Zorunlu öznitelikleri şimdi NOT NULL zorlanabilir.

  • Yeni bir alt ekleyerek yeni bir tablo eklemek yerine varolan bir sütun ekleme gerektirir.

  • Aynı zamanda uygun olmayan bir nitelik, belirli bir alt türü, mülkiyet politikası vehicle_reg_no Alanı olarak belirlenen risk yok.

  • Tek tablo yöntemi olarak type öznitelik gerek yok. Bu tip meta ile tanımlanır: tablo adı.

Ancak bu model aynı zamanda birkaç dezavantajları ile geliyor

  • Ortak öznitelikleri alt türü ile belirli öznitelikleri karıştırılmış ve onları tanımlamak için kolay bir yolu yoktur. Veritabanı da bilmez.

  • Tablo tanımlarken, her alt tablo için ortak niteliklerini tekrar etmek zorunda kalacak. Kesinlikle DRY değil.

  • Tüm ilkeleri alt türü ne olursa olsun, arama zor olur, ve UNIONs bir sürü gerektirir.

Bu tüm politikaları türü ne olursa olsun sorguya mı iyi olurdu

SELECT     date_issued, other_common_fields, 'MOTOR' AS type
FROM       policies_motor
UNION ALL
SELECT     date_issued, other_common_fields, 'PROPERTY' AS type
FROM       policies_property;

Yeni alt ekleme yukarıdaki sorgu her bir alt tür için UNION ALL bir ek ile değiştirilmesi gerekir. Bu kolayca bu işlem unutulmuş ise uygulama hataları yol açabilir.

Sınıf Tablo Devralma (Tip Kalıtım Başına aka Tablo):

Bu 24 ** çözüm. Tüm ortak öznitelikleri içeren bir temel sınıf, tek bir tablo oluşturun. Sonra da temel tablo için foreign key olarak görev olan, her bir alt tür için özel bir tablo oluşturmak istiyorsunuz. Örnek:

CREATE TABLE policies (
   policy_id          int,
   date_issued        datetime,

   -- // other common attributes ...
);

CREATE TABLE policy_motor (
    policy_id         int,
    vehicle_reg_no    varchar(20),

   -- // other attributes specific to motor insurance ...

   FOREIGN KEY (policy_id) REFERENCES policies (policy_id)
);

CREATE TABLE policy_property (
    policy_id         int,
    property_address  varchar(20),

   -- // other attributes specific to property insurance ...

   FOREIGN KEY (policy_id) REFERENCES policies (policy_id)
);

Bu çözüm sorunları diğer iki tasarımları tespit çözer:

  • Zorunlu nitelikler NOT NULL ile zorlanabilir.

  • Yeni bir alt ekleyerek yeni bir tablo eklemek yerine varolan bir sütun ekleme gerektirir.

  • Uygunsuz bir nitelik, belirli bir alt kümesi için hiçbir risk.

  • type öznitelik gerek.

  • Şimdi ortak öznitelikleri alt türü ile belirli öznitelikleri artık karışık değil.

  • KURU, son olarak kalabiliriz. Tabloları oluştururken her alt tablo için ortak niteliklerini tekrar etmeye gerek yok.

  • Politikaları için bir otomatik artan id yönetme bu her alt tablo bağımsız olarak onları oluşturmak yerine temel tablo tarafından ele alınabilir, çünkü daha kolay bir hale gelir.

  • Tüm politikaları için bir alt türü ne olursa olsun artık çok kolay hale geldi arama: UNIONs gerek Yok - sadece SELECT * FROM policies.

Çoğu durumda en uygun olarak sınıf tablo yaklaşım olarak görüyorum.


Bu üç model isimleri Martin Fowler's kitap Patterns of Enterprise Application Architecture gelir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Alan Fullmer

    Alan Fullmer

    3 EYLÜL 2010
  • Sorikan

    Sorikan

    3 ŞUBAT 2008
  • xCraash

    xCraash

    6 Temmuz 2012