PHP群:95885625 Hbuilder+MUI群:81989597 站长QQ:634381967
    您现在的位置: 首页 > 开发编程 > PHP教程 > 正文

    实现微博关注数据库关系的方案分析

    作者:admin来源:itlipeng浏览:时间:2017-10-12 19:52:02我要评论
    分享到
    导读:关注关系产生的四种关系状态关注粉丝双向关注(互粉)无关系用词follower表示粉丝 – 追随者用词following表示关注 – 追随设...
    关注关系产生的四种关系状态
    1. 关注
    2. 粉丝
    3. 双向关注(互粉)
    4. 无关系
    • 用词follower表示粉丝 – 追随者
    • 用词following表示关注 – 追随

    设计的结构必须能满足以下功能:

    1. 查询关注列表
    2. 查询粉丝列表
    3. 查询双向关注列表
    4. 判断两个用户的关系
    5. 查询带关系状态的任一列表

    用一行纪录表示关注和粉丝,字段u2的值表示粉丝,u1表示被关注者。

    Table: user(用户表)

    实现微博关注数据库关系的方案分析

    Table: follower(u2表示粉丝, u1表示被关注的人)

    实现微博关注数据库关系的方案分析

    查询用户id = 1的关注列表

    SELECT * FROM follower WHERE u2 = 1
    查询用户id = 1的粉丝列表

    SELECT * FROM follower WHERE u1 = 1
    查询用户id = 1的双向关注列表
    SELECT t1.* FROM (SELECT * FROM follower WHERE u2 = 1) AS t1 INNER JOIN follower t2 ON t1.u1 = t2.u2 LIMIT 10
    判断两个用户的关系(id = 1 –> id = 5)

    SELECT * FROM follower WHERE (u2 = 1 or u1 = 1) AND (u2 = 5 or u1 = 5) LIMIT 3
    id = 1的用户查询所有 id < 5的用户,并显示关系

    实现微博关注数据库关系的方案分析

     

    如上图所示,要查询的用户的那个圈,被分成了四个部分(上面讲的四种状态):

    关注了我的用户
    和我互粉的用户
    我关注了的用户
    我未关注的用户
    以上复杂的集合关系,通过单一SQL根本无法实现。

    要查询的用户与粉丝集合的交集:

    SELECT * FROM

    (SELECT * FROM user WHERE id < 5) AS t1
    INNER JOIN

    (SELECT * FROM follower WHERE u1 = 1) AS t2

    ON t1.id = t2.u2
    要查询的用户与关注集合的交集:

    SELECT * FROM

    (SELECT * FROM user WHERE id < 5) AS t1
    INNER JOIN

    (SELECT * FROM follower WHERE u2 = 1) AS t3

    ON t1.id = t3.u1
    其他的部分可以通过以上两步查询出来的数据,在内存中作计算得出。

    因为关注关系是互相的,用一行纪录即可表示。以上的设计其实是把关注和粉丝的概念用一行纪录表达。这样会引来一个缺点,当follower非常大的时候,对follower表进行分片,如果按u1或者u2分片,假设按u1分片,那么将导致关注列表,即下面的查询要做聚合。

    SELECT * FROM follower WHERE u2 = 1
    选择u1分片后,u2 = 1的数据行将会落到不同的分片上。

    SELECT * FROM follower_0 WHERE u2 = 1
    UNION
    SELECT * FROM follower_1 WHERE u2 = 1
    而粉丝列表的查询不会受影响,同一个用户的所有粉丝分在一个片上。

    SELECT * FROM follower_1 WHERE u1 = 1
    如果按u2分片,同样也会导致粉丝列表会落在不同的分片上。两个查询不可能同时满足分片。

    如果分片是跨数据库或者是跨主机的方案,问题会变得更复杂。

    针对方片的优化方案

    可以用冗余数据的办法来解决数据分片带来的问题,即将关注和粉丝分2个表存放。 用follower表存放粉丝
    用following表存放关注

    当用户Ub关注Ua,分别往follower, following写入一行纪录。 (Ua -> Ub) 只是他们表示的含义不同。

    follower表示Ua的粉丝是Ub
    following表示Ub关注Ua

    分片的时候,同时对follower和following进行分片。同时上面分析的所有查询方法也要相应改变,思路还是一样,只是单个表的自联接变成2个表的联接。

    以上方案缺点就是数据量会增加一倍,进行关注或者取消关注的写操作会多一次,要同时维护2个表的数据。

    以上优化虽然解决了一些问题,但同时也带来一些问题。可见关系型数据库在处理用户关系的时候,表现得很吃力。我们不得不承认,虽然叫“关系”型数据库却不太懂得处理集合关系。

    转载请注明(B5教程网)原文链接:http://www.bcty365.com/content-10-6034-1.html
    相关热词搜索:
    网友评论: