关系型数据库中好友关系的设计

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 设计一群注册用户的好友关系,各自要能查询到自己的好友列表。最早想过用图数据库来进行好友关系存储,但身边没有成熟的案例,网上的资料也比较少。所以还是决定采用传统关系型数据库MySQL来进行设计。

  接到需求,设计一群注册用户的好友关系,各自要能查询到自己的好友列表。最早想过用图数据库来进行好友关系存储,但身边没有成熟的案例,网上的资料也比较少。所以还是决定采用传统关系型数据库MySQL来进行设计。

  好友关系,如果简单设计成一张表的话,随着注册用户的增多,好友关系势必会呈指数级增加,当系统中用户为10个人时,那么完全添加好友的话,关系数据(假设A和B是好友只有一条数据)则为(9+8+...+1)即55条;当系统中注册用户的数量增长到1000个人时,关系数据最大值为(999+998+...+1)即499500。所以如何设计系统,让用户快速查询到好友关系,是个难点。

  这里给出一种思路:根据注册用户的某一个字段(如用户ID),将它的所有好友关系集中存放到一张表中,而不同的用户,会根据这个ID的不同,将它们的好友关系分别散列在不同的数据表中。这样达到了将数据表数据分散,减轻单表压力的目的。但是,按照这个思路设计时,好友的关系必须是双向的,否则A和B的关系,到底是以A的ID进行散列还是B的ID进行散列呢?这样一来,好友的关系数增加了1倍,但是如果散列的足够均衡,这个结果也是可以接受的。市面上很多好友关系在进行设计时,也是采用双向的方式,即A加了B,B同意之后,即建立了双向好友关系,当A删除B的好友关系时,B查询自己的好友列表时,会发现A还在,只有B再删除A,双向的好友关系才会消除。

  接下来的工作是如何将这个散列方案实施下来。这里有两个问题,一个是在初期规划时,我们可能并不知道这个社交群体最终的规模,即无法在初期就创建固定数量的关系表,这个表一定是当容量达到一定规模时动态增长的;第二个是,在追求每张表的数据均衡时,我们还要考虑一种情况,即如果初期存入的一批用户被散列到某张表中(即该批用户指向的好友关系存在该表中),而恰好该批用户的好友关系增长速度远远超过其他批次的用户,造成该表数据急速增长的情况,该如何处理?在此背景下,我们来考虑这个被散列计算的字段该怎么设计。

  对于以上问题,一个简单的思路如下:假设现在有t_a,t_b,t_c,t_d四张表,都用于存放关系,在它们远没有达到存储规划上限时,我们可以就简单根据现有的各自表的容量,来决定注册用户该字段计算出来该指向哪张表。比如a,b,c现在容量都达到了1000条,而d表的容量才100条,那么在注册用户时,我们就将用户该字段设计成计算结果指向d表。我们还可以设计一个容量因子,在单表数量超过预设上限*该容量因子(如0.7)时,即停止将新用户的字段值设计成计算结果指向该表。另外,如果我们设定一个好友关系上限,如最多500个好友,那么预设的表数据上限除以这个数量限制可以得到这张表最多存放多少个不同的用户,这种做法可以保证这些关系表数量不会异常增长到超过我们预设的上限。

  但是,如果我们的系统允许用户无节制的增加好友,那么当用户量不断增长时,上述方案就无法在系统规模不断增长之后还能保证单表关系数量不会突破限制。此时,限制一个用户所有的好友关系在某个单表的方案已经不现实,但我们还是应该尽量这么做,对于单个用户在单表中设置一个关系数量上限,当他的好友关系超过这个数量时,把它存在另外一张表中。那么,如何知道这个用户是否图破了单表存储的设定上限,拥有多张表存储了好友关系,我们可以在注册用户的字段时加一个标记字段,那么查到该用户即可知道这个信息,对于已经突破了单表设定上限的,我们可以再加一张表-突破关系存放表,某用户突破一次,那么在该表中即存一条数据,其中一个字段的值与该用户原先的散列计算值匹配起来可以确定这次突破后存放的新表名称。这样既可快速定位到这些新表的名称,从而查询出所有的好友关系,另外,好友关系表中对单表单用户的好友关系数量做出了限制,所以当有N个表存放了该用户的数据时,那么好友的数量即,(N-1)*固定容量+第N张表的好友数量,所以统计好友总数也不复杂,只需要知道第N张表的数量即可推算出总数。

  暂时想到这么多,欢迎评论留言补充思路或者其它拓展点。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
4月前
|
小程序 JavaScript 安全
【微信小程序-原生开发】转发给好友/群,分享到朋友圈(含单页模式访问云开发数据库的方法)
【微信小程序-原生开发】转发给好友/群,分享到朋友圈(含单页模式访问云开发数据库的方法)
179 0
|
SQL 缓存 NoSQL
社交系统中用户好友关系数据库设计
社交系统中用户好友关系数据库设计
1247 0
|
JSON JavaScript 小程序
小程序里显示附近的人,云开发数据库实现附近的人,按照位置远近排序,附近多少公里内的好友
小程序里显示附近的人,云开发数据库实现附近的人,按照位置远近排序,附近多少公里内的好友
178 0
|
存储 SQL 分布式计算
用户/帖子/好友/订单中心如何进行数据库水平切分
用户/帖子/好友/订单中心如何进行数据库水平切分
|
数据库
LeetCode(数据库)- 好友申请II:谁有最多的好友
LeetCode(数据库)- 好友申请II:谁有最多的好友
91 0
|
数据库
LeetCode(数据库)- 好友申请l:总体通过率
LeetCode(数据库)- 好友申请l:总体通过率
95 0
|
10天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
25 1
|
12天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
28 4
|
19天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
90 1
|
21天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
64 2