Soru SQL Server veritabanında bir tek satırlık yapılandırma tablosu kullanma. Kötü bir fikir?


Bir alışveriş sepeti uygulaması geliştirirken, yöneticinin tercihlerine ve gereksinimlerine göre ayarları ve yapılandırmaları kaydetmem gerektiğini buldum. Bu bilgi şirket bilgilerinden, Kargo hesabı kimliklerinden, PayPal API anahtarlarından, bildirim tercihlerinden vb. Herhangi bir şey olabilir.

İlişkisel veritabanı sisteminde tek bir satırı depolamak için bir tablo oluşturmak son derece uygunsuz görünüyor.

Bu bilgiyi saklamak için uygun yol nedir?

Not: DBMS'm SQL Server 2008 ve programlama katmanı ASP.NET (C #) ile uygulanmaktadır.


125
2018-02-19 23:39


Menşei




Cevaplar:


Geçmişte bu iki yolu yaptım - tek sıralı bir tablo ve bir anahtar / değer çifti tablosu - ve her yaklaşıma pozitif ve negatifler var.

Tek sıra

  • pozitif: değerler doğru tipte saklanır
  • Olumlu: Kodla başa çıkmak daha kolaydır (yukarıdakilerden dolayı)
  • pozitif: her bir ayar için ayrı ayrı varsayılan değerler verilebilir
  • negatif: yeni bir ayar eklemek için şema değişikliği gerekiyor
  • negatif: çok sayıda ayar varsa tablo çok geniş olabilir

Anahtar / Değer Çifti

  • pozitif: yeni ayarların eklenmesi bir şema değişikliği gerektirmez
  • pozitif: tablo şeması dar ve yeni ayarlar için ekstra satır kullanılıyor
  • negatif: her ayarın aynı varsayılan değeri vardır (boş / boş?)
  • negatif: herşey dizgiler olarak saklanmalıdır (örneğin, nvarchar)
  • negatif: Koddaki ayarlarla uğraşırken, bir ayarın ne olduğunu ve ne tür bir döküm olduğunu bilmek zorundasınız.

Tek satır seçeneği, çalışmak için en kolay olanıdır. Bunun nedeni, her ayarı veritabanında doğru türde depolayabilmeniz ve arama türlerinin yanı sıra arama anahtarlarını kodda saklamanız gerekmemesidir.

