数据库架构设计(四)——多对多业务无限容量

应用场景

类似于好友中心,好友和好友之间是多对多的关系,这里也分为两种类型,一种为强好友关系,例如QQ好友,需要相互同意才能关联;另一种是弱好友关系,例如微博关注,不需要确认就可以关注。

但是,总体的关系是 uid:fuid——>n:n,下面主要是以强好友作为主要场景来分析的。

整体架构

1、强好友关系-元数据实现一

通过强好友关系业务分析,很容易了解到,其核心元数据为:

friend(uid1, uid2);

其中:

uid1,强好友关系中一方的uid

uid2,强好友关系中另一方的uid

uid=1的用户添加了uid=2的用户,双方都同意加彼此为好友,这个强好友关系,在数据库中应该插入记录还是记录呢?

回答:都可以,为了避免歧义,可以人为约定,插入记录时uid1的值必须小于uid2。

2、强好友关系-元数据实现二

强好友关系是弱好友关系的一个特例,A和B必须互为关注关系(也可以说,同时互为粉丝关系),即也可以使用关注表和粉丝表来实现:

guanzhu(uid, guanzhu_uid);

fensi(uid, fensi_uid);

例如:用户A(uid=1)和用户B(uid=2)为强好友关系,即相互关注:

用户A(uid=1)关注了用户B(uid=2),A多关注了一个用户,B多了一个粉丝,于是:

guanzhu表要插入这一条记录

fensi表要插入这一条记录

同时,用户B(uid=2)也关注了用户A(uid=1),B多关注了一个用户,A多了一个粉丝,于是:

guanzhu表要插入这一条记录

fensi表要插入这一条记录

数据冗余是实现多对多关系水平切分的常用实践

对于强好友关系的两类实现:

friend(uid1, uid2)表

数据冗余guanzhu表与fensi表(后文称正表T1与反表T2)

在数据量小时,看似无差异,但数据量大时,数据冗余的优势就体现出来了:

friend表,数据量大时,如果使用uid1来分库,那么uid2上的查询就需要遍历多库

正表T1与反表T2通过数据冗余来实现好友关系,分别存在于两表中,故两个表都使用uid来分库,均只需要进行一次查询,就能找到对应的关注与粉丝,而不需要多个库扫描

如何进行数据冗余

接下来的问题转化为,好友中心服务如何来进行数据冗余,常见有三种方法。

方法一:服务同步冗余

顾名思义,由好友中心服务同步写冗余数据,如上图1-4流程:

业务方调用服务,新增数据

服务先插入T1数据

服务再插入T2数据

服务返回业务方新增数据成功

优点:

不复杂,服务层由单次写,变两次写

数据一致性相对较高(因为双写成功才返回)

缺点:

请求的处理时间增加(要插入次,时间加倍)

数据仍可能不一致,例如第二步写入T1完成后服务重启,则数据不会写入T2

如果系统对处理时间比较敏感,引出常用的第二种方案

方法二:服务异步冗余

数据的双写并不再由好友中心服务来完成,服务层异步发出一个消息,通过消息总线发送给一个专门的数据复制服务来写入冗余数据,如上图1-6流程:

业务方调用服务,新增数据

服务先插入T1数据

服务向消息总线发送一个异步消息(发出即可,不用等返回,通常很快就能完成)

服务返回业务方新增数据成功

消息总线将消息投递给数据同步中心

数据同步中心插入T2数据

优点:请求处理时间短(只插入1次)

缺点:

系统的复杂性增加了,多引入了一个组件(消息总线)和一个服务(专用的数据复制服务)

因为返回业务线数据插入成功时,数据还不一定插入到T2中,因此数据有一个不一致时间窗口(这个窗口很短,最终是一致的)

在消息总线丢失消息时,冗余表数据会不一致

如果想解除“数据冗余”对系统的耦合,引出常用的第三种方案

方法三:线下异步冗余

数据的双写不再由好友中心服务来完成,而是由线下的一个服务或者任务来完成,如上图1-6流程:

业务方调用服务,新增数据

服务先插入T1数据

服务返回业务方新增数据成功

数据会被写入到数据库的log中

线下服务或者任务读取数据库的log

线下服务或者任务插入T2数据

优点:

数据双写与业务完全解耦

请求处理时间短(只插入1次)

缺点:

返回业务线数据插入成功时,数据还不一定插入到T2中,因此数据有一个不一致时间窗口(这个窗口很短,最终是一致的)

数据的一致性依赖于线下服务或者任务的可靠性

上述三种方案各有优缺点,可以结合实际情况选取。

数据冗余固然能够解决多对多关系的数据库水平切分问题,但又带来了新的问题,如何保证正表T1与反表T2的数据一致性呢?下一讲我会特殊再讲一讲数据一致性的同步方法。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180425G0UTI500?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券