zoukankan      html  css  js  c++  java
  • 社交系统中用户好友关系数据库设计

    基础分析
    第一步,有一张用户表,表内包含用户的基本信息,比如账号、姓名、性别等信息。这里用tb_user表示用户信息表。

    ID 用户名
    1 张三
    2 李四
    3 王五
    4 赵六
    第二步,需要将用户与用户直接建立好友关系。这里有两种情况:单向好友关系、互为好友关系。
    - 单向好友关系就是张三在李四的好友列表中,但李四没有在张三的好友列表中;
    - 互为好友关系,如果张三和李四为好友,则双方都在彼此的好友列表中;

    好友关系设计
    无论上面两种关系的哪一种,好友关系表都可以使用下面的设计,表tb_friend:

    ID user_id friend_id
    1 1 2
    2 1 3
    示例中,张三拥有李四和王五两个好友。

    单向好友模式
    如果是单向好友模式,那么两个人互为好友关系则插入的数据应该是这样:

    ID user_id friend_id
    1 1 2
    2 2 1
    也就是张三是李四的好友,李四也是张三的好友。此时使用sql语句查询时只用限定user_id作为条件即可查询出用户的好友列表:

    select * from tb_friend where user_id = 1
    1
    互为好友关系
    因为是互为好友关系,则只需要插入一条数据即可。对应的查询语句为:

    select * from tb_friend where user_id = 1 or friend_id = 1
    1
    2
    当然也可以使用UNION ALL来实现:

    select friend_id as friends from tb_friend where user_id = 1
    UNION ALL --使用UNION ALL,因为不存在重复的
    select user_id as friends from tb_friend where friend_id = 1
    1
    2
    3
    注意事项:
    - user_id1–>friend_id2和user_id2–>friend_id1是相同的记录,不需要重复插入;
    - 为了快速判断两个人是不是好友,可在程序层插入数据前添加一个限制user_id1 < user_id2;
    - 可加入缓存层(Redis或Memcached)来提高性能;
    - 可从数据库层限制(user_id,friend_id)不可重复;

    加入分组
    如果好友数量比较多,关系比较复杂,可引入好友分组,可进行如下改造:

    ID user_id friend_id user_group friend_group
    1 1 2 好友 同学
    2 1 3 同学 同学
    在数据库中添加了user_group,当前user给friend设置的分组,friend_group是当前user的朋友对其设置的分组类别。

    于是,查询好友列表的SQL如下:

    select friend_id as friends ,user_group as my_group from tb_friends where user_id = 1

    UNION ALL

    select user_id as friends , friend_group as my_group from friend_id = 1
    1
    2
    3
    4
    5
    小结
    至此社交系统中好友关系的设计及SQL语句使用基本完成。可根据具体的业务情况进行修改。在查询除好友的id列表之后就可以进行好友信息的查询。此处需要注意的是如果用in语句来查询会有不走索引、sql语句大小限制、性能等问题,可考虑使用左连接进行查询。

    关于好友(社交)关系的数据库设计

    比如QQ或者一些社交网站,好友关系的数据库应该如何设计?于是我自己大概的进行了一些尝试。

    一开始,好友关系比较简单,比如:

     

    这样1,2,3,4互为好友,它的数据库可以这样设计:

    CREATE TABLE IF NOT EXISTS users
    (
    user_id char(10) NOT NULL,
    friend_id char(10) NOT NULL
    );

    INSERT INTO users VALUES('1', '2');
    INSERT INTO users VALUES('1', '3');
    INSERT INTO users VALUES('1', '4');
    INSERT INTO users VALUES('2', '3');
    INSERT INTO users VALUES('2', '4');
    INSERT INTO users VALUES('3', '4');

    SELECT *
    FROM users;

    用两个字段<user_id, friend_id>来构成好友之间的关系,因为双方互为好友就不必重复存储。

    那么要快速地进行好友列表的查询,sql应该这么写:

    -- 查询id: 4的好友列表
    SELECT friend_id AS friends
    FROM users
    WHERE user_id = '4'
    UNION ALL --使用UNION ALL,因为不存在重复的(UNION会判重, 实际在插入时就知道了)
    SELECT user_id AS friends
    FROM users
    WHERE friend_id = '4';
    结果如下:

     

    然鹅,当好友关系比较复杂时,比如加入了好友分组后,我便尝试进行一些改造,假设有如下一种好友关系:

     

    每个人有自己的分组,两人之间可以在不同的分组中,比如3在1的同学分组中,而1在3的好友分组中,那么就必须加入两个字段,一个存储user_id的分组,一个存储friend_id的分组,重新设计如下:

    CREATE TABLE IF NOT EXISTS users_g
    (
    user_id char(10) NOT NULL,
    friend_id char(10) NOT NULL,
    user_group char(10) DEFAULT '默认分组',
    friend_group char(10) DEFAULT '默认分组'
    );

    INSERT INTO users_g VALUES('1', '2', '好友', '好友');
    INSERT INTO users_g VALUES('1', '3', '同学', '好友');
    INSERT INTO users_g VALUES('1', '4', '亲人', '好友');
    INSERT INTO users_g VALUES('2', '3', '亲人', '亲人');
    INSERT INTO users_g VALUES('2', '4', '朋友', '朋友');
    INSERT INTO users_g VALUES('3', '4', '好友', '同学');

    SELECT *
    FROM users_g;

    于是查询好友列表的sql就变成了:

    -- 查询id: 4的好友列表,及其分组
    SELECT friend_id AS friends, user_group AS my_group
    FROM users_g
    WHERE user_id = '4'
    UNION ALL
    SELECT user_id AS friends, friend_group AS my_group
    FROM users_g
    WHERE friend_id = '4';
    结果如下:

    嗯感觉这样设计应该是可以的,当然我也希望有人能给出好的建议什么的啊哈哈~

  • 相关阅读:
    org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON
    小程序用户表wx_user设计
    CSDN支持语法高亮的常用语言(Markdown使用之)
    查看CentOS版本信息
    Java操作MongoDB之mongodb-driver
    使用SpringCache进行缓存数据库查询
    MYSQL:WARN: Establishing SSL connection without server's identity verification is not recommended.
    SpringDataRedis常用方法
    SpringBoot整合Redis进行缓存数据库查询
    java连接neo4j
  • 原文地址:https://www.cnblogs.com/duanxz/p/3634605.html
Copyright © 2011-2022 走看看