Birçok farklı etkinlik türünü bir siteyle ilişkilendiren bir uygulamayı devralmıştım. Yaklaşık 100 farklı aktivite türü vardır ve her biri farklı 3-10 alan kümesine sahiptir. Ancak, tüm faaliyetlerin en az bir tarih alanı (tarih, başlangıç tarihi, bitiş tarihi, planlanan başlangıç tarihi vb. Herhangi bir kombinasyonu olabilir) ve bir sorumlu kişi alanı olabilir. Diğer tüm alanlar büyük ölçüde değişiklik gösterir ve bir başlangıç tarihi alanı mutlaka "Başlangıç Tarihi" olarak adlandırılmaz.
Her aktivite türü için bir alt tür tablosu oluşturmak, 100 farklı alt tür tablosu olan bir şema ile sonuçlanır; Bu sorunun geçerli çözümü, etkinlik değerlerini anahtar / değer çiftleri olarak depolamaktır. Bu, mevcut sistemin karşısına geçmek için büyük ölçüde basitleştirilmiş bir şemadır.
Her Faaliyetin birden fazla Etkinlik Alanı vardır; her Sitede birden çok Etkinlik vardır ve SiteActivityData tablosu her SiteActivity için KVP'leri depolar.
Bu, (web tabanlı) uygulamayı kodlamayı çok kolaylaştırır, çünkü gerçekten yapmanız gereken tek şey belirli bir etkinlik için SiteActivityData'daki kayıtlar üzerinde döngü yapmak ve bir forma her satır için bir etiket ve giriş denetimi eklemektir. Ancak birçok sorun var:
- Bütünlük kötüdür; SiteActivityData öğesine etkinlik türüne ait olmayan bir alan koymak mümkündür ve DataValue değişken bir alandır, bu nedenle sayıların ve tarihlerin sürekli olarak yayınlanması gerekir.
- Bu verilerin raporlanması ve geçici olarak sorgulanması zor, hataya açık ve yavaştır. Örneğin, belirli bir aralıkta Bitiş Tarihi olan belirli bir türdeki tüm etkinliklerin bir listesini almak için pivotlar ve tarihlere döküm varcharları gerekir. Rapor yazarları bu şemadan nefret ediyor ve onları suçlamıyorum.
Aradığım şey, neredeyse hiç alanı olmayan çok sayıda etkinliği raporlamayı kolaylaştıracak şekilde saklamanın bir yoludur. Ne kadar şimdiye kadar geldi aktivite verileri sözde noSQL formatında saklamak için XML kullanmaktır:
Etkinlik tablosu, ActivityField tablosuna olan ihtiyacı ortadan kaldırarak her etkinlik için XSD içerir. SiteActivity, anahtar / değer XML'i içerdiğinden, bir sitenin her etkinliği artık tek bir satırda olacaktır.
Bir etkinlik böyle bir şeye benzeyecekti (ama tam olarak etmedim):
<SomeActivityType>
<SomeDateField type="StartDate">2000-01-01</SomeDateField>
<AnotherDateField type="EndDate">2011-01-01</AnotherDateField>
<EmployeeId type="ResponsiblePerson">1234</EmployeeId>
<SomeTextField>blah blah</SomeTextField>
...
Avantajları:
- XSD, XML'yi doğrular, veritabanı düzeyinde bir sayı alanına bir dize koymak gibi hatalar yakalar, her şeyi varchar'ta depolayan eski şema ile imkansız olan bir şey.
- Web formlarını oluşturmak için kullanılan KVP'lerin kayıt kümesi kullanılarak kolayca çoğaltılabilir
select ... from ActivityXML.nodes('/SomeActivityType/*') as T(r)
- XML'in bir xpath alt sorgusu, pivot kullanmadan başlangıç tarihi, bitiş tarihi vb. İçin sütunlara sahip bir sonuç kümesi oluşturmak için kullanılabilir.
select ActivityXML.value('.[@type=StartDate]', 'datetime') as StartDate, ActivityXML.value('.[@type=EndDate]', 'datetime') as EndDate from SiteActivity where...
Bu iyi bir fikir gibi mi görünüyor? Bu kadar çok sayıda farklı özellik kümesini depolamanın başka yollarını düşünemiyorum. Sahip olduğum bir başka düşünce, mevcut şemayı tutmak ve bir veri ambarında daha kolay sorgulanabilir bir şeye dönüştürmekti, ancak daha önce hiç bir yıldız şeması tasarlamamıştım ve nereden başlayacağımı bilmiyordum.
Ek soru: Bir etiketi XSD'de tarih veri türüne sahip olarak tanımlarsam xs:date
, SQL Server bunu tarih değeri olarak dizine ekleyecek mi? Ben tarihe göre bir tarih değerine döküm ve bir dizin kullanma şansını darbe gerekir sorgu tarafından endişe duyuyorum.