Розуміння системи повідомлень


15

Я розглядав, як створити систему сповіщень на ІП та інших місцях, і знайшов собі рішення, яке є прийнятою відповіддю тут: /programming/9735578/building-a-notification-system, яка використовує ця структура:

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

Повідомлення про те, що щось (об'єкт = подія, дружба ..) змінюється (дієслово = додається, запитується ..) кимось (актором) і повідомляється користувачеві (темі). Ось нормалізована структура даних (хоча я використовував MongoDB). Вам потрібно повідомити певних користувачів про зміни. Отже, це сповіщення від користувачів. Це означає, що якщо було залучено 100 користувачів, ви генеруєте 100 сповіщень.

Спочатку я думав, що розумію цей підхід, але коли я почав готуватися до його здійснення, зрозумів, що, мабуть, не розумію його особливо добре. Останні кілька коментарів до відповіді - це питання інших користувачів, які також мали проблеми з розумінням рішення.

Я не впевнений, що це саме та модель, яку я закінчу наступним, але враховуючи кількість оновлень, які я маю, я впевнений, що це піде на користь мені, щоб зрозуміти це, і я, безумовно, хотів би дізнатися більше. Я сподіваюся, що це також буде корисним для інших, хто зіткнувся з рішенням цього рішення (до речі, у мене не вистачає інтернет-балів, щоб залишити коментар до цієї відповіді, спрямованої на це питання, будь-хто інший, будь ласка!)

Запитання

Якщо я правильно це зрозумів, notiObjectID - це зовнішній ключ, що вказує на таблицю_об'єктів notification_object , а notificationID - зовнішній ключ, що вказує на таблицю повідомлень . Здається, що об'єкт повинен бути зовнішнім ключем, що посилається на ідентифікатор запису бази даних, про який йдеться у повідомленні (наприклад, конкретна подія чи публікація), але хіба нам тоді не потрібно інше поле, щоб вказати, до якої таблиці належить ідентифікатор?

Автор писав

notice_object.object ідентифікує тип зміни, як рядок "дружба". Фактична посилання на змінений об'єкт із його додатковими даними, про які я говорю, є у notification_change.notificationObjectID

що, здається, не має для мене сенсу. Object - це рядок (enum?), А notivoObjectID - це зовнішній ключ, що посилається на об'єкт, про який йдеться? Тоді як взагалі пов’язані середня та права таблиці?

Здається, що середня таблиця вказує, про який об’єкт (або тип об’єкта) йдеться про сповіщення, наприклад, про подію чи публікацію. Тоді ми можемо мати багато записів у noti_change, які вказують на той самий тип об'єкта, що дозволяє нам поєднувати сповіщення (наприклад, "25 користувачів, розміщених на стіні X) - отже, відносини 1: n між середньою та правою таблицями.

Але чому між лівою та середньою таблицями існує співвідношення 1: n? Чи будемо ми давати "25 користувачам, розміщеним на стіні Сема" та "Мері оновила свій події" Пікнік-пікнік "той самий ідентифікаційний номер сповіщення? Якщо всі сповіщення для одного користувача мають той самий ідентифікаційний номер сповіщення, навіщо нам взагалі потрібна таблиця на ліворуч?

Питання про виставу - скажімо, Джон розміщує коментар до події пікніка Марії. Здається, нам знадобиться зробити пошук, щоб перевірити, чи існує вже сповіщення_об'єкт для пікніка Марії, перш ніж ми створили запис_міни повідомлення . Це негативно вплине на результативність, чи це не є проблемою? Продовжуючи запитання з попереднього пункту, як би ми дізналися, на який запис сповіщення вказати об’єкт сповіщення ?

Відповіді:


8

Дякую за такі ретельні запитання, і вибачте за всю плутанину - коментувати через 1 рік після первинної відповіді важко, а зараз через 3 роки .. початкові думки зникають і мене також бентежать, але я боюся редагувати дірку, тому що я не працюю про зберігання сповіщень у бекенді зараз і не впевнений, чи я буду робити судження без практичного застосування

Я думаю, що під час написання:

  • Так і ні, notificationID був іноземним ключем, notivobjectID не був. Вам потрібно ще одне поле ФК, щоб зв’язати таблиці разом. Я звинувачую свій досвід монго в тому, що я не дуже зрозумів про це :(
  • Так і ні, noti_object.object є невиразним, тому що ви можете мати його як рядок або щось складне (JSON або FK). У моєму випадку це був просто іменник.

Отже, все залежить від того, як виглядатимуть ваші сповіщення. Для простого випадку, ви просто хочете пов’язати ціле сповіщення з якоюсь URL-адресою, наприклад, зі сторінкою друзів. Ось чому корисний об'єкт (objectType) як рядок - ви прив'язуєте до нього URL-адреси.

Повідомлення "у вас є 3 запити друзів " можна зберігати по-різному.

Якщо ви хочете показати їх по одному - у вас буде 3 сповіщення, 3 об’єкти сповіщень (friend_request) та 3 записи в noti_change, які посилаються на певного користувача-друга.

Якщо ви хочете показати одне сповіщення - у вас буде 1 сповіщення, 1 / більше об’єктів та 3 / більше дій. Отже, у такому складному випадку, як «у вас є 3 запити друзів від користувача A, користувача B, користувача C» - ви використовуєте notiObjectID для кожного користувача та маєте кілька посилань у своєму повідомленні.

Чи варто використовувати 1 або 3 friend_request об’єкти? Це залежить від

  1. Що таке об’єкт і що таке дія. Чи «стаття сподобалася / коментується»? Або це «подобається / додано коментар» і об’єкт ієрархії зв’язується лише під час відображення? Ось фейсбук відрізняє «фото коментування» від «згадування користувача», який семантично здається дуже близьким - у вас однакова фотографія, той же актор, але різні сповіщення, які могли бути об'єднані разом

введіть тут опис зображення

  1. Чи можете ви видалити сповіщення або вам потрібна історія? Тож якщо я надішлю запит на дружбу, а потім скасую його, або прокоментую, а потім видалюю статтю, як-от, а потім на відміну від чогось - чи повинен він показувати цю історію (як іншу дію) кінцевому користувачеві як дві різні дії? Напевно, ні. Крім того, його технічно більш складний - вам потрібно шукати, чи є існуючий_об'єкт сповіщень, додати до нього нове_мінювання_зміни (якщо ні - додати новий об’єкт), щоб пізніше мені потрібно було здійснити пошук через noti_change, щоб його видалити. Натомість я б просто додати ще одне сповіщення_об'єкт до того ж сповіщення і видалити його, якщо його пішли з видаленням каскаду.

З іншого боку, можуть бути випадки, коли може бути корисним групування дій, де нічого не стирається з історії.

Я думаю, що саме тому під час написання було зроблено співвідношення між лівою та середньою таблицями 1: n, щоб ви могли згрупувати сповіщення не лише акторів одного і того ж об'єкта (середньоправі таблиці), але й кількох об'єктів / сутностей.

Але впевнено, ви можете спростити весь регістр та оптимізувати сховище, повернувши зв'язок ліво-середини на n: 1, щоб у вас з’явилися сповіщення від користувачів, що генеруються для однієї події.

Так, щоб це виглядало більше так.

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

Сподіваюся, що це допомогло


Чудово, дякую за цю грунтовну відповідь. Я перегляну це питання і повідомляю, чи є у мене ще запитання, але я думаю, що це дуже добре пояснює.
user45623
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.