Çılgınca farklı tuşlarla anahtar / değer çifti gruplarını verimli bir şekilde depolama


9

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.

resim açıklamasını buraya girin

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:

resim açıklamasını buraya girin

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.


Raporlara ait verilerin ne kadar güncel olması gerekir? Raporlar üretime çarpacak mı?
James Anderson

Çoğu rapor şimdi bir veri ambarına çarptı (bu gerçekten bir DW değil, esasen üretim işlem şemasının bir kopyası ve diğer veritabanlarından alınan tablolar ve tablolar eklendi). Güncel olmayan bir güne ait raporlar almak kabul edilebilir, ancak canlı olması bir bonus olacaktır.
Paul Abbott

Tarlalarda ne kadar çakışma var? On alan 100 alt türü de kapsıyor mu yoksa yaklaşık 500 farklı alan var mı?
Tüm

72 alan ve 75 etkinlik türü vardır. 30 alan yalnızca bir etkinlik tarafından kullanılırken, geri kalanların çoğu 5-10 etkinlik tarafından kullanılır. Yaklaşık 30 farklı etkinlik tarafından kullanılan bir avuç alan var. Çoğunlukla, faaliyetler arasında çok fazla ortaklık yoktur.
Paul Abbott

Yanıtlar:


7

Aradığım şey, neredeyse hiç alanı olmayan çok sayıda etkinliği raporlamayı kolaylaştıracak şekilde saklamanın bir yoludur.

İlk yorum yapmak için yeterli temsilcisi yok, işte başlıyoruz!

Birincil amaç rapor veriyorsa ve bir DW'niz varsa (yıldız şeması olmasa bile) bunu bir yıldız şemasına almayı denemenizi tavsiye ederim. Yararları hızlı ve basit sorgulardır. Dezavantajı ETL'dir, ancak zaten verileri yeni bir tasarıma taşımayı düşünürsünüz ve ETL'yi yıldız şemasına taşımanız, bir XML sarma çözümünden daha kolay ve inşa edilebilir (ve SSIS, SQL Server lisansınıza dahildir). Ayrıca tanınmış bir raporlama / analiz tasarımı sürecini başlatır.

Peki bunu nasıl yapacağınız ... Görünüşe göre Factless Fact olarak bilinen bir şeye sahipsiniz . Bu, ilişkili bir ölçüsü olmayan (satış fiyatı gibi) bir etkinliği tanımlayan özelliklerin kesişimidir. Etkinliklerinizin bir kısmı veya tamamı için tarihleriniz var mı? Muhtemelen bir Etkinlik, Site ve Tarih (ler) ile kesişme noktanız olmalıdır.

DimActivity- Tahmin ediyorum ki bir kalıp var, bunları en azından nispeten paylaşılan sütunlara ayırmanıza izin verebilecek bir şey. Eğer öyleyse, üç tane olabilir mi? beş? faaliyet sınıfları için boyutlar. En kötüsü, etkinlik adı gibi birkaç tutarlı sütununuz vardır, filtreleyebilir ve kalan rastgele ayrıntılar için "Özellik1" vb. Gibi genel başlıkları bırakabilirsiniz.

Boyuttaki her şeye ihtiyacınız yoktur - Etkinlik boyutunda herhangi bir tarih olmamalıdır (büyük olasılıkla) - Tarih Anahtarına Vekil Anahtar referansları olarak hepsi gerçekte olmalıdır . Örnek olarak, bir kişi boyutunda kalacak bir Tarih, bir kişinin niteliği olduğu için doğum tarihi olacaktır. Bir hastane ziyaret tarihi, diğer şeylerin yanı sıra, bir kişiyle ilişkili bir zaman olayı olduğu için, ancak hastaneyi ziyaret eden kişinin bir özelliği değildir. Aslında daha fazla tarih tartışması.

DimSite- düz görünüyor, bu yüzden burada Yedek Anahtarları açıklayacağız. Temelde bu sadece artan, benzersiz bir kimliktir. Tamsayı Kimliği sütunu yaygındır. Bu, DW ve kaynak sistemlerinin ayrılmasına izin verir ve veri ambarında en uygun birleştirmeleri sağlar. Doğal Anahtarınız veya İş Anahtarınız genellikle saklanır, ancak bakım / tasarım için analiz ve birleştirme yapılmaz. Örnek şema:

CREATE TABLE [DIM].[Site]
(
 SiteSK INT NOT NULL IDENTITY PRIMARY KEY
,SiteNK INT NOT NULL --source system key
,SiteName VARCHAR(500) NOT NULL
)

DimDate- tarih özellikleri. Kimlik yerine "akıllı anahtar" yapın. Bu, WHERE DateSK = 20150708 gibi sorgular için bir tarihle ilgili anlamlı bir tamsayı yazabileceğiniz anlamına gelir. DimDate'i yüklemek için çok sayıda ücretsiz komut dosyası vardır ve çoğunda bu akıllı anahtar bulunur. ( bir seçenek )

DimEmployee - DimPerson'da daha genel bir değişiklik söz konusuysa XML'iniz buna dahil etti ve ilgili kişi niteliklerini kullanılabilir ve raporlamaya uygun olduğu için doldurun.

Ve gerçek şu ki:

FactActivitySite
DimSiteSK - FK to DimSite
DimActivitySK - FK to DimActivity
DimEmployee - FK to DimEmployee
DimDateSK - FK to DimDate

Bunları Gerçekte yeniden adlandırabilir ve etkinlik başına birden çok tarih anahtarınız olabilir. Gerçekler genellikle çok büyüktür, bu nedenle güncellemelerden kaçınmak genellikle iyidir ... Tek bir etkinlikte birden çok tarih güncellemeniz varsa, "güncelleme" satırlarının seçimine izin veren bir SK ekleyerek bir Sil / Ekle tasarımını denemek isteyebilirsiniz. silinir ve en son veriler eklenir.

İhtiyacınız ne olursa olsun için Gerçek tarihleri genişletin: StartDateSK, EndDateSK, ScheduledStartDateSK.

Tüm boyutlar, genellikle sabit kodlanmış -1 SK içeren Bilinmeyen bir satıra sahip olmalıdır. Gerçeği yüklediğinizde ve bir etkinliğin dahil edilen Tarihlerden hiçbirine sahip olmadığında, yalnızca -1 yüklemesi gerekir.

Gerçek, boyutlarda saklanan özelliklerinize tamsayı referanslarının bir koleksiyonudur, bunları birleştirin ve tüm ayrıntılarınızı çok temiz bir birleştirme deseninde elde edersiniz ve veri türleri nedeniyle son derece küçük ve hızlıdır. SQL Server'da olduğunuzdan, performansı daha da artırmak için bir sütun deposu dizini ekleyin . ETL sırasında bırakıp yeniden inşa edebilirsiniz. SQL 2014+ sürümüne geçtikten sonra columntore dizinlerine yazabilirsiniz.

resim açıklamasını buraya girin

Bu rotaya giderseniz Boyutsal Modelleme'yi araştırın. Kimball metodolojisini tavsiye ederim . Orada da çok sayıda ücretsiz rehber var, ancak bu bir defalık çözüm dışında bir şey olacaksa, yatırım muhtemelen buna değer.


(wesdev'den soru): @Dave, hangi ERD aracını kullandınız?
ypercubeᵀᴹ

Bu Microsoft Visio 2013'te yapıldı
Dave
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.