Aşağıdaki tablo tasarımlarından hangileri performans için daha iyidir?


16

Hesaplarda toplamak için günlük maliyeti izleyen bir şey yaratmam istendi ve bunu destekleyecek bir veritabanı tablosu şeması bulmaya çalışıyorum.

İşte bildiklerim

  • Şirketin 2,5 milyondan fazla hesabı var
  • Bunlardan şu anda ayda ortalama 200.000 çalışıyorlar (bu, şu anda düşük olan personel seviyelerine göre değişiyor)
  • İzlemek istedikleri 13 farklı maliyet türü var ve gelecekte daha fazlasını ekleyebilecekleri konusunda uyardılar
  • Maliyetlerin günlük olarak izlenmesini istiyorlar
  • Maliyetler tüm envantere bölünmez. Aylık çalışan hesap sayısı (200.000) arasında bölünürler veya kullanıcılar bir grup hesaba maliyet uygulamak için hesap tanımlayıcıları girebilir veya maliyeti hangi hesaplara uygulayacaklarını belirtebilirler.

İlk düşüncem normalleştirilmiş bir veritabanı idi:

accountid
tarih
CostTypeId
Miktar

Benim sorunum matematik yapmak. Bu masa hızla büyüyecek. 13 maliyet türünün tümünün cari ay için tüm çalışan hesaplara uygulandığı varsayılarak, bu ayda 200k * 13 * N days in month75-80 milyon kayıt civarında veya yılda bir milyar kayıt civarındadır.

İkinci düşüncem onu ​​biraz denormalize etmekti

accountid
tarih
Toplam tutar
CostType1
CostType2
CostType3
CostType4
CostType5
CostType6
CostType7
CostType8
CostType9
CostType10
CostType11
CostType12
CostType13

Bu yöntem daha denormalize olur ve ayda 6 milyona kadar ( 200k * N days in month) veya yılda yaklaşık 72 milyon kayıt oluşturabilir . İlk yöntemden çok daha azdır, ancak şirket gelecekte yeni bir Maliyet Türüne karar verirse, başka bir veritabanı sütununun eklenmesi gerekir.

İki yöntemden hangisini tercih edersiniz? Neden? Bunu daha iyi idare edebilecek başka bir alternatif var mı?

En çok hem yazlık hem de ayrıntılı raporlar gibi performans raporlarıyla ilgileniyorum. Masrafları hesaplara yayacak olan iş, etrafta kimse olmadığında gece çalışacaktır. İkincil bir endişe veritabanı boyutudur. Mevcut veritabanı zaten neredeyse 300GB ve diskteki alanın 500GB civarında olduğuna inanıyorum.

Veritabanı SQL Server 2005


Yani başka bir disk al. Diskler ucuz. Bunun hakkında tartışmak için bir toplantının maliyeti 2 TB olabilir.

Yanıtlar:


9

Yılda bir milyar kayıt fazla değildir.

Bölümleme (her Costtype için) ve arşivleme ile yönetilebilir.

Saklanacak veri öğelerinin sayısı halaSaklanacak 200k * 13 * N'dir. Sütunlar olarak, sayfa başına daha az satır alırsınız ve satırlardan daha fazla yer kaplar. "CostType1" sabit uzunluklu bir veri türü değilse, marjinal ise kazanabilirsiniz.

Dedikleri gibi "ÖPÜCÜK"


3
@Rachel kesinlikle bu kadar büyük bir veri seti ile bir bölümleme şeması uygulanmasını öneririm. Eğer aydan aya çalışmaya ve raporlamaya odaklanıyorlarsa, bu zihniyetle çakışabilecek bir bölüm anahtarı seçmek en iyisidir. Ayrıca, bölümünüzü düzgün bir şekilde yapılandırırsanız, verileri tablodan kolayca girip çıkarabilir ve büyük veri yükleri ve yuvarlanan veri kümeleri için silme işlemleri saat yerine saniye süren bir çırpıda yapar.
David

6

Tasarımınız kesinlikle bir gece veya gündüz farkı yaratabilirken, bu durumda, dizinleri gerektiği gibi kapsayan da dahil olmak üzere dizinlere daha fazla odaklanacağım. Ayrıca SQL Server'ın tablo bölümleme gibi çok büyük tablolarla uğraşmak için verdiği araçlardan bazılarına da bakarım.

Bu şekilde düşünün, tabloda 80 milyar kayıt olmasına rağmen, uygun indeksleme ile, herhangi bir noktada gerçekten ilgilendikleriniz diskte fiziksel olarak birlikte gruplandırılacaktır. Verilerin SQL sunucusunda düzenlenme şekli nedeniyle, dizin sınırlarına göre bölünmüş veriler başka bir tabloda da olabilir, çünkü ihtiyaç duyduklarını elde etmek için tüm tabloyu okumak zorunda değildir.

