Üzerinde çalıştığım bir Web uygulaması içinde, tüm veritabanı işlemleri Entity Framework ORM üzerinde tanımlanan bazı genel depolar kullanılarak soyutlanır.
Ancak, genel havuzlar için basit bir tasarıma sahip olmak için, ilgili tüm tablolar benzersiz bir tamsayı tanımlamalıdır ( Int32
C #, int
SQL'de). Şimdiye kadar, bu her zaman masanın PK'sı ve aynı zamanda IDENTITY
.
Yabancı anahtarlar yoğun olarak kullanılır ve bu tamsayı sütunlarına başvururlar. Hem tutarlılık hem de ORM tarafından navigasyon özellikleri oluşturmak için gereklidirler.
Uygulama katmanı genellikle aşağıdaki işlemleri gerçekleştirir:
- tablodan ilk veri yüklemesi (*) -
SELECT * FROM table
- Güncelleme -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- Sil -
DELETE FROM table WHERE Id = IdVal
- Ekle -
INSERT INTO table (cols) VALUES (...)
Daha az sıklıkta yapılan işlemler:
- Toplu
BULK INSERT ... into table
veri - ardından (*) tüm veri yükü (oluşturulan tanımlayıcıları almak için) - Toplu silme - bu normal bir silme işlemidir, ancak ORM açısından "hantal":
DELETE FROM table where OtherThanIdCol = SomeValue
- Toplu güncelleme - bu normal bir güncelleme işlemidir, ancak ORM açısından "hantal":
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
* tüm küçük tablolar uygulama düzeyinde önbelleğe alınır ve neredeyse hepsi SELECTs
veritabanına ulaşmaz. Tipik bir desen ilk yük ve çok sayıda INSERT
s, UPDATE
s ve DELETE
s'dir.
Mevcut uygulama kullanımına bağlı olarak, tabloların herhangi birinde 100M kayıtlarına ulaşma şansı çok düşüktür.
Soru: Bir DBA'nın bakış açısından, bu tablo tasarım sınırlamasına sahip olarak karşılaşabileceğim önemli sorunlar var mı?
[DÜZENLE]
Yanıtları okuduktan sonra (harika geri bildirim için teşekkürler) ve başvurulan makaleleri, daha fazla ayrıntı eklemem gerektiğini hissediyorum:
Mevcut uygulama özellikleri - Mevcut web uygulaması hakkında bahsetmedim, çünkü modelin diğer uygulamalar için de tekrar kullanılıp kullanılamayacağını anlamak istiyorum. Ancak benim özel durumum, bir DWH'den çok sayıda meta veri ayıklayan bir uygulamadır. Kaynak veriler oldukça dağınık (tuhaf bir şekilde denormalize, bazı tutarsızlıklar, birçok durumda doğal tanımlayıcı vb. Yok) ve uygulamam net ayrılmış varlıklar oluşturuyor. Ayrıca, oluşturulan tanımlayıcıların (
IDENTITY
) çoğu görüntülenir, böylece kullanıcı bunları iş anahtarları olarak kullanabilir. Bu, büyük bir kod yeniden düzenlemesinin yanı sıra GUID'lerin kullanımını hariç tutar ."Bir sırayı benzersiz bir şekilde tanımlamanın tek yolu olmamalı" (Aaron Bertrand ♦) - bu çok iyi bir tavsiye. Tüm tablolarımda, işletme kopyalarına izin verilmemesini sağlamak için BENZERSİZ BİR KISIT tanımlanır.
Ön uç uygulama odaklı tasarım ve veritabanı odaklı tasarım - tasarım seçimi bu faktörlerden kaynaklanır
Varlık Çerçevesi sınırlamaları - birden çok sütun PK'ya izin verilir, ancak değerleri güncellenemez
Özel sınırlamalar - tek bir tamsayı anahtarına sahip olmak, veri yapılarını ve SQL dışı kodu büyük ölçüde basitleştirir. Örn: tüm değer listelerinin bir tamsayı tuşu ve görüntülenen değerleri vardır. Daha da önemlisi, önbellekleme için işaretlenmiş herhangi bir tablonun
Unique int key -> value
haritaya konabileceğini garanti eder .
Karmaşık seçme sorguları - bu neredeyse hiçbir zaman gerçekleşmeyecektir, çünkü tüm küçük (<20-30K kayıtlar) tablo verileri uygulama düzeyinde önbelleğe alınır. Bu, uygulama kodunu yazarken hayatı biraz zorlaştırır (LINQ yazmak daha zordur), ancak veritabanı çok daha iyi vurulur:
Liste görünümleri -
SELECT
yükte sorgu (her şey önbelleğe alınır) veya şuna benzer sorgular oluşturmaz:SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
Diğer tüm gerekli değerler önbellek aramaları (O (1)) ile getirilir, bu nedenle karmaşık sorgular oluşturulmaz.
Görünümleri düzenle - şöyle
SELECT
ifadeler oluşturur :SELECT allcolumns FROM BigTable WHERE PKId = value1
(tüm filtreler ve değerler int
s)