2012-03-06 17 views
5

Tüm farklı özelliklere sahip, farklı öznitelik türlerinin olacağı "öğeler" ile ilgili verileri saklamam gerekiyor ve her tür kendi ek özniteliklerine sahip. Bunun genel bir gereklilik olduğunu umuyorum; En iyi uygulama çözümü nedir? SQL Server kullanıyoruz. sahiptirÖğeler ve özel ürünler: Yinelenen sütunlar, ana tablo ve ayrıntı tablosu içeren birden çok tablo veya ...?

  • Fiyatı
  • bizim gerçek verilerde
  • Modeli
  • Sahibi

(Make

Araç:

en uydurma bir örnek verelim , 10-15 ortak sütunu yer alacaktır)

Araç bir araç artı.

  • EngineSize
    • Stil (sedan, spor, vs.)
    • Renk

      Tekne bir Araç numarası artıdır:

      • Deplasman
      • PortOfOrigin

      ... vb. çeşitli şeyler için. Gerçek verilerimizde, her uzmanlık tipi tipik olarak 2-5 sütun ekler; başlamak için 5 tip olacak. Zaman içinde türler ekleyeceğiz, ancak muhtemelen toplamda sadece 3 veya 4 daha fazla (eğer). Ekleme türleri geliştirme gerektirir, bu nedenle son kullanıcılar tarafından nemli-nilly eklenebilir "etiketler" gibi değil. DB ve istemci katmanlarında ve muhtemelen orta kademede de değişiklik yapılmasını gerektirecek bir tür eklemeyi varsayıyoruz. Bu tamamen iyi.

      Tüm öğeler arasında çok fazla sorgu yapacağız (yukarıdaki örnekte araçlar); sadece belirli bir eşya türünün (Araba, Tekne) ayrıntıları hakkında endişeleniriz. Çoğaltılmış sütunlu, arabalar, tekneler, için

      1. Ayrı masalar,:

        bu verileri depolamak için dört yol görüyoruz.

      2. Vehicle verileri içeren bir tablo, ek Car verileri için bir tablo ve ek Boat verileri için bir tablo.
      3. Öğelerin bir tablosu, ek öznitelik için satır içeren ayrı bir öğe öznitelik tablosu. Örneğin, detaylar için yumuşak bir şema.
      4. Yalnızca sütun dışı kodlar tarafından verilen genel sütunlara sahip bir tablo.

      her baktığımızda: yinelenen sütunlarıyla, arabalar, tekneler, için

      1. Ayrı masalar. Ör kabaca: Yeterince

        CREATE TABLE [Cars] (
            [Id] IDENTITY PRIMARY KEY, 
            [Price] DECIMAL (19, 4), 
            [Make] NVARCHAR(200), 
            [Model] NVARCHAR(200), 
            [Owner] INT, 
            [Id] INT PRIMARY KEY, 
            [Style] NVARCHAR(200), 
            [Color] NVARCHAR(200), 
            [EngineSize] DECIMAL(19, 2) 
        ) 
        CREATE TABLE [Boats] (
            [Id] IDENTITY PRIMARY KEY, 
            [Price] DECIMAL (19, 4), 
            [Make] NVARCHAR(200), 
            [Model] NVARCHAR(200), 
            [Owner] INT, 
            [Id] INT PRIMARY KEY, 
            [Displacement] DECIMAL(19, 4), 
            [PortOfOrigin] NVARCHAR(200) 
        ) 
        

        Basit, Otomobil Cars gidip Tekneler Boats gidin. Daha fazla araç türü eklersek, bir tablo ekliyoruz. Başka bir ortak sütun eklersek, geri dönüp tüm araç tablolarına eklememiz gerekir. Genel olarak araçlara yönelik raporlama, tüm tabloların bir sendika görüşüne karşı (Id sütununa dikkat ederek) yapılabilir.

      2. bir Vehicle veri tablosu, ek Car verileri için bir tablo ve ek Boat veriler için bir tablo. Ör kabaca:

        CREATE TABLE [Vehicles] (
            [Id] IDENTITY PRIMARY KEY, 
            [Price] DECIMAL (19, 4), 
            [Make] NVARCHAR(200), 
            [Model] NVARCHAR(200), 
            [Owner] INT, 
            [Type] INT  -- A type ID, e.g. "Car" vs. "Boat" 
        ) 
        CREATE TABLE [Cars] (
            [Id] INT PRIMARY KEY, 
            [Style] NVARCHAR(200), 
            [Color] NVARCHAR(200), 
            [EngineSize] DECIMAL(19, 2) 
        ) 
        CREATE TABLE [Boats] (
            [Id] INT PRIMARY KEY, 
            [Displacement] DECIMAL(19, 4), 
            [PortOfOrigin] NVARCHAR(200) 
        ) 
        

        Yani her Araba Cars içinde Vehicles ve bir bağlantılı üst üste bir satır olurdu. Her Tekne Boats içinde Vehicles ve bir bağlantılı üst üste bir satır olurdu. Daha fazla araç türü eklersek, bir tablo ekliyoruz. Genel olarak araçlara yönelik raporlama, sadece Vehicle tablosuna karşı yapılabilir. Belirli Car veya Boat bir ayrıntılarını al, biz bir birleşim kullanın. öğelerin

      3. Bir tablo, öğenin ayrı bir tablo ek özellik başına bir satır ile bağlıyor. Örneğin, detaylar için yumuşak bir şema. Ör kabaca:

        CREATE TABLE [Vehicles] (
            [Id] IDENTITY PRIMARY KEY, 
            [Price] DECIMAL (19, 4), 
            [Make] NVARCHAR(200), 
            [Model] NVARCHAR(200), 
            [Owner] INT, 
            [Type] INT 
        ) 
        CREATE TABLE [VehicleDetails] (
            [VehicleId] INT, 
            [Name] NVARCHAR(200), 
            [Value] NVARCHAR(MAX) 
        ) 
        

        Yani her Car ("Stil", "Renk" ve "EngineSize" için birer) VehicleDetails içinde Vehicles ve üç sıra bir satır alır. Raporlama büyük ölçüde Vehicle tablosuna karşı yapılır. Ayrıntıları bildirmek hızlı bir şekilde dağılmaya başlar. Yumuşak şemalar çoğunlukla kullanıcı tanımlı veriler etrafında yerlerine sahipler, fakat bunun iyi bir seçenek olmayacağını düşünüyorum. sadece sigara DB koduna göre anlam jenerik sütunları ile

      4. Bir tablo:

        CREATE TABLE [Vehicles] (
            [Id] IDENTITY PRIMARY KEY, 
            [Price] DECIMAL (19, 4), 
            [Make] NVARCHAR(200), 
            [Model] NVARCHAR(200), 
            [Owner] INT, 
            [Type] INT, 
            [Detail01] NVARCHAR(MAX), 
            [Detail02] NVARCHAR(MAX), 
            [Detail03] NVARCHAR(MAX), 
            [Detail04] NVARCHAR(MAX), 
            [Detail05] NVARCHAR(MAX), 
            [Detail06] NVARCHAR(MAX), 
            [Detail07] NVARCHAR(MAX), 
            [Detail08] NVARCHAR(MAX), 
            [Detail09] NVARCHAR(MAX), 
            [Detail10] NVARCHAR(MAX) 
        ) 
        

        Yani Araba Detail02 için, Detail01 için Renk Stil atamak olacaktır verileri ve EngineSize Detail03 için; Tekneler için, biz Detail02 içinde Detail01 ve PortOfOrigin içinde Deplasman koyardım. Benzer şekilde, son kullanıcı tanımlı şemalarla bunun için bir yer olabilir, ancak DB yapısını kontrol edebildiğiniz zaman bunun iyi bir yanıt olmayacağını tahmin ediyorum.

    +0

    İlişkisel veritabanı kesinlikle gerekli midir? Bu model için bir belge veritabanını kullanmak daha uygun olacaktır. – Oded

    +0

    @Oded: İyi soru. Bu durumda, evet, en azından şimdilik, RDBMS'de saklanmalıdır. Bu tür gereksinimlerden yeterince yararlanacak olursak, belki RDBMS'yi bir belge veritabanıyla artırırız. –

    +0

    "Zamanla daha fazla tür ekleyeceğiz" - bana seçenek 2'yi gösterir. Yumuşak bir şema (EAV modeli), genel sütunlardan biri olan bir başlatıcı değildir. – Oded

    cevap

    6

    Duruma göre.

    Yaklaşım 1, en nitelikleri türlerinin çoğu için ortak olacak durumlar için en iyisidir.

    Yaklaşım 2, çoğu özniteliğin çoğu tür için ortak olacağı durumlar için en iyisidir.

    Yaklaşım 3 temel olarak öznitelik öznitelikleri işlemek için bir Varlık-Öznitelik Değeri yaklaşımı ile yaklaşım 1 'dir.Bu yaklaşım, çoğu özniteliğin çoğu tür için ortak olacağı durumlar için en iyisidir ve ek özniteliklerin gerekeceğini tahmin etmek zordur - bu, kullanıcı tarafından oluşturulan alanlar gerektiren durumlarda oldukça yaygındır.

    Yaklaşım 4 her durumda iyi bir fikir değil - saf Entity-Attribute-Value - Yaklaşımı değişmezlik korurken 1.

    da başka bir olası yaklaşım vardır, kod katmanına meta katmanından anlamsal içeriği kaldırır yaklaşım (esasen 3 ve 4 numaralı yaklaşımların bir karışımı). Bu, bir RDBMS'de uygulandığında üretilen karmaşıklık ve düşük performans nedeniyle genellikle bir anti-desen olarak kabul edilir. Bununla birlikte, mümkün olan tek yaklaşımın olduğu bazı durumlar vardır - öncelikli olarak varlık ilişkilerinin önceden bilinmediği durumlar.

    +0

    Teşekkürler, çok makul. Bu bilgiyi şu soruya ekledim: * "Size bir fikir vermek için, 10-15 ortak özelliklerin (örneğin, Taşıt verileri) ve herhangi bir özel türün (Araba, Tekne) sırasına göre olacağını görürüz. 2-4 ekleyecektir. * * Bu seçenek 1'e doğru eğilmenizi önerir. –

    +0

    @ T.J.Crowder - Ne kadar ek tür beklediğinizi düşünmeniz gerektiğini söyleyebilirim. Eğer küçük bir miktar ise, 1'e kadar yalın, eğer büyük bir miktar, 2'ye düştüğünde. – Oded

    +0

    @Oded: Teşekkürler, sorudan dışarıda bıraktığım bir şeyi vurguladınız. :-) ekledim. (Başlamak için beş tip, muhtemelen zaman içinde üç veya dörtten fazla bir şey değil.) –

    İlgili konular