Tabloyu bölümlere ayırmayı da seçerseniz erişim süresini ve ekleme süresini artırabilirsiniz.


4

Normalleşirdim. Bir bankada müşteri hesabı karlılığı için maliyet muhasebesi yaptık ve maliyet merkezi veya genel muhasebe veya her ay milyonlarca hesap üzerinden çeşitli tekniklerle tahsis edilen yüzlerce sürücüyü kullanarak 250 milyondan fazla bireysel maliyet oluşturduk.

Örneğin, ATM'lere hizmet vermenin toplam maliyeti, göreli kullanım miktarına göre ATM kullanan hesaplar arasında bölündü. Dolayısıyla, ATM'lere hizmet vermek için 1 milyon dolar harcanmışsa ve yalnızca 5 müşteri her seferinde bir kez ve bir müşteri 5 kez kullandıysa, bir müşterinin bankaya maliyeti 5 milyon dolar, diğer müşterilerin bankaya maliyeti 0,1 milyon dolar. Diğer sürücüler çok daha karmaşık olabilir.

Sonuçta, muhtemelen seyrek bulacaksınız - belirli hesaplar belirli kaynaklardan / sürücülerden maliyet almıyor - ve bazı hesaplar hiçbir şey alamıyor. Normalleştirilmiş bir modelde, bu satırlar mevcut değildir. Denormalize modelde, satır boş sütunlarla birlikte bulunur. Ayrıca, seyrek normalleştirilmiş bir modelde, performansın arttığını görmelisiniz, çünkü bir satırın varlığı, belirli bir "kova" da NULL olmayan tüm satırları (hatta görebileceğiniz her miktar sütunundaki endeksler çok israf olmaya başlar).


SPARSE - Bu, tüm farkı yaratan çok iyi bir nokta. Seyrek ise, normalleştirerek yerden tasarruf edersiniz. Aksi halde değil. Ancak disk alanı ucuz, bu yüzden kişisel olarak maksimum esneklik için oy verdim (normalleştirilmiş).

3

Performans avantajından bağımsız olarak, kesinlikle seçenek 1 lehine olurdum. Seçenek 2, Peter'ı Paul'e ödemek için soyar.


2

Seçenek 1 ile gitmek istiyorum, ve sonra raporlama hızı yolda bir sorun haline gelirse ben de tablo 2 eklemek ve bir tür otomatik gece / offpeak sürecinde bir raporlama veritabanına doldurmak.

Daha sonra, günlük tablo-2 yapısını, gerektiğinde haftalık, aylık, üç aylık, yıllık toparlanmalara yuvarlamayı düşünebilirsiniz.

Ancak, dediğim gibi, 'ham' verileri uygun (normalleştirilmiş) biçimde depolamayı da seçerdim.


0

Bahsettiğiniz hacimler göz önüne alındığında, ikinci seçenek için gideceğim, ancak TotalCost olmadan. Bunun hala normal olduğunu söyleyebilirsin.


Düzenleme: alternatif olarak ve gereksinimlerinize ve AccountId'nin boyutuna bağlı olarak, aşağıdakileri de göz önünde bulundurabilirsiniz:

AccountDate
-----------
AccountId  
Date  
AcDtID (surrogate key)

Costs
-------
AcDtID
CostTypeId  
Amount  

Bu tasarımla, yine de ilk tabloya denormalize bir TotalCost ekleyebilir ve her seferinde ilk hesapta bazı raporlar çalıştırmaya izin vererek her gece yeniden hesaplanmasını sağlayabilirsiniz.


Ben TotalCostraporlama çoğunluğu orada özetlenmiştir çünkü ve bunu eklenti 13 farklı değerlerden daha tek bir değeri sorgulamak için daha hızlı olacağını düşündüm.

Muhtemelen, ama sonra gerçekten geçişli bir bağımlılık getiriyorsunuz. Bu kayıtlar hiç güncellenecek mi? ya da sadece yazılı ve sonra sadece okumak?

Bu tarih aralığına yeni bir maliyet uygulandığında kayıtlar güncellenir. Yaklaşık bir ay sonra toplam maliyetin güncellenmesi olası değildir, ancak yıllık destek ücretleri gibi şeyler nedeniyle hala mümkündür.

Daha sonra her güncelleme 2 güncelleme gerektirir ve TotalCost alanı tutarsızlık riski ekler.

Geçiş bağımlılığı, ancak tutarsızlık riski olmamakla birlikte, bir CHECK () kısıtlaması TotalCost'un her zaman maliyetlerin toplamı olduğunu garanti edebilir.
Mike Sherrill 'Cat Recall'

0

bir alt sorguyu kullanabilmeniz ve ikinci satırı bir sütun veya çok sayıda sütun olarak seçebilmeniz için firs tablosunu iki tabloya ayırmanız gerekir. bu şekilde daha esnektir ve böylece ikincisi gibi bir sonucu daha kolay elde edebilirsiniz.

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.