Hata izleyicilerinde, müşteri kaynak yönetiminde ve benzer iş araçlarında sıkça bulunan "kullanıcı tanımlı alanlara" ulaşmaya başladığınızda, bunların bajillion alanlarına sahip bir tablo ile desteklenmemeleridir (eğer öyleyse, muhtemelen Kendi).
Bunun yerine, var olan Öznitelik Değeri tablosu tasarımları ve geçerli öznitelikleri yönetmek için ilişkili yönetim aracı bulunur.
Aşağıdaki tabloyu düşünün:
+ -------------- +
| şey |
| -------------- |
| id |
| türü |
| desc |
| attr1 |
| attr2 |
| attr3 |
| attr4 |
| attr5 |
+ -------------- +
Bu, birkaç özellik ekledikten sonra. Okuyormuş attr1
gibi davranmak yerine, artist
ya tracks
da genre
ya da her şeyin niteliği ne olursa olsun. Ve 5 yerine, ya 50 olsaydı. Açıkça bu yönetilemez. Ayrıca, yeni bir alanı işlemek için modelin güncellenmesini ve uygulamanın yeniden dağıtılmasını gerektirir. Uygun değil.
Şimdi aşağıdaki tablo yapısını düşünün:
+ -------------- + + --------------- + + ------------- +
| şey | | thing_attr | | attr |
| -------------- | | --------------- | | ------------- |
| id | <--- + | thing_id (fk) | +> | id |
| türü | | attr_id (fk) | + - + | adı |
| desc | | değeri | | |
+ -------------- + + --------------- + + ------------- +
Temel alanları ile her şeye sahipsiniz. İki tablonuz daha var. Özniteliklere sahip biri. Her alan attr
tablodaki bir satırdır . Ve sonra masa ve masa thing_attr
ile ilgili bir çift yabancı anahtar var . Ve sonra, bu varlık için alanın değeri ne olursa olsun depoladığınız bir değer alanı vardır.thing
attr
Ve şimdi attr tablosunun çalışma zamanında güncellenebileceği ve genel uygulamaya önemli bir etki yapmadan anında yeni alanların eklenebileceği (veya kaldırılabileceği) bir yapınız var.
Sorgular biraz daha karmaşıktır ve doğrulama da daha karmaşık hale gelir (korkak saklı yordamlar veya tüm istemci tarafı). Tasarımda bir takas.
Ayrıca, bir gün bir geçiş yapmanız gereken ve şimdi ilk dağıttığınız şemadan yarım düzine kadar daha fazla özellik olduğunu bulmak için uygulamaya geri döndüğünüz durumu da düşünün. Bu, doğru şekilde kullanıldığında Varlık Özellik Değeri tablosunun daha temiz olabileceği çirkin geçişler ve yükseltmeler yapar. (Her zaman değil, ama olabilir.)
Çalışma zamanında şemayı değiştirmenin herhangi bir dezavantajı var mı? Kullanıcı bir şeyin yeni bir niteliğe ihtiyacı olduğunu düşünüyorsa, tabloya dinamik olarak bir sütun eklensin mi?
Eğer nosql veritabanının uygun lezzeti ile çalışıyorsanız, muhtemelen bunu yapabilirsiniz (bunun için nosql'in uygun lezzetinin muhtemelen yukarıda açıklanan ilişkisel olanlar için EAV tablosu olan bir anahtar / değer deposu olacağını unutmayın ) çok fazla sorun olmadan. Bununla birlikte , başka bir yerde ayrıntılı olarak açıklanan nosql için tüm tavizlerle birlikte gelir.
Bunun yerine ilişkisel bir veritabanı üzerinde çalışıyorsanız - şemaya sahip olmanız gerekir. Sütunu dinamik olarak eklemek, aşağıdakilerin bazı alt kümelerinin doğru olduğu anlamına gelir:
- Meta-veritabanı programlama yapıyorsunuz. Bu sütunu güzel bir ORM ile o alana temiz bir şekilde eşlemek yerine, muhtemelen
select *
verilerin gerçekte ne olduğunu bulmak için bazı karmaşık kodlar yapıyor ve daha sonra karmaşık bir kod yapıyorsunuz (bkz. Java'nın ResultSetMetaData ) ve ardından bunu bir haritada ( veya başka bir veri türü - ancak koddaki hoş alanlar değil ). Bu, daha sonra geleneksel yaklaşımla sahip olduğunuz adil tip ve yazım güvenliğini ortadan kaldırır.
- Büyük olasılıkla ORM'den vazgeçtiniz. Bu, sistemin işi sizin için yapmasına izin vermek yerine tüm kodlar için ham sql yazdığınız anlamına gelir.
- Temiz yükseltmeler yapmaktan vazgeçtiniz. Müşteri, bir sonraki sürümünüzün de kullandığı bir adla bir alan eklediğinde ne olur? Eşleştirme sitesinde,
hasdate
zaman damgasını saklamak için bir alan eklemek isteyen yükseltme, hasdate
başarılı bir maç için bir boole ile tanımlanmıştı ... ve yükseltme molalarınız var.
- Müşterinin, sorgunuzu da kıran bazı ayrılmış sözcükleri kullanarak sistemi kırmamasına güveniyorsunuz ... bir yerde.
- Kendinizi bir veritabanı markasına bağladınız. DDL farklı veritabanlarının farklıdır. Veritabanı türleri bunun en kolay örneğidir.
varchar2
vs text
ve benzerleri. Sütunu ekleme kodunuz MySQL üzerinde çalışır ancak Postgres veya Oracle veya SQL Server'da çalışmaz.
- Müşteriye verileri gerçekten iyi eklemesi için güveniyor musunuz ? Elbette, EAV ideal olmaktan uzaktır, ancak şimdi geliştiricinin eklemediği bazı yanlış karanlık tablo isimleriniz var, yanlış dizin türüyle (varsa), kodda herhangi bir kısıtlama eklenmediğinde olmak vb.
- Uygulamayı çalıştıran kullanıcıya şema değişikliği ayrıcalıkları verdiniz. DDL yerine SQL ile sınırlı olduğunuzda Little Bobby Drop Tables mümkün değildir (
delete * from students
bunun yerine emin olabilirsiniz , ancak veritabanını gerçekten kötü şekillerde bozamazsınız). Bir kazadan veya kötü amaçlı etkinliklerin patladığı şema erişimiyle yanlış gidebilecek şeylerin sayısı.
Bu gerçekten "yapma" der. Bunu gerçekten istiyorsanız, EAV tablo yapısının bilinen bir deseni veya tamamen bu yapıya adanmış bir veritabanı ile gidin. İnsanların bir tabloda rastgele alanlar oluşturmasına izin vermeyin. Baş ağrıları buna değmez.