Veritabanı tasarımı - Her zaman mağaza durumu veya hesaplama durumu?


17

Diyelim ki ilişkisel bir veritabanı uygulamam ve bir "kullanıcı" nesnesi ve bir "mesaj" nesnesi var. Şimdi bu kullanıcıya okunmamış mesaj sayısını göstermek istiyorum.

Bunu arşivlemenin en iyi yolu nedir? Kullanıcıya bir alan ekler miyim ve kullanıcı bir mesaj alırsa sayar mı ve okursa sayıyı azaltır mıyım? Yoksa okunmamış olarak işaretlenen kullanıcının ileti sayısını hesaplamak için her seferinde bir sorgu yürütüyor muyum?

İlk yaklaşımın daha karmaşık ve hataya açık olduğunu düşünüyorum, ancak ikinci yaklaşımdan daha iyi performans gösterecek.

Bu normal olarak nasıl yapılır veya daha iyi yaklaşım nedir?


1
Bir dizi faktöre bağlıdır: DB'niz bölümlenmiş mi? Kaç satır / kullanıcı bekliyorsunuz? Hangi boyutta toplam DB bekliyorsunuz (veya toplam kaç kullanıcı)? Saniyede kaç istek bekliyorsunuz? Tüm bunların doğru olması gerekmez, ancak bazı kaba fikirler ...
Omer Iqbal

10
+1 Bu klasik bir ilişkisel veritabanı sorusudur. Normalleştirmek mi yoksa normalleştirmek değil mi? Soru bu. Şiddetteki aşırı çoğalmanın sapanlarına ve oklarına maruz kalmak ya da tetikleyicileri almak ve bunları kullanarak bitirmek mi?
Ross Patterson

Bunun klasik bir Rel. db. soru, sitede zaten bir cevap olmalı, bu DUP olarak kapatılmalıdır veya bir cevabımız yok ve bu açık bırakılmalıdır.
mattnz

Yanıtlar:


14

Bu normal olarak nasıl yapılır veya daha iyi yaklaşım nedir?

En iyi yaklaşım, ilk önce fazladan bir alan olmadan denemek, performansı ölçmek ve eğer gerçekten çok yavaş çıkıyorsa, optimize etmeye çalışırsınız. Bu, ekstra bir alan kullanarak ilk yaklaşımınıza geçmek anlamına gelebilir, ancak mesajlarınızı birleştirilmiş alanlara ("okunmamış", "kullanıcı kimliği") ek bir dizin koyarak, diğer seçenekleri de test etmeyi düşünmelisiniz.


2
En iyi yaklaşım (önce daha basit yöntemle gitmek). Genel kurallar ayrıntılardan daha iyidir, fwiw. ("Test!" İçin +1.)
DougM

9

Veritabanı teorisine göre ders kitabı çözümü veritabanınızda diğer verilerin değerlerine bağlı hiçbir değere sahip olmayacaktır, çünkü bunlar geçişli bağımlılıklardır . Diğer alanlara dayalı olarak hesaplanan değerler olan alanlara sahip olmak, normalleştirmenin ihlalidir, çünkü gereksiz bilgilere yol açar.

Bununla birlikte, bazen ders kitabının söyledikleri ve pratikte en pratik yöntem nedir farklıdır. Her sayfa görüntülemedeki okunmamış mesaj sayısını saymak oldukça pahalı bir işlem olabilir. -Tablodaki sayının önbelleğe useralınması performans için çok daha iyi olur. Maliyet, veritabanında tutarsızlıkların mevcut olması olabilir: Bir mesajın okunmamış sayacı da güncellemeyi hatırlamadan silinmesi, eklenmesi veya okunması mümkün olabilir.


4
Tutarlılık sorunu üzerinde sayacı ayarlamak tetikleyiciler ile yalamak kolaydır INSERTya DELETE. (Veya UPDATEbir iletinin sahibinin değişmesini hesaba katarak.). İyi bir DBMS işlemi gerçekleştirir ve tetikleyicileri aynı işlemde çalıştırır, bu nedenle bunların tümü veya hiçbiri gerçekleşmez.
Blrfl

4

Olası sorun performanstır ve henüz bir performans sorununuz yoktur. Çözüm # 1'de bunu işlemek için seçtiğiniz veritabanına bağlı olarak yapabileceğiniz birçok şey vardır: dizinleme, donanım, önbellekleme, vb. Bu, kullanıcının geçerli bir okunmamış mesaj sayısını alması için ne sıklıkta ihtiyaç duyduğuna bağlıdır. Bu seçeneklerin çoğu uygulama tarafında özel kodlama gerektirmez, bu nedenle bunları bir kod değişikliği veya çok az bir uygulama ile uygulayabilirsiniz. Uygulaması ile büyümeyi kolaylaştırır.

Bir kullanıcı bağlandığında / oturum açtığında, sayıyı veritabanından bir kez almak o kadar da kötü değildir. Uygulamanız e-posta gibi mesajların sürekli güncellenen bir listesini tutacak mı? Buradan okunmamış bir sayı almak veritabanına başka bir gezi gerektirmez ve yeni mesajlar almak için yine de bir db gezisi alacaktır.

IsRead'i işaretlemek için her mesaj okunduğunda db'ye seyahat mi ediyorsunuz? alan, başka bir alanın yeniden hesaplanması olmadan yeterlidir.

Çözüm # 2 ile (bir alanda / diskte sayım tutmak), bir sorun olduğunda bu alanı periyodik olarak yeniden oluşturmak / yeniden hesaplamak için bir rutine ihtiyacınız olacak mı? Ve her zaman sorunlar var. Tüm bunları bir işlemde saracak mısınız? Birisi her birine bir ileti gönderdiğinde, kullanıcı tablosunun kilidi nedeniyle alıcı kullanıcının UnreadCount'unu güncelleyemediği için başarısız olabilir mi? Yoksa bu alan için ayrı bir tablo mu oluşturacaksınız?



0

Bunu her seferinde bir sorgu yürüterim, yani ikinci yaklaşımınız. Sorgunuzun performansını artırmak için, kullanıcı tablosuna yabancı anahtar görevi gören sütundaki ileti tablonuza bir dizin eklediğinizden emin olun.

Daha sonra Doc'un dediği gibi, bu yaklaşımın performansını ölçün ve ardından farklı bir yol izlemeniz gerekip gerekmediğini söyleyebilirsiniz.

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.