Birimleri veritabanında saklamanın en iyi yolu


21

Bir ya da başka bir miktarı temsil eden yüzlerce sütuna sahip büyük (SQLServer) bir veritabanını miras aldım. Bu değerlerin birimleri (örneğin, "galon", "inç", vb.) Extended Properties'in MS_Description alanında depolanır. Bu bilgileri saklamanın daha iyi bir yolu olup olmadığını merak ediyorum. Belgeleme amaçları için iyi olduğunu düşünüyorum, ancak bu verilere dayanarak sağlam birim dönüşüm hesaplamaları yapmak zor olurdu. Bu noktada istilacı bir değişiklik yapmaya hazır değilim, ancak bunu yapma şansım olursa, bu konuda önerilen En İyi Uygulama nedir? Başımın üstündeki seçenekler şunları içerebilir:

  • Sütun adını dahil edilen birimlerle değiştirin (örneğin, "TotalVolumeInGallons". Bu, bilgileri biraz daha hazır hale getirir, ancak yine de benim için zayıf görünüyor.)
  • Her "Miktar" sütununa karşılık gelen ayrı bir "Birimler" sütunu ekleyin (bu sütun nvarchar olabilir VEYA birim dönüşümleri hesaplamayı kolaylaştıracak ayrı bir Birimler tablosuna yabancı bir anahtar olabilir. Öte yandan, birçok sütun veritabanımın boyutunu iki katına çıkarabilirdi - çok fazla gereksiz veri ile.)
  • Genişletilmiş Özellikler'de özellikle birimler için ayrılmış yeni bir alan oluşturun. (Ne yazık ki, bunun Birimler tablosunun yabancı bir anahtarı olabileceğini sanmıyorum.)
  • Gözden kaçtığım başka bir fikir var mı?

GÜNCELLEME: @Todd Everett'in cevabını okuduktan sonra, bana olası bir çözüm geldi, ben de devam edip kendi soruma cevap vereceğim. (Aşağıya bakınız)


En iyi uygulama, uygulama boyunca evrensel ve tutarlı bir şekilde kullanılan tek bir ölçüm sistemine sahip olmaktır. SI, tercih edilen sistem olacaktır. Diğer sistemlerdeki değerler yükleme sırasında veya her kullanıcının tercih ettiği seti seçebileceği sunum katmanında dönüştürülecektir.
Michael Green

Yanıtlar:


12

Yüzlerce sütundan bahsettiğinizden beri bir EAV tasarımını düşünürdüm . Joe Celko buna karşı uyarırken , sizin durumunuzda geçerli olabileceğini düşünüyorum. Tüm "miktarlarınız" sayılar gibi geliyor, bu yüzden Joe'nun anlattığı yayın sorunlarından ve her "değeri" bir dizge haline getirme ihtiyacından kaçınırsınız. Tüm miktarlar tam sayı ise daha iyi çalışacaktır, ancak bazıları ondalıksa da çalışabilir. Ölçü Birimleri göz önüne alındığında, bir adım daha ileri gidebilir ve David Hay tarafından bu makaleye dayanan ve aynı zamanda Veri Modeli Modelleri: Düşüncenin Konvansiyonları adlı kitabında ana hatlarıyla belirtilen “evrensel veri modeli” stil modelini uygulayabilirsiniz .. Bu model, ihtiyaç duyduğunuzda hangi "miktarların" hangi "şeylere" uygulanacağını yapılandırma ek avantajına sahiptir. Sayfa 162'deki kitapta gösterilen ek bir adım, farklı Ölçü Birimleri arasında dönüştürmek için kullanabileceğiniz bir Ölçü Birimi tablosu'dur. İşte bir örnek:

UOM Conversion              

UOM From    UOM To        Cal Step  Operator Factor Constant
Kilograms   Pounds        1         *        2.2
Celsius     Fahrenheit    1         *        1.8
Celsius     Fahrenheit    2         +               32

