Nasıl kaybetmek performans / iyi-tasarım olmadan tamamen özelleştirilebilir bir uygulama (aka veritabanı), inşa etmek?

5 Cevap php

Bir benim web uygulaması tam restyle başında im ve ben güvenilir olabilir iyi bir veritabanı tasarımı hakkında bazı şüpheler var, sorgu-performans ve kullanıcılar tarafından tamamen özelleştirilebilir, aynı zamanda (kullanıcılar alışkanlık veritabanını özelleştirebilirsiniz yapısı, fakat uygulamanın fonksiyonelliğini).

Yani, benim gerçek durum, örneğin, basit bir kullanıcının tablo:

id | name | surname | nickname | email       | phone
1  | foo  | bar     | foobar   | foo@bar.com | 99999

Thats it.

Ama benim müşteri biri belirli bir kullanıcı için, 2 e-posta adreslerini veya telefon numaralarını istiyorum söylüyorlar sağlar.

E kadar şimdi, ben sadece kullanıcıların tablodaki sütunlar ekleyerek bu sorunu çözmek için kullanılır:

id | name | surname | nickname | email       | phone | email_two    | phone_two
1  | foo  | bar     | foobar   | foo@bar.com | 99999 | foo@bar.net  | 999998

Ama yeni uygulamanın sürümü ile bu şekilde cant kullanmak .. ben yapısını düzenlemek için Müşterimizin çağrısına sevmiyorum, bundan sonra mojito içme gibi olacak :)

Yani, ben sadece başka bir tablo ile, insanlar gümrük alanını tanımlayabilirsiniz bir çözüm düşündüm:

id | table_refer | type_field | id_object | value
1  | users       | phone      | 1         | 999998
2  | users       | email      | 1         | foo@bar.net

değişmeden kullanıcıların bir tablo tutmak.

Ama bu şekilde 2 sorunları var:

  1. Biliyorum ne için, ben 1 kullanıcıyı silerseniz otomatik olarak yabancı anahtar kaskad 'table_refer' değeri = kullanıcıları ve id_object sahip ikinci tablodaki tüm satırı silin ki, bu şekilde Foreigns tuşunu kullanmak için hiçbir olasılık = var users.id. Tabii, bazı tetikleyiciler işlevini kullanabilirsiniz edeceğiz, ama güvenilirlik bazı kaybedersiniz.
  2. Ben veritabanını sorgulamak gerekir olduğunda, ön ben de option_table .. tüm ... etek kontrol etmek gerekir, 'foo@bar.net' maç kullanıcılar almak, ve bu benim kod kompleksi yapacak ve daha az güvenilir ve dağınık birçok kullanıcıların tablo alışkanlık 'option_table' ile 'genişletilmiş' tek kişi olduğunu varsayarak .. katılır, gri bir görünüm gibi görünüyor.

Amacım ihtiyaç duydukları gibi, benim müşteriler varsayarak, uygulama (kullanıcılar, ürün, fatura, baskı görünümleri, fotoğraflar, haberler, vs ..) hemen hemen tüm nesne için, gibi birçok özel alanlar ekleyerek izin olduğunu, bu tablonun en (3 masa ve kalıtım gerarchy ile, 2 tablodaki parçalı) bölümlenmiş olacaktır.

You think my way can be good, do you know some other better, or am i in a big mistake? Please, every suggest is gold now!

EDIT:

What i'm lookin for could be simplifyed ith the 'articles-custom-fields' in wordpress blogs. My goal is to let the user to define new fields that he needs, for example, if my users table is the one above, and a customer need a field that i havent prevent, like the web-site url, he must be able to add it dinamically, without edit the database structure, but just the data.

Ben 2 ° tablo (her nesne için maibe 1) iyi bir çözüm olabilir diye düşünüyorum, ama yine de daha iyi yollar için bekliyorum!

5 Cevap

Ben benzer bir soruya benim Answer dediği gibi, "Veritabanı Tasarımı Sert." Siz verileri almak için ilgili JOIN-ing ve göndergesel ekstra çaba ile, tablolar normalize ve kendi tabloları içine telefon numaralarını ve e-posta adreslerini getirerek, sizin için daha iyi olduğu konusunda karar vermek zorunda olacak bütünlük, veya bir numara sizin tabloda n e-posta ve telefon alanlar ve bu gerektirdiği "veri messiness" sahip.

Veritabanı tasarımı her zaman değiş bir dizi. Belki hayır "One True Cevap ™" Orada bazı prototipler kadar bodge ve bazı profilleme yapmak vb, tüm açılardan bakmak gerekir.

Sizin Önerilen model iki veritabanı kalıplarından oluşur: bir entity-attribute-value table ve polymorphic association.

Varlık-öznitelik-değer performans ve veri bütünlüğü departmanında hem de bazı oldukça büyük sorunları var. Sorgularda ek niteliklere erişmek için ihtiyacınız yoksa, o zaman bazı standart serileştirme (json, XML) bir metin alanına öznitelik değeri haritalama serileştirebilirsiniz. Veritabanı tasarım açısından "saf", ama muhtemelen iyi bir pragmatik bir seçim, sen tradeoffs farkında olduğunu verilmemiştir. Postgres üzerinde de dize yalnızca değerlerin sınırlaması kabul edilebilir ise, sorgularda kullanışlı hale getirmek için anahtar-değer çiftleri depolamak için hstore contrib modülünü kullanabilirsiniz.

Polimorfik dernek için, bir dernek bir tablo sunarak tutarlılığını alabilirsiniz:

users                attrib_assocs       custom_attribs
-----                -------------       --------------
attrib_assoc_id -->  id             <--  assoc_id
...                  entity_type         field
                                         value

Biraz daha bütünlük elde etmek için, ayrıca ENTITY_TYPE 'kullanıcı' eşittir, kullanıcıların tablo üzerinde birincil anahtar ve ilgili yabancı anahtarları ve onay kısıtlaması ENTITY_TYPE ekleyin.

Eğer bu şekilde yaparsanız sorguları tüm katılmak ve performans öldürmek ve basit sorgular sert yapacak sütun, ve sert sorguları çok zor table_refer kullanmak zorunda olacak.

Lütfen birden fazla e-posta istiyorsanız birçok satır olabilir bu yüzden, başka bir tabloya dışarı e-posta ayrıldı.

Sadece tek bir kategori - Sen genellikle tüm verileri görüntülemek için ihtiyaç var bu son derece özelleştirilebilir ve zengin uygulamalarında AJAX vb kullanarak, talep üzerine (kullanıcı için e-posta listesi gibi) ek veri istemek için uygulama tasarım olabilir.

Özel Eğer field_types(id, name, datatype) tablo oluşturabilirsiniz kayıtları ve bir tablo custom_fields(user_id, field_type_id, value) saklamak, ve sonra bu gibi smth seçmek için:

SELECT * FROM custom_fields WHERE user_id=XXX AND field_type_id IN (X,Y,Z).

şimdi sen 1, hızlı bir sorgu, kategorilere bölünmüş alanlarda veri almak ve performans sorunları olmadan kod ile kendi veri türleri kendi değerlerini ayrıştırmak.

Ben postgresql özellikleri hakkında emin değilim, ama sen gerçekten aramak istemiyorum DB derece özelleştirilebilir veri yapılarını istiyorsanız, s erializing the data to a LOB bir seçenektir.

Aslında bu ASP.NET kullanıcı ayarları başına Kişiselleştirme, varsayılan olarak çalışır yoludur.

Eğer herhangi bir nedenle alanları aramak isterseniz ben bu yaklaşımı tavsiye etmiyoruz.