Bir bildirim sistemini anlama


15

Ben SE ve başka bir yerde bir bildirim sistemi oluşturmak için nasıl içine bakarak edilmiştir ve kendimi burada kabul cevabı olan çözüme çizilmiş bulundu: /programming/9735578/building-a-notification-system hangi kullanımları bu yapı:

╔═════════════╗      ╔═══════════════════╗      ╔════════════════════╗
notification       notification_object      notification_change 
╟─────────────╢      ╟───────────────────╢      ╟────────────────────╢
ID           ║—1:n—→║ID                 ║—1:n—→║ID                  
userID             notificationID           notificationObjectID
╚═════════════╝      object                   verb                
                     ╚═══════════════════╝      actor               
                                                ╚════════════════════╝

Bir bildirim (nesne = olay, arkadaşlık ..) biri (oyuncu) tarafından değiştirilir (fiil = eklenir, talep edilir ..) ve kullanıcıya (konu) bildirilir. İşte normalleştirilmiş bir veri yapısı (MongoDB kullandığım halde). Bazı kullanıcıları değişiklikler hakkında bilgilendirmeniz gerekir. Kullanıcı başına bildirimlerdir. Yani 100 kullanıcı varsa 100 bildirim oluşturursunuz.

İlk başta bu yaklaşımı anladığımı düşündüm, ama uygulamaya hazırlandığımda, görünüşe göre özellikle iyi anlamadığımı fark ettim. Yanıtla ilgili son birkaç yorum, çözümü anlamada sorun yaşayan diğer kullanıcılardan gelen sorulardır.

Takip edeceğim model olup olmadığından emin değilim, ancak sahip olduğu yukarı oyların sayısı göz önüne alındığında, onu anlamamın fayda sağlayacağından eminim ve kesinlikle daha fazla bilgi edinmek istiyorum. Umarım bu da bu çözümü kavramakta zorluk çeken başkaları için de yararlı olacaktır (bu arada, bu soruya yönlendiren bu cevaba bir yorum bırakmak için yeterli internet puanım yok, lütfen başka biri yapın!)

Sorular

Ben doğru anladıysam, notificationObjectID bir yabancı anahtar işaret olduğunu notification_object masa ve notificationID işaret yabancı anahtardır bildirim masaya. Nesnenin , bildirimin ilgili olduğu veritabanı girişinin kimliğine atıfta bulunan yabancı bir anahtar olması gerektiği anlaşılıyor (örn. Belirli bir olay veya gönderi), ancak o zaman kimliğin hangi tabloya ait olduğunu belirtmek için başka bir alana ihtiyacımız yok mu?

Yazar yazdı

message_object.object, değişiklik türünü tanımlar, örneğin bir dize "dostluk" Değiştiğim nesneye bahsettiğim ekstra verileriyle gerçek referans, bildirim_değiştir.notificationObjectID

bu bana mantıklı gelmiyor. Nesne bir dize (enum?) Ve bildirimObjectID, bildirimin ilgili olduğu nesneye başvuran yabancı bir anahtar mı? Peki orta ve sağdaki tablolar nasıl birbirine bağlanır?

