Açıkladığınız tür hiyerarşisini modellemek için en az şu beş seçeneğiniz vardır:
Tek Tablo Devralma : tüm Ürün türleri için tek bir tablo, tüm türlerin tüm niteliklerini depolamak için yeterli sütun. Bu , herhangi bir satırda çoğu NULL olan birçok sütun anlamına gelir .
Sınıf Tablosu Devralma : Tüm ürün türlerinde ortak olan öznitelikleri saklayan Ürünler için bir tablo. Ardından, ürün türü başına bir tablo, söz konusu ürün türüne özgü nitelikleri depolar.
Beton Tablo Kalıtım : Ortak Ürün özellikleri için tablo yok. Bunun yerine, ürün türü başına bir tablo, hem yaygın ürün özelliklerini hem de ürüne özgü özellikleri depolar.
Serialized LOB : Tüm ürün türlerinde ortak olan özellikleri depolayan Ürünler için bir tablo. Fazladan bir sütun, yarı yapılandırılmış verilerden oluşan bir BLOB'u XML, YAML, JSON veya başka bir biçimde saklar. Bu BLOB, her ürün türüne özgü özellikleri depolamanızı sağlar. Bunu tanımlamak için Cephe ve Memento gibi süslü Tasarım Desenleri kullanabilirsiniz. Ancak, SQL içinde kolayca sorgulanamayan nitelikler bloğuna bakılmaksızın; tüm blob'u uygulamaya geri getirip orada sıralamanız gerekir.
Varlık Öznitelik Değeri : Ürünler için bir tablo ve öznitelikleri sütunlar yerine satırlara döndüren bir tablo. EAV ilişkisel paradigma açısından geçerli bir tasarım değildir, ancak birçok kişi yine de kullanır. Bu, başka bir cevapta belirtilen "Özellikler Kalıbı" dır. Bazı tuzaklar için StackOverflow'daki eav etiketi ile ilgili diğer soruları görün .
Bu konuyla ilgili daha fazla yazdım, Genişletilebilir Veri Modelleme .
EAV hakkında ek düşünceler: Birçok kişi EAV'yi destekliyor gibi görünse de, sevmiyorum. En esnek çözüm ve bu nedenle en iyisi gibi görünüyor. Ancak TANSTAAFL atasözünü unutmayın . İşte EAV'in bazı dezavantajları:
- Bir sütunu zorunlu hale getirmenin bir yolu (eşdeğeri
NOT NULL
).
- Girişleri doğrulamak için SQL veri türlerini kullanmanın bir yolu yoktur.
- Özellik adlarının tutarlı bir şekilde yazıldığından emin olmanın bir yolu yoktur.
- Herhangi bir özelliğin değerlerine yabancı anahtar koymanın bir yolu yoktur; örneğin, bir arama tablosu için.
- Geleneksel bir tablo düzeninde sonuçları getirmek karmaşık ve pahalıdır, çünkü
JOIN
her bir özellik için birden fazla satırdan özellik almak için yapmanız gerekir .
EAV'ın sağladığı esneklik derecesi, diğer alanlarda fedakarlık gerektirir, muhtemelen kodunuzu orijinal sorunu daha geleneksel bir şekilde çözmek için olduğundan daha karmaşık (veya daha kötü) yapar.
Ve çoğu durumda, bu esnekliğe sahip olmak gereksizdir. OP'nin ürün türleri hakkındaki sorusunda, ürüne özgü özellikler için ürün türü başına bir tablo oluşturmak çok daha basittir, bu nedenle en azından aynı ürün türündeki girişler için uygulanan bazı tutarlı yapılarınız vardır.
EAV'ı yalnızca her satırın potansiyel olarak farklı özelliklere sahip olmasına izin verilmesi gerekiyorsa kullanırım . Sonlu bir ürün türü kümeniz olduğunda, EAV aşırıya kaçar. Sınıf Tablosu Kalıtım benim ilk tercihim olurdu.
Güncelleme 2019: JSON'u "birçok özel özellik" sorununa çözüm olarak kullanan insanların sayısı ne kadar fazla olursa, bu çözümü o kadar az beğenirim. Sorguları desteklemek için özel JSON işlevlerini kullanırken bile sorguları çok karmaşık hale getirir . Normal satırlarda ve sütunlarda depolamak yerine JSON belgelerini depolamak çok daha fazla depolama alanı gerektirir.
Temel olarak, bu çözümlerin hiçbiri ilişkisel bir veritabanında kolay veya verimli değildir. "Değişken niteliklere" sahip olma fikri temel olarak ilişkisel teori ile çelişmektedir.
Bunun nedeni , uygulamanız için en az kötü olan çözümlerden birini seçmeniz gerektiğidir . Bu nedenle, bir veritabanı tasarımı seçmeden önce verileri nasıl sorgulayacağınızı bilmeniz gerekir. "En iyi" bir çözüm seçmenin bir yolu yoktur, çünkü belirli bir uygulama için çözümlerden herhangi biri en iyisi olabilir.