Bu, Kg'den Lb'ye dönüştürmenin ilk adımın Kg'yi 2.2 ile çarpması olduğunu söylüyor. Bir dönüşümün sabit bir değer içermesi ve birden fazla adım yaratma kabiliyetine sahip olması gerekiyorsa, bir de sabittir. Yani, Celsius deyimini Fahrenheit'e dönüştürürken, Celsius değerini 1.8 ile çarpıp 32'yi eklersiniz. Anahtar UOM'dan, UOM'a ve Hesaplama Adımından olacaktır.

Bu benim 2 sent değerinde. Umarim bu referanslar, mevcut tasarıma yeniden başlama şansını yakalamanız durumunda size düşünce için bazı iyi yemekler verir.


Düşünceleriniz için çok ilginç bazı yemekler için teşekkürler - çok şey öğrendim. Ancak, EAV'ın benim durumumda uygun bir model olduğunu sanmıyorum (önerinizi doğru anlarsam) çünkü 100'lerce sütun olmasına rağmen, hiçbir şekilde seyrek değiller. Bununla birlikte, bu DID ilgili bir fikri ortaya koymaktadır (orijinal yazımdaki GÜNCELLEME bölümüne bakınız).
kmote

Fikriniz bana oldukça iyi geliyor - Sizin belirttiğiniz dışında, onunla ilgili herhangi bir konuyu elimizden düşünemiyorum. Ancak sütunlar yeniden adlandırılabilirse / değiştirilebilirse, bu herhangi bir tasarımda sorun olabilir. İşbirliği eğlenceli olduğunda, fikir, ikimizin de başlamayı düşünmediği bir fikir ortaya çıkar!
Todd Everett,

8

Bütün iş.

İkinci durumda, elma ve portakal ekleyemeyeceğinizi ve bu nedenle verilerin yanlış yorumlamaya tabi olmasının son derece kolay olduğunu unutmayın.

Ayrıca, dönüşümlerin çok güvenli olamayacağına ve yuvarlama hatasına, taşmalara vb. Duyarlı olabileceğine dikkat edin.

Ek olarak, özgül ağırlık ve sıcaklık gibi fiziksel sorunlar vardır. 20 galonluk suyun pound'a dönüştürülmesi, suyun yoğunluğunu bilmenizi gerektirir. Ancak suyun yoğunluğu sıcaklıkla birlikte değişir, bu nedenle ölçüme eşdeğer yoğunluğu veya sıcaklığa benzer şekilde bilmeniz ve bir hacim düzeltme faktörü kullanmanız gerekebilir.

Genişletilmiş özellikler söz konusu olduğunda, bu sadece dokümantasyon için iyidir - dokümantasyon için iyi bir sütun adı daha iyidir. Sütunun ismiyle sabit bir birimde olmasıyla ilgili sorun, ölçü birimlerini değiştirirken kendinize bir köşeye koymanızdır - yeni müşteri varillerde petrol istiyor, galon değil - ve verileri de iyi olduğu için kendi veritabanı, ancak sütun adı şimdi yanıltıcıdır.

Diğer bir seçenek ise kanonik versiyonları değişen orijinal ölçümlere ek olarak sabit birimlerde (yani her zaman kilogram ve metre) saklamaktır. Sabit ünitelerdeki toplu işlemler iyi olmalıdır (örneğin, sıcaklık eklemeyeceğiniz hariç), ancak orijinal ölçümü kaybetmezsiniz.


1
Bahsettiğiniz potansiyel "yanlış yorumlama" tam da bu veritabanının şu andaki mimarisi ile ilgili endişelerimden biri - ve azaltmanın bir yolunu bulmaya çalışıyorum.
kmote

1
sütun adı çözümünün olası dezavantajı hakkında harika bir nokta.
kmote

1
@kmote Bu basit bir problem değil - bireysel işlemlerin farklı orijinal ölçü birimlerinin olabileceği yerlere ait raporlar var, ancak aynı zamanda bir toplam da var - bu da kullanıcı tarafından seçilen bir birime dönüştürüldükten sonra toplam.
Cade Roux,

7