Bu yaklaşımı kullanmakla ilgilendiğim bir şey, "özel" tek satırlık ayar tablosunda birden fazla satır geçirmekti. Bunu (SQL Server'da) aştım:

  • varsayılan bir 0 değeriyle yeni bir bit sütunu eklenmesi
  • Bu sütunun 0 değerine sahip olduğundan emin olmak için bir kontrol kısıtlaması oluşturmak
  • bit sütununda benzersiz bir kısıtlama yaratmak

Bu, tabloda yalnızca bir satır bulunabileceği, çünkü bit sütununun 0 değerine sahip olması gerektiği, ancak benzersiz kısıtlama nedeniyle yalnızca bu değerle bir satır olabileceği anlamına gelir.


164
2018-02-20 00:13



LOB uygulamasında tek sıralı şeyi yaparız. Değerler, bunların uygulamada kullanımını çok daha kolay hale getiren doğru tiptedir. Şemamız, uygulama ile birlikte sürümlendirilmiştir, bu nedenle yapılandırma ayarlarında bir değişiklik, herhangi bir uygulama revizyonu gibi yönetilir. - DaveE
Tek sıra pozitif: Bazı sütunlarda FK tanımlı olabilir! - wqw
Hangi sütunun değer türünde bir değere sahip olduğunu belirlemek için her zaman bir tür tanımlayıcısı olan bir anahtar / değer çifti yapabilirsiniz. Bu size her iki dünyanın en iyisini sunar ve ihtiyacınız olduğunda değer elde etmek için depolanmış bir proc kullanabilirsiniz. - Middletone
+1, tabloyu tek bir satıra sınırlama fikri için teşekkürler - Jeff Ogata
Tek sıralı çözümü uyguladıktan sonra gününüze gerçekten zarar verebilecek bir şey, daha sonra “her değerin değiştiğini ve kimin değiştiğini izlemeye devam edelim…” ile görevlendirildiklerinizdir. - Dave Mateer


Bilgi türü ve bilgi değeri için bir sütun içeren bir tablo oluşturmanız gerekir (en azından). Bu şekilde, her yeni bilgi eklendiğinde yeni sütunlar oluşturmak zorunda kalmazsınız.


9
2018-02-19 23:44



Basit ve temiz. Sadece oradaki anahtar değer çiftlerinin bir listesiyle çalışın. Varsayılan değerler hakkında biraz düşünmek isteyebilirsiniz, kullanım içeriğine bağlıdır ... - Paul Kohler
Yeni sütunlar oluşturmak neden sorun? Geliştiricilerin SQL şemalarını güncellemeyle ilgili politik sorunlar nedeniyle kaçınmaları gereken durumlar olduğunu biliyorum, ancak bu konuya değinilmiyor. - finnw


Tek bir satır iyi çalışır; Güçlü türlere bile sahip olacak:

show_borders    bit
admin_name      varchar(50)
max_users       int

Bir dezavantaj, şema değişikliği gerektirmesidir (alter table) yeni bir ayar eklemek. Bir alternatif normalleştirilir, burada bir tabloyla sonuçlanırsınız:

pref_name       varchar(50) primary key
pref_value      varchar(50) 

Bu zayıf türlere (her şey bir varchar) sahiptir, ancak yeni bir ayar eklemek sadece bir satır ekleyerek, sadece veritabanı yazma erişimi ile yapabileceğiniz bir şey.


6
2018-02-20 00:06





Şahsen, eğer işe yarayan buysa, onu tek bir sıra halinde depolarım. Bir SQL tablosunda saklamak için Overkill? Muhtemelen, ama bunu yaparken gerçek bir zarar yoktur.


4
2018-02-19 23:57





Normalleştirilmiş yaklaşımda yeni bir yapılandırma parametresi eklerken şemayı değiştirmeniz gerekmez, ancak muhtemelen yeni değeri işlemek için kodunuzu değiştirmeye devam edersiniz.

Dağıtımınıza bir "alter tablosu" eklemek, tek satır yaklaşımının sadeliği ve tür güvenliği için büyük bir zorunluluk gibi görünmüyor.


3
2018-03-22 13:48





Tahmin ettiğiniz gibi ve en basit durumlar haricinde, tüm konfigürasyon parametrelerini tek bir sıraya koymak birçok dezavantaja sahiptir. Bu kötü bir fikir ...

Yapılandırmayı ve / veya kullanıcı tercih türünü depolamanın uygun bir yolu XML’de. Birçok DBMS, XML veri türünü destekler. XML sözdizimi, bu yapılandırma geliştikçe "dili" ve yapılandırmayı açıklayan yapıyı harcamamıza olanak tanır. XML'in bir avantajı, hiyerarşik yapıya yönelik örtük desteğidir; örneğin, bir dizi sonek ile isimlendirmek zorunda kalmadan, küçük yapılandırma parametreleri listelerinin depolanmasını sağlar. XML formatının olası bir dezavantajı, bu verilerin aranması ve genel olarak modifiye edilmesi diğer yaklaşımlar kadar basit değildir (karmaşık olmayan, basit / doğal olmayan)

İlişkisel modele daha yakın kalmak istiyorsanız, Varlık Öznitelik Değeri modeli Muhtemelen ihtiyacınız olan şeydir, burada bireysel değerler tipik olarak aşağıdaki gibi bir tabloda saklanır:

EntityId     (foreign key to the "owner" of this attribute)
AttributeId  (foreign key to the "metadata" table where the attribute is defined)
StringValue  (it is often convenient to have different columns of different types
IntValue      allowing to store the various attributes in a format that befits 
              them)

AttributeId, her olası özniteliğin (durumunuzdaki "yapılandırma parametresi") tanımlandığı bir tablonun yabancı bir anahtarıdır.

AttributeId  (Primary Key)
Name
AttributeType     (some code  S = string, I = Int etc.)
Required          (some boolean indicating that this is required)
Some_other_fields   (for example to define in which order these attributes get displayed etc...)

Sonunda EntityId, bu çeşitli özniteliklerin "sahibi olan" bazı varlıkları tanımlamanıza izin verir. Sizin durumunuzda, bir UserId olabilir ya da yönetmek için sadece bir konfigürasyonunuz varsa sadece örtük olabilir.

Uygulama geliştikçe, olası yapılandırma parametrelerinin büyümesine izin vermenin yanı sıra, EAV modeli, "meta verileri" yani Özniteliğin kendileriyle ilgili verileri veri kümelerine yerleştirir, böylece yaygın olarak görülen sütun adlarının tüm kodlamasının önüne geçilir. Konfigürasyon parametreleri tek bir satırda saklandığında.


3
2018-02-20 00:03



Bir yapılandırma tablosunun çoğu kullanımı için overkill gibi geliyor. - JerryOL
Bence bu yaklaşımın arkasındaki genel fikir harika. Ama neden XML? Sadece JSON veya YAML gibi basit bir veri değişim formatı seçin ve diğer varyasyonların her ikisinden de avantajlara sahip olabilirsiniz. - schlamar
EAV ilişkiseldir ancak normalleştirilmemiştir. Bunun için kesinlikle kullanım durumları vardır (örneğin, ORM sistemleri bunlara bayılıyor gibi görünmektedir), ancak meta verilerinin EAV için veritabanında yer aldığı argümanı onu kullanmak için ikna edici bir sebep değildir. Tüm RDBMS, sistem tablolarında her zaman bulabileceğiniz meta verileri içerir, bu nedenle tek satırlık tablolarda ayrıca veritabanında meta veriler bulunur. Sabit kodlanmış sütun adları da bir sorun değil. Varlıklar ve öznitelikler için anahtarlar kullanırsanız, bunları tanımlayan başka bir yerde kodlanmış bir arama tablosu (veya sunum katmanınızda daha da kötüsü) vardır. - Davos


Bir Anahtar ve Değer çifti, yapılandırma ayarlarını depolayabilen bir .Net App.Config dosyasına benzer.

Yani, değerini almak istediğinizde şunları yapabilirsiniz:

SELECT value FROM configurationTable
WHERE ApplicationGroup = 'myappgroup'
AND keyDescription = 'myKey';

2
2018-05-02 22:06