IsDeleted uygulamak zorunda kaldığında uygun dizin mimarisi nedir (yumuşak siler)?


17

Şu anda, tamamen işlevsel olan mevcut bir veritabanı ve uygulamamız var. Bu noktada mimariyi değiştirme yeteneğim yok. Bugün, veritabanındaki her tablonun varsayılan değeri '0' olan bir "IsDeleted" NOT NULL BIT alanı vardır. Uygulama verileri "sildiğinde", IsDeleted bayrağını 1'e günceller.

Anlamakta sorun ne tabloların her dizinlerin nasıl yapılandırılması gerektiğidir. Şu anda, her sorgu / birleştirme / vb her zaman IsDeleted denetimi uygular. Geliştiricilerimizin izlemesi gereken bir standart. Olduğu söyleniyor, tüm kümelenmiş birincil anahtar dizinleri tabloların her biri birincil anahtar VE IsDeleted BIT alanı içerecek şekilde değiştirilmesi gerekip gerekmediğini belirlemeye çalışıyorum. Ayrıca, HER sorgu / join / etc beri. IsDeleted denetimini uygulamalıdır, HER TEK dizin (kümelenmemiş) dizinin ilk alanı olarak IsDeleted alanını içermesi uygun bir varsayım mıdır?

Bir diğer sorum da filtrelenmiş dizinler. Dizinlerin boyutunu azaltmak için "WHERE IsDeleted = 0" gibi dizinler üzerinde filtreler koymak anlıyorum. Ancak, her birleştirme / sorgu IsDeleted denetimini uygulamak zorunda kalacağından, filtrelenmiş dizinin kullanılmasını önler (IsDeleted sütunu birleştirme / sorguda kullanıldığından)?

Unutmayın, IsDeleted yaklaşımını değiştirme yeteneğim yok.

Yanıtlar:


13

Buradaki en kolay yaklaşım, anahtarlarınızı ve kümelenmiş dizinleri tek başına bırakmak ve kümelenmemiş dizinleriniz için filtrelenmiş dizinler kullanmaktır.

Ayrıca, bazı büyük tabloları bölümlenmiş yığınlara veya bölümlenmiş kümelenmiş sütun depolarına (SQL Server 2016+) geçirerek birincil anahtarı ve benzersiz dizinleri bölümlendirmeden bırakabilirsiniz. Bu, IsDeleted satırları için anahtar olmayan sütunları, ek olarak farklı şekilde sıkıştırılabilen veya farklı bir dosya grubunda depolanabilecek ayrı bir veri yapısına itmenizi sağlar.

Ve geliştiricilerin IsDeleted satırlarını filtrelemek için parametre yerine değişmez bir bilgi kullandığından emin olun. Bir parametre ile SQL Server her iki durumda da aynı sorgu planını kullanmak zorundadır.

ÖRNEĞİN

SELECT ... WHERE ... AND IsDeleted=0

Ve yok:

SELECT ... WHERE ... AND IsDeleted=@IsDeleted

Bir parametre kullanmak filtrelenmiş dizinin kullanılmasını önler ve parametre koklama konusunda sorun yaşamanıza neden olur.


IsDeletedSütunun yaygınlığı ve önemi göz önüne alındığında, fiziksel depolamaya bakılmaksızın, verileri iki görünüm yoluyla (isteğe bağlı olarak farklı şemalarda) ortaya çıkarmak, hem parametrelendirme sorununu çözmek hem de olmaması gereken verilere erişirken hata yapmak muhtemelen mantıklı olacaktır. daha az muhtemel. Temel verilere erişmek yalnızca silinmiş ve silinmemiş verilerin bir şekilde birleştirilmesi gereken nadir durumlarda ve satırların gerçekten "silinmiş" olarak değiştirilmesi gerektiğinde geçerlidir.
Jeroen Mostert

@JeroenMostert iyi tavsiye. RLS burada veya EF Çekirdek Global Sorgu Filtreleri gibi bir şey de kullanılabilir. docs.microsoft.com/tr-tr/ef/core/querying/filters
David Browne - Microsoft