Geçmişte benim için iyi sonuç veren basit bir çözüm, tüm verilerinizi 'temel' birimlerde saklamak. Örneğin, uzunluklar için baz üniteniz milimetre olabilir ve ağırlıklar için baz üniteniz kilogram olabilir. Bu çözüm, halihazırda mevcut değilse, mevcut verilerinizin bazılarının ana üniteye dönüştürülmesine neden olabilir.

Standart ana ünitelerdeki tüm verilere sahip olduğunuzda, şimdi bir sistem çapında bir varsayım olduğundan üniteyi veritabanında saklamaya gerek yoktur. Her birim tipi için gereken görüntülenen birimler (örneğin mm, inç, cm, m uzunlukları gösterilip gösterilmeyeceği), yerel depolamaya kaydedilebilecek bir uygulama / müşteri alanı sorunu haline gelir.

Desteklenen çeşitli birimler arasında dönüştürme için birim dönüştürme tabloları, uygulamanız içinde kodlanabilir, çünkü yeni ölçü birimleri çok nadiren değişir.

Not: Başka bir konuya ilişkin bir çözüm, zaman damgalarını her zaman 'temel' birim - UTC'de saklamak için bir veritabanında saklamaktır .

Konuyla ilgili bir başka soru-cevap ...


5

Herhangi bir ünite aynı tipte başka bir üniteye dönüştürülebildiğinden

y = ((x + xOffset) * multiplicand / denominator) + yOffset

Birim tiplerini artı bu 4 değeri içeren bir tablo oluşturacağım.

From Unit     To Unit      Unit Type    From Offset    Multiplicand    Denominator    To Offset
'milligrams'  'grams'      'mass'       0              1               1000           0
'grams'      'kilograms'   'mass'       0              1               1000           0
'grams'      'ounces'      'mass'       0              100000          2835           0
'ounces'     'pound'       'mass'       0              1               16             0

Dönüştürme olasılığınız olan tüm ölçümleri listenin her iki tarafına ekledikten sonra, sadece ofsetleri göz ardı ederek ve çoklu kopya ve paydayı ve Ünite ve Üniteyi değiştirerek ters işlemi yaptığınız bir Sorgu gerçekleştirin.

Tüm türler arasına Dönüşüm eklemek için bir çapraz birleştirme Bazı filtrelerle kalan kalan Dönüşümleri ekleyebilirsiniz.


3

@Todd Everett'in cevabını okuduktan sonra, bana bir çözüm geldi, ben de devam edip kendi soruma cevap vereceğim. Ya ben yapacağım düşünüyorum ayrı yaratmaktır ColumnUnitsdört sütunlu, tablo: Schema, Table, Column, UnitsID(UnitsID FK ayrı üzere olduğu UnitsOfMeasureböylece Ölçü ilişkili Birimine verilen herhangi bir sütun haritalama, masanın). Açıkçası, bu fikrin en büyük dezavantajı, geliştiricilerin bir sütunu veya tabloyu yeniden adlandırdıklarında bu tabloyu düzenlemeyi hatırlamaları gerekmesidir [ belki bir DDL tetikleyicisi kullanıyor musunuz? ], aksi takdirde sistem bozulur. Ancak bu tür yeniden adlandırmaların nadir olduğunu ve küçük dükkanların (benim durumumda sadece bir kişi) olduğunu farz edersek, bu mimarinin uygulanabilir olması gerekir. Bunun avantajı, mevcut DB üzerinde hiçbir invaziv değişiklik yapılması gerekmemesi ve değeri, orijinal yazımdaki ikinci seçeneğimin gerektirdiği gibi, satır başına bir kez yerine her sütun için yalnızca bir kez kaydetmem gerekiyor.


ilginç bir bulmaca ... ve sahip olduğunuz ilginç bir fikir. senin fikrin sorgulamak için kolaylaştıracak, ama pek elde edecek görünmüyor. Referans verilerini başka bir yere taşıdınız. Beni bu tasarım hakkında en çok ne rahatsız ediyor
Sir Swears-a-lot

... bir öğenin daha fazla özelliği varsa, yine de daha fazla sütun eklemeniz gerekir. bu nedenle @todd everett'in bir eav tasarımı önerisini beğendim.
Sir Swears-a-lot
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.