返回信息流题目如下:某交友网站,约有会员1000W,每个会员都可能是另一个会员的好友,请您设计一个数据库,用来表示这种好友关系。数据库使用Mysql。
我的设计思路如下:
建立一个表,暂定名称为Friends,含3个自段
id,自动增加,做为索引
uid,用户的id
fid,用户的好友id
如果限定每个会员最多可以添加500个好友,那么这个表的记录最多将会达到1000W*500,也就是 500亿条记录,这样的话,数据库的查询效率是会非常非常低的。
请问大家,还有更好的设计方法吗?
这是我后来想到的分表存储
回来后我才想到可以分表存储,为了保证每个表的记录不超过2000w条,那么可以根据UID来分表,每个表中最多含有4w个uid,总共将分为250个表,不知道这样的效率会不会提高很多呢,继续向大家请教
这是一条镜像帖。来源:北邮人论坛 / database / #1677同步于 2007/12/22
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Database机器人发帖
面试时遇到的一道数据库设计题,来此请教大家
adnin
2007/12/22镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
首先要设计好结构,其次,横向或者纵向切分,还有通过主从库达到读写分离。大概都是这种思路吧。。
【 在 adnin (超级管理员) 的大作中提到: 】
: 题目如下:某交友网站,约有会员1000W,每个会员都可能是另一个会员的好友,请您设计一个数据库,用来表示这种好友关系。数据库使用Mysql。
: 我的设计思路如下:
: 建立一个表,暂定名称为Friends,含3个自段
: ...................
【 在 fbsd 的大作中提到: 】
: 首先要设计好结构,其次,横向或者纵向切分,还有通过主从库达到读写分离。大概都是这种思路吧。。
您能说详细点吗
数据库的效率应该不是问题,对于OLTP来说,查询的值一般都是少量的,1000W条记录那么索引总共最多只有四层,这样找到一条记录,可能访问到的块最多五个。
反而,你这样设计上来说,对于程序的设计支持不是很好,举个例子来说,当需要删除某个用户,需要做的事,包括删除这个用户(uid),以及与之相关的用户(fid)中的在这个用户的uid,对于程序的维护是不利的。
这种设计上的限制应当尽可能的去利用主外键实现,毕竟,你不能让程序去实现主外键约束,用这个库的程序可不只一个。
所以我的建议是:应当建立多张表。至少两张,一个是用户表,用来保存用户信息,另一个是用户关系表(这个表中两个用户uid1和uid2均为外键,reference on user表)
初步想法。。
【 在 z0zi 的大作中提到: 】
: 数据库的效率应该不是问题,对于OLTP来说,查询的值一般都是少量的,1000W条记录那么索引总共最多只有四层,这样找到一条记录,可能访问到的块最多五个。
: 反而,你这样设计上来说,对于程序的设计支持不是很好,举个例子来说,当需要删除某个用户,需要做的事,包括删除这个用户(uid),以及与之相关的用户(fid)中的在这个用户的uid,对于程序的维护是不利的。
: 这种设计上的限制应当尽可能的去利用主外键实现,毕竟,你不能让程序去实现主外键约束,用这个库的程序可不只一个。
: ...................
你说的没错
但是这个题目要求只是设计一个好友的关系表,用户表必然是有的,但不属于本题目的范围
用一张表不行吗?
pk number,
userid varchar2,
friendsList varchar2
friendsList逗号分割好友id,当然查询,添加,删除和其他操作相对复杂
交友网站并不见得就是OLTP,小网站就一个服务器也不是不可能的
对于这种好友关系,一般来说是通过外键关联表来解决的,在楼主给出的题目下,建立一个基于用户基础信息表的自关联表,记录用户的关联情况。
【 在 walkman 的大作中提到: 】
: 用一张表不行吗?
: pk number,
: userid varchar2,
: ...................
,号隔开是最不可行的办法。会严重降低效率,包括反响查询和编辑删除
三楼的方案是非常正确的。如果数据实在是太多的,可以采用别的技术来处理,但是数据库模式的设计应该这样。我对mysql不熟,没法具体说出可以采用那些技术。但是在oracle中可以使用表/索引分区,聚簇索引,并行查询来处理。基本上这个数据量不是问题,只要索引建得正确。