Şemayı basit bir banka veritabanı için yazıyorum. İşte temel özellikler:
- Veritabanı, bir kullanıcıya ve para birimine karşı işlemleri kaydeder.
- Her kullanıcının para birimi başına bir bakiyesi vardır, bu nedenle her bir bakiye, belirli bir kullanıcıya ve para birimine karşı tüm işlemlerin toplamıdır.
- Bir denge negatif olamaz.
Banka başvurusu, veri tabanı ile yalnızca depolanmış prosedürler aracılığıyla iletişim kuracaktır.
Bu veritabanının günde yüz binlerce yeni işlemi kabul etmesini ve daha yüksek bir büyüklükteki sorgu sorgularını kabul etmesini bekliyorum. Bakiyeleri çok hızlı bir şekilde yerine getirmek için bunları önceden toplamam gerekiyor. Aynı zamanda, bir dengenin işlem geçmişiyle hiçbir zaman çelişmediğini garanti etmem gerekiyor.
Seçeneklerim:
Ayrı bir
balances
masaya sahip olun ve aşağıdakilerden birini yapın:Hem işlemleri uygulayın
transactions
vebalances
tablolar.TRANSACTION
Bakiye ve işlemlerin her zaman senkronize olmasını sağlamak için saklı yordam katmanımda mantığı kullanın . ( Jack tarafından desteklenir .)İşlemleri
transactions
tabloya uygulayın vebalances
tabloyu benim için işlem tutarıyla güncelleyen bir tetikleyiciye sahip olun .İşlemleri
balances
tabloya uygulayın vetransactions
benim için işlem tutarını içeren tabloya yeni bir giriş ekleyen bir tetikleyiciyi kullanın .
Saklı yordamların dışında hiçbir değişiklik yapılamayacağından emin olmak için güvenlik tabanlı yaklaşımlara güvenmek zorundayım. Aksi takdirde, örneğin, bazı işlemler doğrudan
transactions
tabloya bir işlem ekleyebilir ve şema altında1.3
ilgili bakiyenin senkronize olamayacağı belirtilir.Bir var
balances
endeksli görünümü uygun işlemleri toplar. Bakiyeler, depolama motoru tarafından işlemleriyle uyum içinde olmaları için garanti altına alındığından, bunu garanti etmek için güvenlik tabanlı yaklaşımlara güvenmem gerekmiyor. Öte yandan, dengeleri zorlayamıyorum çünkü görüşlerin - endekslenmiş görünümlerin bile -CHECK
kısıtlamaları olamaz . ( Denny tarafından desteklenmektedir .)Sadece bir
transactions
masaya sahip olun, ancak işlem yapıldıktan hemen sonra etkili bakiyeyi saklamak için ek bir sütuna sahip olun. Bu nedenle, bir kullanıcı ve para birimi için en son işlem kaydında mevcut bakiyeleri de bulunur. (Aşağıda Andrew tarafından önerildi; garik tarafından önerilen varyant .)
Bu problemle ilk karşılaştığımda, bu iki tartışmayı okudum ve seçeneğe karar verdim 2
. Başvuru için, burada bir çıplak kemik uygulaması görebilirsiniz .
Yüksek yük profiline sahip böyle bir veritabanı tasarladınız veya yönetdiniz mi? Bu soruna çözümün neydi?
Doğru tasarım seçimini yaptığımı mı düşünüyorsun? Aklımda tutmam gereken bir şey var mı?
Örneğin,
transactions
tablodaki şema değişikliklerininbalances
görünümü yeniden oluşturmamı gerektireceğini biliyorum . Veritabanını küçük tutmak için işlemleri arşivliyor olsam bile (örneğin, başka bir yere taşıyarak ve bunları özet işlemlerle değiştirerek), her şema güncellemesinde on milyonlarca işlemin görüşünü yeniden oluşturmak zorunda kalmak, muhtemelen dağıtım başına önemli ölçüde daha fazla kesinti anlamına gelecektir.Dizin oluşturulmuş görünüm gitme yoluysa, bakiyenin negatif olmadığını nasıl garanti ederim?
Arşivleme işlemleri:
Arşivleme işlemlerini ve yukarıda bahsettiğim "özet işlemleri" konusunu biraz ele alalım. İlk olarak, düzenli arşivleme, bunun gibi yüksek yüklü bir sistemde bir gereklilik olacaktır. Eski işlemlerin başka bir yere taşınmasına izin verirken bakiyelerle işlem geçmişi arasındaki tutarlılığı korumak istiyorum. Bunu yapmak için, her arşivlenmiş işlem grubunu kullanıcı başına ve para birimine göre miktarlarının bir özeti ile değiştireceğim.
Yani, örneğin, bu işlemlerin listesi:
user_id currency_id amount is_summary
------------------------------------------------
3 1 10.60 0
3 1 -55.00 0
3 1 -12.12 0
arşivlendi ve bununla değiştirildi:
user_id currency_id amount is_summary
------------------------------------------------
3 1 -56.52 1
Bu şekilde, arşivlenmiş işlemlere sahip bir bakiye, eksiksiz ve tutarlı bir işlem geçmişi tutar.