Tablo bölmesi vs ile ilgili şikayetler


10

On milyonlarca kayıt içeren (potansiyel olarak) öğelerden oluşan bir tablo tasarlıyorum. Bazı öğeler yönetici tarafından "onaylanana" kadar kullanılamaz. "Kullan" derken, bu tür öğelere "onaylanana" kadar başka bir tabloda referans verilmeyeceğini kastediyorum. Herhangi bir zamanda öğelerin% 50'sine kadar "onaylanmamış" olabilir. Kayıtlar "onaylanabilir", ancak tam tersi olmayabilir.

İki tasarım seçeneğini düşünüyorum:

  • biraz bayrak
  • "onaylanmamış" öğelerden oluşan ayrı bir tablo - öğe onaylandığında "normal" tabloya taşınır (öğe kimliğinin yenilenmesi sorun değildir)

Bence ikinci seçenek çok daha iyi. Bit bayrağı satır başına yalnızca bir bayt alır, bu yüzden bir sorun değildir. Ancak aynı tabloda bir milyon onaylanmış ve bir milyon onaylanmamış kayıt varsa - onaylanmış kayıtlara sahip işlemler için tarama süresi artar.

Soru: Bunun yerine ilk (bit bayrağı) seçeneğini düşünmeli miyim? Açıklanan durumda herhangi bir faydası var mı?


1
Onaylanan kayıtlara erişimi hızlandırmak için filtrelenmiş dizinler kullanabileceğinizi hatırlamanızda yardımcı olabilir. brentozar.com/archive/2013/11/…
mendosi

Ne yazık ki filtrelenmiş dizinler parametreli sorgularda kullanılmaz.
Dima

@Dima bu tamamen doğru değil. Filtrelenmiş bir dizin söz veriyorsa WHERE status='A've bir sorgu varsa WHERE status = 'A' AND (... other columns and parameters here...), dizin yine de kullanılabilir.
ypercubeᵀᴹ

Yanıtlar:


6

Bölümlenmiş görünümlerle her iki yöne de sahip olabilirsiniz .

Her durum için, sınırlamalarla zorlanan ve birbirini dışlayan değerlerle temel tablo oluşturursunuz. Sonra sendikaların temel tablolarını bir araya getirdiği bir görünüm Görünüm veya her temel tabloya açıkça başvurulabilir. Bir satırın durumu görünüm boyunca GÜNCELLENİRse, DBMS bunu bir temel tablodan SİLECEK ve yeni duruma karşılık gelen duruma ekler. Her temel tablo, kullanım şekline göre bağımsız olarak indekslenebilir. Optimize edici, mümkünse tek bir karşılık gelen temel tabloya indeks referanslarını çözecektir.

Yararları
a) daha sığ endekslerdir. Bununla birlikte, dizini fan-out üzerindeki matematiği yapın. Bu ölçekte ve durum değerleriniz arasında bölünme durumunda, dizinlerin bölünmüş tablolarda birleştirilmiş tabloda olduğu gibi aynı derinlikte olması mümkündür.
b) hiçbir uygulama kodunun değiştirilmesi gerekmez. Veriler sürekli bir bütün olarak görünmeye devam ediyor.
c) gelecekteki yeni durum değerleri, kısıtlamayla yeni bir temel tablo eklenerek ve görünüm yeniden oluşturularak dahil edilebilir.

Maliyet, tüm bu veri hareketidir; her durum güncellemesi için iki sayfa ve ilişkili dizinler yazılır. IO ile uğraşmak için bir sürü. Bu hareket de parçalanmaya neden olacak.


5

(potansiyel olarak) on milyonlarca kayıt içeren bir tablo.

SQL Server'ın verimli bir şekilde işleyebileceği göz önüne alındığında, aslında bu kadar değil. Tabii ki, en büyük tablolardan birinin (tek örnekli sistem) 2 milyon sıraya sahip olduğu ve şimdiye kadar ele aldığım en yüksek işlerden birini hatırlıyorum. Daha sonra bir sonraki iş, yüz milyonlarca satıra sahip bazı tablolarla 17 Üretim örneğine sahipti ve bunların hepsi, 1 milyardan fazla satıra sahip birden fazla olgu tablosuyla bir Veri Ambarı'nda toplandı. Beni yanlış anlamayın, on milyonlarca satırda alay etmiyorum, sadece iyi bir veri modeli ve uygun indeksleme (ve dizin bakımı) ile SQL Server'ın çok işleyebileceğini vurguluyorum .

Herhangi bir zamanda öğelerin% 50'sine kadar "onaylanmamış" olabilir.

