方案一
follow(关注关系表)
字段名
类型
索引
注解
id
primaryKey()
user_id
integer()->unsigned()->notNull()
normal
用户
followed_user
integer()->unsigned()->notNull()
关注的人的id
status
smallInteger()->unsigned()->defaultValue(1)
关注状态:是否取消关注等
created_at
integer()->unsigned()->notNull()
normal
updated_at
integer()->unsigned()->notNull()
normal
用户每关注一个人,都会在表中添加一条数据
优点:
1.设计简单,方便查询
2.可以区分关注的每一个人进行特殊处理(例如,不同人的关注事件,是否互粉,特别关注等),方便扩展
3.好写代码。
缺点:
当用户量大时表数据量会非常庞大,因此必需要采用水平分表的方式将用户分散到多个表。
例如,有10万用户,ID为1~10000的用户放在表1(follow_1), ID为10001~20000的用户放在表2(follow_2), 以此类推。
然而分表后又会面临另一个问题,当被关注者依照多个表反查自己的粉丝时将会非常麻烦。因此需要再建一个粉丝表:
fans(粉丝表)
字段名
类型
索引
注解
id
primaryKey()
user_id
integer()->unsigned()->notNull()
normal
用户
follower
integer()->unsigned()->notNull()
粉丝
status
smallInteger()->unsigned()->defaultValue(1)
关注状态:是否取消关注等
created_at
integer()->unsigned()->notNull()
normal
updated_at
integer()->unsigned()->notNull()
normal
此数据表依然需要做水平分表处理。
方案二
follow(关注关系表)
字段名
类型
索引
注解
id
primaryKey()
user_id
integer()->unsigned()->notNull()
唯一
用户
followed_user
text
关注的人
follower
text
粉丝
created_at
integer()->unsigned()->notNull()
normal
updated_at
integer()->unsigned()->notNull()
normal
以json格式记录每个用户关注的人和粉丝
优点:
1.每个用户只有一条记录
2.方便查询
缺点:
1.当粉丝数或关注的人数过大时,followed_user 和 follower 字段的数据长度会非常大,当用户关注的人或者粉丝数达到十万级别时,一条数据的数据量将会达到 兆 级别,将会极大地降低mysql的查询和php数据处理的效率。
2.每一次使用该表时都要将整条数据取出进行计算,对资源耗费太过严重。
方案三
使用redis的Hash数据类型
Redis hash是一个string类型的field和value的映射表。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
每个用户分一张hash表,表名为用户id(可加前缀或后缀)
用户每关注一个人,便在hash表中添加一条数据
field: 关注用户的id
value:关注时间
user_1
field
value
2
1483423443
3
1483423445
13
1483423440
...
...
user_2
field
value
1
1483423443
5
1483423445
10
1483423440
...
...
......
优点
1.查询处理速度快。
缺点
1.消耗服务器内存和CPU。最好使用一台单独的服务器来运行 Redis
2.数据查询,处理不如关系型数据库灵活。
3.开发步骤复杂,学习成本高。
参考
论坛相关讨论
PPT等资源下载