1
dagger 2013-12-25 21:46:39 +08:00 1
既然想到了schemaless,那也可以直接在RDBMS里存JSON啊,notification里搞个data字段,结构化的消息信息转成JSON放里面就可以了
|
3
usoluyun 2013-12-25 22:56:58 +08:00 1
rdbms里面放json不是好主意,主要是因为如果json过大(超过4k)对性能影响还是非常明显的。有条件的还是考虑nosql,或者还是把消息主体细化拆分到不同的表里。
|
4
heroicYang 2013-12-25 23:27:59 +08:00 1
RDBMS 的话还是规规矩矩的范式化设计吧,NoSQL 就揉到一个文档好了。
|
5
zzNucker 2013-12-26 00:36:12 +08:00 1
我是来给lz点赞的,好久没看到这么诚意的问题了。
|
8
gfreezy 2013-12-26 12:17:57 +08:00
我们的提醒的结构用的是 1 结构,实际在使用的时候发现提醒的类型数目有限,基本是可穷举的。这样在实际构造HTML代码的时候比较麻烦,但是逻辑上还是比较简单的。
desc notification: id | sender_id | receiver_id | action | target_id | extra | create_time | delete_time sender_id: 提醒的发起人 receiver_id: 提醒接收人 action: 什么动作触发的提醒 两部分组成,第一部分为行为的代号,第二部分为目标的代号 行为代号: 评论101, 关注102,新朋友103,赞104,做过105,@别人106, 回答(问题) 107, 提问 108, 官方消息109 目标代号: 菜谱1001, 用户1002, 讨论区话题1003,作品1005, 菜单1007, 问题1013 target_id: 触发提醒的动作的承受者 extra: 动作承受者的补充信息,默认为'' create_time: 提醒创建时间 delete_time: 提醒需要被删除的时间 delete_time表示提醒即将被删除的时间,当delete_time为NULL时,这是一条未读提醒。当delete_time为一个合法的时间时,这是一条已读提醒。到达delete_time时,此条提醒被移动到notification_r1表中,此后此条提醒对用户不可见。 用crontab定期根据delete_time来清理提醒。 |
9
dagger 2013-12-26 14:52:15 +08:00
|
11
alex321 2013-12-26 16:16:52 +08:00
可否改变一下思路,采用事件驱动来处理,甚至触发处理呢。
如果单纯采用表的方式处理,在性能上或者及时响应性上会遭遇纠结状况。 |
12
hustlzp OP @alex321
系统中维护一个公用的消息任务队列?有消息产生就往队列里塞,队列的worker负责处理并分发到各user?是这个意思吗? 在stackoverflow上看到的一个回复: http://stackoverflow.com/questions/1315991/design-pattern-notification-system "Create a system queue, each message added to this queue has a list of "consumers" and the content. The main message pump processes each message and sends the message to all consumers. Lets say 2 people befriend each other. You add a message to the main system queue that A is friends with B and consumers are both A and B. When your message "pump" (processor) sees this message it adds it to the queue of A and the queue of B. So now user A and user B have a new message that they are friends. In turn each user has a message processor, so when it sees a message called "I am friends with [someone]" it processes this as add a new entry to the "wall" visible to friends of A that "A is friends with B", etc. This is overly simplistic but hopefully shows how message queues can be used for this (very similar system is used as the windows UI framework) so there is already an existing example and there are plenty of synchonized message queue patterns you can use." |
13
hustlzp OP 过段时间会把notification的实践经验分享出来
|
14
alex321 2013-12-26 17:22:34 +08:00
@hustlzp 类似。如果全部用一个公共队列的话,并发一多估计也是个问题。可以进一步优化一下,公共队列负责队列中时间的捕获,个人的提醒用额外的方式来处理。
这一类属于基础技术架构的东西最好能有负责架构的童鞋参与讨论。 |
16
gfreezy 2013-12-26 19:09:46 +08:00
|
17
alex321 2013-12-26 21:58:26 +08:00
@gfreezy 不清楚题主的设计负载呢,就按照常规的负载来预期的。30w 规模的用户,提醒是基于事件驱动的。典型的状态是,用户 a 在话题中提醒 b,或者 a 评论了 b 的内容,系统将对 b 提醒;并且,b 关注了 a 的情形下,a 的其他操作事件也将触发系统对 b 的提醒。
如果题主所涉及到的是直接提醒,也就是上述情形中的前者,可以参考下 discuz! 的提醒,相对容易一些。 |
18
gfreezy 2013-12-26 22:18:18 +08:00
|
19
hustlzp OP |
20
dawncold 2013-12-27 03:12:48 +08:00
感觉用一个通用的notification表,不同类型的消息只需要title不一样就可以了,用户看到的就是“xxx赞了你的回复”,"xxx回复了你的主题","您购买的商品已发货"等等,等用户点击具体的消息后会看到具体的内容。
另外根据你的表设计,有一种情况就是,如果一个用户在看消息的时候,可能消息会有很多条你会做分页,那么用户的notification_checked_at = greatest(notification.created_at on this page) |
21
bombless 2013-12-27 04:50:09 +08:00
楼主这种情况的话类似的问题我感觉非常普遍,很关心大家的讨论结果。如果是我的话也很不喜欢在关系型数据库加json的想法,不过我看过的大概三到四个类似实现都是用类似的手段,尽管用的不是json
|
23
Pure88 2016-06-29 18:06:27 +08:00
哈哈,我转互联网第一个项目,就干过跟你同样的傻事。
当时我的 notification 表 就是采用分离设计的。 如果是现在,我可能会把不同的 notification 设计成 json 协议数据,存到 notification 表里面,上层取出来解析一下,然后生成动态 html 了。 |