Hmm. Kulağa doğru gelmiyor. Girişleri "onaylama" oranı, yeni giriş alma oranının yarısı kadardır? Her 2 yeni giriş için yalnızca 1 tanesi "onaylanacak" mı? 2 milyon satır ve her biri "onaylanmış" ve "onaylanmamış" için 1 milyon, bir kaç yıl sonra 10 milyon girişle, her birinin "onaylanmış" ve "onaylanmamış" için 6 milyon olmasını mı bekliyorsunuz? Yoksa 1 milyon "onaylanmamış" bir şekilde sabit kalacak mı, 10 milyon yeni giriş ile 11 milyon "onaylı" ve hala 1 milyon "onaylanmamış" olacak mı?

Kayıtlar "onaylanabilir", ancak tam tersi olmayabilir.

Bugün bu doğrudur , ancak işler zamanla değişir ve bu nedenle işletmenin "onaylamama" ya da "arşivlenmiş" gibi başka bir duruma izin vermeye karar vermesi olasılığı her zaman vardır.

Öyleyse, seçimlere bakalım:

İşaretle (veya muhtemelen TINYINT"durum")

  • Her durumun sorguları için biraz daha yavaş
  • Zaman içinde daha esnek / yalnızca yeni bir Arama durumu değerine sahip üçüncü bir durum (örneğin "Arşivlendi") gibi bir değişikliği dahil etmek kolaydır. Yeni tablo yok (zorunlu olarak), bazı yeni kodlar, sadece bazı kodlar güncellendi.
  • Daha az iş (kod, test vb.) Ve tek bir TINYINTsütunu güncelleme hatası
  • Daha az karmaşık = zaman içinde daha düşük bakım maliyetleri, yeni çalışanların anlaması için daha kısa eğitim süresi
  • (muhtemelen) Bir tablo güncellendiğinde İşlem Günlüğü üzerinde daha küçük etki
  • İki tablo arasında "RecordStatus" ve FK için bir Lookup tablosuna ihtiyacınız var.

İki ayrı tablo (biri "onaylandı", biri "onaylanmadı" için)

  • Her durumun sorguları için biraz daha hızlı
  • Zaman içinde daha az esnek / üçüncü bir durum (örneğin "Arşivlendi") gibi bir değişikliği dahil etmek daha zor; yeni durum büyük olasılıkla başka bir tablo ve kesinlikle yeni ve güncellenmiş kod gerektirir.
  • Daha fazla çalışma (kod, test vb.) Ve kayıtların "Onaylanmadı" tablosundan "Onaylandı" tablosuna taşınması için daha fazla alan
  • Daha karmaşık = zaman içinde daha yüksek bakım maliyetleri, yeni çalışanların anlaması için daha uzun eğitim süresi
  • (muhtemelen) Bir tablo silindiğinde ve bir tablo eklendiğinde İşlem Günlüğü üzerinde daha büyük etki
  • " Öğenin kimliğinin yenilenmesi " konusunda endişelenmenize gerek yok : Onaylanmamış tablonun bir IDENTITYsütun olan kimlik sütunu ve Onaylanan tablonun (burada gerekli olmadığı için) olmayan bir kimlik sütunu IDENTITYvardır. Dolayısıyla tablolar arasında kayıt hareket ettikçe kimlik değerleri tutarlı kalır.

Şahsen ben StatusIDbaşlamak için sütun ile tek tabloya doğru eğilir . İki tablo kullanmak aşırı karmaşık, erken bir optimizasyon gibi görünüyor. Kayıt sayısının birkaç yüz milyonlarca olması ve endekslemenin herhangi bir performans kazanımı sağlamaması durumunda bu optimizasyon türü tartışılabilir .


Hızlı hareket eden verileri olan bir tablodur: çoğu zaman birçok yeni satırla doldurulur, sıklıkla satırlar silinir. Yalnızca tek bir konuya odaklanmak için tüm ayrıntıları (ticari karar, müşteri kodlaması vb.) Kaldırmaya çalıştım. Temelde biraz bayraklı eski tasarım masasına sahibiz. Ve% 100 için bayrağın 1 olarak ayarlandığı satırların hiçbir zaman başka bir tabloda kullanılmadığını biliyorum. Bu yüzden sadece orada yer aldıklarını ve ayrı bir masaya taşınabileceklerini hissediyorum. Tablo hemen hemen her sorguda DB'ye taranır. Bu nedenle "ağırlığını" potansiyel olarak azaltmak CPU / IO ops'lerini azaltabilir.
Dima

3
Bölünmüş tabloların başka bir avantajı: Yalnızca "Onaylandı" tablosuna başvuran FK'leriniz olabilir.
ypercubeᵀᴹ

Tek bir varlık için bölünmüş tablolarla ilgili diğer sorun kısıt bütünlüğüdür. Diğer tablolardan yapılan referanslar, kaydın ilerlemesiyle hoş olmayacaktır. Bu, bölünmüş tablo için ayna referans tabloları gibi bu sorunların üstesinden gelmek için kodun yazılmasını gerektirecektir -> Çok zahmetli
user1567453
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.