Ortadaki tablo, bildirimin hangi nesne (veya nesne türü) hakkında olduğunu, örneğin bir olayı veya postayı belirtiyor gibi görünüyor. Daha sonra, bildirim_değişimi aynı nesne türüne işaret eden birçok girişe sahip olabiliriz , bu da bildirimleri paketlememize izin verir ("X'in duvarında yayınlanan 25 kullanıcı gibi) - dolayısıyla orta ve sağ tablolar arasındaki 1: n ilişkisi.

Peki sol ve orta tablolar arasında neden 1: n ilişki var? "Sam'in duvarına 25 kullanıcı gönderdi" ve "Mary" Friday Picnic "etkinliğini aynı bildirim kimliğini verecek miyiz? Aynı kullanıcı için tüm bildirimlerin aynı bildirim kimliğine sahip olması durumunda, neden tablodaki tabloya ihtiyacımız var? ayrıldı?

Bir performans sorusu - John'un Mary'nin piknik etkinliği hakkında yorum yaptığını varsayalım. Bildirim_ Değişimi girişini oluşturmadan önce Mary'nin Pikniği için bir bildirim_nesnesi olup olmadığını görmek için bir arama yapmamız gerekiyor gibi görünüyor . Bu performansı olumsuz etkileyecek mi yoksa sorun değil mi? Biz hangi bilemez nasıl bir önceki paragrafta sorularını Sürekli bildirim işaret etmek giriş notification_object için?

Yanıtlar:


8

Bu kadar kapsamlı sorular için teşekkürler ve tüm karışıklıklar için üzgünüm - ilk cevaptan 1 yıl sonra ve şimdi 3 yıl sonra yorum yapmak ... ilk düşünceler soluyor ve beni karıştırıyor, ama delikli şeyi düzenlemekten korkuyorum çünkü çalışmıyorum çünkü şu anda arka uçta bildirimleri saklama ve pratik uygulama olmadan iyi kararlar verip vermediğimden emin değilim

Yazarken düşünüyorum:

  • Evet ve hayır, bildirim Kimliği yabancı bir anahtardı, bildirimObjectID'si değildi. Tabloları birbirine bağlamak için başka bir FK alanına ihtiyacınız var. Mongo deneyimimi bu kadar net olmamakla suçluyorum :(
  • Evet ve hayır, report_object.object belirsizdir, çünkü bir dize veya karmaşık bir şey (JSON veya FK) olarak kullanabilirsiniz. Benim durumumda bu sadece bir isimdi.

Yani her şey bildirimlerinizin görünümüne bağlıdır. Basit bir durumda, bildirimin tamamını arkadaşlar sayfası gibi bazı URL'lere bağlamak istersiniz - bu nedenle nesneye (entityType) bir dize olarak sahip olmak yararlıdır - URL'leri ona bağlarsınız.

"3 arkadaşlık isteğiniz eklendi" bildirimi farklı şekilde saklanabilir.

Onlara birer birer göstermek istiyorsanız - bildirim_de belirli bir arkadaş kullanıcısına bağlantı veren 3 bildirim, 3 bildirim nesnesi (friend_request) ve 3 girişiniz olacaktır.

Bir bildirim göstermek istiyorsanız - 1 bildirim, 1 / daha fazla nesne ve 3 / daha fazla işleminiz olur. Yani bu karmaşık durumda, «A kullanıcısı, B kullanıcısı, C kullanıcısı» ndan 3 arkadaşlık isteğiniz var - her kullanıcı için bildirimObjectID'lerini kullanırsınız ve bildirim metninizde birkaç bağlantı bulunur.

1 veya 3 friend_request nesnesi mi kullanmalısınız? Göre değişir

  1. Nesne nedir ve eylem nedir. «Makale beğenildi / yorumlandı» mı? Yoksa “beğen / yorum eklendi” ve nesne hiyerarşisi yalnızca görüntüleme sırasında bağlanıyor mu? İşte semantik olarak çok yakın görünen «fotoğraf yorumlama» dan «fotoğraf yorumlama» 'yı ayıran facebook - aynı fotoğrafa, aynı aktöre ama bir araya getirilebilecek farklı bildirimlere sahipsiniz

resim açıklamasını buraya girin

  1. Bir bildirimi kaldırabilir misiniz veya bir geçmişe mi ihtiyacınız var? Bir arkadaşlık isteği gönderir ve sonra iptal edersem veya yorum yapar ve sonra bir şey gibi ve sonra silerseniz - Bu geçmişi (başka bir eylem olarak) son kullanıcıya iki farklı eylem olarak göstermeli mi? Muhtemelen değil. Buna ek olarak, teknik olarak daha karmaşık - mevcut bir bildirim_object olup olmadığını araştırmanız gerekir, daha sonra onu kaldırmak için bildirim_change üzerinden arama yapmam gerekecek şekilde yeni bir bildirim_change ekleyin (eğer değilse - yeni bir nesne ekleyin). Bunun yerine, aynı bildirime başka bir bildirim_object eklerim ve eylemleri basamaklı olarak silindiğinde kaldırılırsa kaldırırım.

Öte yandan, tarihin hiçbir şeyin silinmediği eylemlerin gruplandırılmasının yararlı olabileceği durumlar olabilir.

Bu yüzden yazma sırasında, sol ve orta tablolar arasında 1: n ilişki yapıldığını düşünüyorum - böylece bildirimleri sadece aynı varlıktaki (orta-sağ tablolar) değil, aynı zamanda birkaç nesne / varlık tarafından da gruplandırabilirsiniz.

Ancak, sol-orta ilişkisini n: 1 ile ters çevirerek tüm vakayı basitleştirebilir ve depolamayı optimize edebilirsiniz, böylece bir etkinlik için kullanıcı başına bildirim oluşturulur.

Böylece daha çok şöyle görünecekti ..

╔═════════════╗      ╔═══════════════════╗      ╔════════════════════╗
notification       notification_object      notification_change 
╟─────────────╢      ╟───────────────────╢      ╟────────────────────╢
ID           ║←—n:1—║ID                 ║—1:n—→║ID                  
noteObjFK          entityType               noteObjFK           
viewerUserID       entityID                 actionOnEntity      
╚═════════════╝      ╚═══════════════════╝      actorUserID         
                                                ╚════════════════════╝

Umarım bu yardımcı oldu


Harika, bu kapsamlı cevap için teşekkürler. Bu konuyu inceleyeceğim ve başka sorularım olursa size haber vereceğim, ancak bence bu çok iyi açıklıyor.
user45623
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.