天天看点

关注/粉丝 表结构设计及查询(附带SQL)

表主要字段:

id user_id focus_user_id create_time
id 用户id 被关注人id 创建时间
  1.    user_id 设置索引 用于查询 我的关注
  2.    focus_user_id   设置索引 用于查询 我的粉丝
  3.    user_id ,focus_user_id 设置联合唯一索引 数据库约束控制 不会出现重复关注
  4.    create_time 设置索引 用于查询 我的粉丝/我的关注 列表时 按时间倒叙分页查询

在查询时:

1. 查询 A 的关注用户列表:

select focus_user_id from user_focus where user_id = A.userId order by create_time desc           

2. 查询 A 的粉丝列表:

select user_id from user_focus where focus_user_id = A.userId order by create_time desc           

3. 查询 A,B二个用户之间的关注状态:

( SELECT 1 from user_focus where user_id = A.userId and focus_user_id = B.userId )
union all
( SELECT 2 from user_focus where user_id = B.userId and focus_user_id = A.userId )           

这里会返回一个List<Integer> 数组,有四种情况

  •      空数组 A,B 之前无任何关系
  •      [1,2] A,B 相互关注
  •      [1]  A 关注了 B
  •      [2] B 关注了 A

4. 查询 A, B 共同关注

5. 查询 A,B 共同粉丝

由于 4,5 查询 项目中暂时用不到就不写出来了,另外这二个语句在面对 粉丝人数 或关注人多过多时 性能会很差,因为这会导

致数据库大量数据排序

微博在这方面会限制用户关注上限 3000人 ,但是用户的粉丝是不能限制的,好在这类产品在意的是我们的共同关注,而不是我

们的共同粉丝由于限制了关注上线3000 ,所以在一些查询中也不会太慢,例如查询我关注的人他们的关注。

---------------------------------------------------------------分割线-------------------------------------------------------------------------------------

6. 查询我关注的用户他们关注了哪些用户,并排除我关注的用户和自己 。有点拗口,就是类似微博的推荐关注用户

<select id="getXXX" resultType="java.lang.String">
         select distinct B.focus_user_id from user_fans A
         INNER JOIN user_fans B on A.focus_user_id = B.user_id
         LEFT JOIN user_fans C on B.focus_user_id = C.focus_user_id AND C.user_id = #{userId,jdbcType=VARCHAR}
         where A.user_id = #{userId,jdbcType=VARCHAR} AND B.focus_user_id != #{userId,jdbcType=VARCHAR}
         AND C.focus_user_id is NULL limit 10
    </select>           

7. 查询用户A的粉丝,并且这些粉丝是我关注的人。

<select id="getXXX" resultType="java.lang.String">
        SELECT
          A.focus_user_id
        from user_fans A
        INNER JOIN user_fans B on A.focus_user_id = B.user_id
        where A.user_id = #{myUserId,jdbcType=VARCHAR}
        AND B.focus_user_id = #{userId,jdbcType=VARCHAR} limit 3
    </select>