弱关联多对多:弱关联指的是单向关系,即A关注B,但不一定B就关注A
需要额外增加2张关系表,分别是关注表和粉丝表(为什么不能只用一张表分2个字段,“关注人”字段和“粉丝”字段?因为1个关系会产生2条记录,那是按“关注人”字段做切分还是按“粉丝”字段做切分呢?加入按“关注人”字段切分,要查询某用户是哪些用户的粉丝,就得全表扫描,失去了分库分表的意义了)
强关联多对多:即A关注B的同时,B也关注了A
增加一张有好友1字段和好友2字段的关系表,每个好友关系关联只用一条记录表示
单表查询用户A的所有好友,建议用:
select * from friend where uid1=A
union
select * from friend where uid2=A
而不要用 select * from friend uid1=2 or uid2=2 (用or是不会走索引查询的)
缺点:同上一个结论,分库分表按“好友1”还是按“好友2”切分?
表设计同弱关联,分别在关注表和粉丝表里各插入2条记录
数据虽然冗余,但每张表都有自己的维度,方便按各自的维度分库分表。
数据冗余的表结构设计
分成2张表就涉及到双写同步,同步方式双写会增加响应时间。
PS:第二次写表发生异常造成不一致情况,考虑手工订正或者新增异常处理服务。
异步推送双写
同步写入第一张表后,通过异步消息方式写第二张表不阻塞后续处理。
缺点:
- 增加系统复杂性,需要消息组件和异步写表服务。
- 存在不一致性的时间窗口,异步双写只能保证最终一致性。
- 要考虑到消息丢失的异常场景处理。
异步拉取双写
同步写第一张表后记录初始status,新增轮询服务区扫该表status是初始的记录,去写第2张表,增加了可靠性。
缺点:
异步推送双写的前2个问题还是存在。
最终一致性的架构设计
新增服务扫描2张表获取数据不一致的记录,进行订正。
缺点: 效率低导致不一致的时间窗口过长。
每次写入后推送消息通知订正服务,实时性高
缺点:增加系统复杂性
数据不一致的场景引出了写数据顺序的问题,根据场景决定如果第一步成功,第二步失败会有什么结果(不存在第一步失败第二部成功的场景)
网友评论