9

Bu popüler olmayan bir fikir olabilir, ancak "bunu her yerde yap" / tek bir boyutun tüm sorularınıza cevap verdiğini düşünmüyorum.

Herhangi bir nedenle çok sayıda IsDeleted satırı tarayan sorgularınız varsa, çözümlerden biri bu sorguyu karşılamak için filtrelenmiş, kümelenmemiş bir dizin oluşturmaktır.

Başka bir seçenek de, yalnızca silinmeyen satırlara filtre uygulanan bir dizi farklı sorgu tarafından kullanılabilen dizine alınmış bir görünüm oluşturmaktır. Bu, otomatik dizinli görünüm eşleştirmenin NOEXPANDipucu vermeden çalıştığı Enterprise Edition'da özellikle yararlı olabilir .

Küçük tablolar veya çok okunan tablolar için, filtrelenmiş kümelenmemiş dizinler veya görünümler veya gerçekten herhangi bir şey eklemek veritabanınıza gereksiz ek yük ekliyor olabilir.


2

Silme işlemlerinin nadir olduğu makul varsayımı altında, endekslerde hiçbir değişiklik uygun bir çözüm değildir.

Er ya da geç bir silinmiş satır başvuruları sormak gerektiğini ve endekslerde satırları aniden çok değer bulundu.

Görünümleri kullanmadığınız sürece, filtreleri yine de dahil etmek için tüm sorgularınızı düzenlemeniz gerektiğini lütfen unutmayın.


0

IS_DELETED bayrağının 0 ya da PK değeri olduğu bir sistem gördüm. Diğer sistemlerde ise PK olumsuzdu.

Çoğu sorgu "doğal" veya iş (bazen çok alanlı) anahtarıyla değerleri aldığından, birleştirmeler dışında PK tarafından hiçbir zaman sorgulanmazlar; ancak ana tablonun ve birleştirilen tabloların sonuna her zaman AND IS_DELETED = 0 eklediler.

Bu sistem ayrıca değişiklikleri izleyen her işlem tablosu için bir denetim tablosuna sahipti; ve uygulamanın silinen veriler de dahil olmak üzere tüm veri değişikliklerini görüntüleme özelliği vardı.


0

Sorguyu değiştirme hakkınız ve yeteneğiniz olduğunu umuyoruz.

Ancak, her birleştirme / sorgu IsDeleted denetimini uygulamak zorunda kalacağından, filtrelenmiş dizinin kullanılmasını önler (IsDeleted sütunu birleştirme / sorguda kullanıldığından)?

Önemli bir nokta söylemek istedim, umarım açıklayabilirim.

Karmaşık sorguda Transaction tableve Mastertabloların her ikisi de kullanılır.

IsDeleted=0Yalnızca Transactiontabloda kullanın . MasterTabloda kullanmayın .

Misal,

Select * from dbo.Order O
inner join dbo.category C on o.categoryid=o.categoryid
inner join dbo.Product P on P.Productid=o.Productid
where o.isdeleted=0

c.isdeleted=0( CategoryTabloda kullanma) içinde bir anlamı yoktur . Gereksizdir.

Benzer şekilde kullanmanın bir anlamı var P.isdeleted=0mı?

Çünkü tüm geri alınmamış Sipariş'i ve ayrıntılarını istiyorum.

Nasıl olabilir Productzaman silinecek Orderolan Activeveya nerede Productidreferanstır.

Bu nedenle, önemli sorguda dikkatlice hata ayıklarsanız, isdeleted = 0 öğesinin bazılarını kaldırabilirsiniz.

Filtrelenmiş Dizin'i körü körüne oluşturmayın, önce tüm bu çok önemli ve yavaş sorguyu seçin.

Bu yavaş sorguyu optimize edin, ardından yalnızca Filtrelenmiş Dizin veya ayar Dizinini belirleyin.

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.