牛客社区所有的表和SQL语句

发布于:2024-04-23 ⋅ 阅读:(24) ⋅ 点赞:(0)

文章目录

1 帖子表 discuss_post

1.1 字段描述

描述 字段 类型
帖子Id,主键 id int
贴子所属的用户id,帖子是由谁发表的 user_id varchar(45)
帖子标题 title varchar(100)
帖子内容 content text
帖子类型:0-普通; 1-置顶; type int
帖子状态:0-正常; 1-精华; 2-删除; status int
帖子创建时间 create_time timestamp
帖子评论数量(回帖、评论、回复) comment_count int
帖子分数(根据分数进行热度排行) score double

1.2 相关功能描述

1.2.1 分页查询帖子

对应接口

List<DiscussPost> selectDiscussPosts(int userId, int offset, int limit, int orderMode);

注意事项

  1. 以下所有查询都是查未被删除的帖子,即status != 2。
  2. 如果userId不为0,即要查询某个用户的帖子。
  3. 如果 orderMode 为 0,先按照帖子类型(置顶1、普通0)降序排序,让置顶的帖子放在前面,type一样的帖子按照时间顺序降序排序,让先发表的帖子放在前面。
  4. 如果 orderMode 为 1,表示按照热度查询,先按照帖子类型(置顶1、普通0)降序排序,让置顶的帖子放在前面,type一样的帖子分数降序排序,让分数高的帖子放在前面,如果分数一样,按照时间排序,把先发布的帖子放在前面。

对应SQL

<select id="selectDiscussPosts" resultType="DiscussPost">
    select <include refid="selectFields"></include>
    from discuss_post
    where status != 2
    <if test="userId!=0">
        and user_id = #{userId}
    </if>
    <if test="orderMode==0">
        order by type desc, create_time desc
    </if>
    <if test="orderMode==1">
        order by type desc, score desc, create_time desc
    </if>
    limit #{offset}, #{limit}
</select>

1.2.2 查询帖子总数量

对应接口

int selectDiscussPostRows(@Param("userId") int userId);

注意事项

  1. 查询的是查未被删除的帖子,即status != 2。
  2. 如果userId不为0,表明要查询某个用户发布的帖子总数量,此时应该假设where条件判断。

对应SQL

<select id="selectDiscussPostRows" resultType="int">
    select count(*)
    from discuss_post
    where status != 2
    <if test="userId!=0">
        and user_id = #{userId}
    </if>
</select>

1.2.3 插入一条帖子记录

对应接口

int insertDiscussPost(DiscussPost discussPost);

注意事项

传入的是帖子对象

对应SQL

<insert id="insertDiscussPost" parameterType="DiscussPost" keyProperty="id">
    insert into discuss_post(<include refid="insertFields"></include>)
    values(#{userId},#{title},#{content},#{type},
    #{status},#{createTime},#{commentCount},#{score})
</insert>

1.2.4 根据帖子ID查询某条帖子

对应接口

DiscussPost selectDiscussPostById(int id);

注意事项

查询的是未被删除的帖子,所以status != 2。

对应SQL

<select id="selectDiscussPostById" resultType="DiscussPost">
    select <include refid="selectFields"></include>
    from discuss_post
    where status != 2 and id = #{id}
</select>

1.2.5 更新帖子评论数量

对应接口

int updateCommentCount(int id, int commentCount);

注意事项

更新帖子评论数量要和新增帖子放在同一个事务中,防止出现数据不一致问题。

对应SQL

<update id="updateCommentCount">
    update discuss_post set comment_count = #{commentCount} where id = #{id}
</update>

1.2.6 更新帖子类型

对应接口

int updateType(int id, int type);

注意事项

对应SQL

<update id="updateType">
    update discuss_post set type = #{type} where id = #{id}
</update>

1.2.6 更新帖子状态

对应接口

int updateStatus(int id, int status);

注意事项

对应SQL

<update id="updateStatus">
    update discuss_post set status = #{status} where id = #{id}
</update>

1.2.7 更新帖子分数

对应接口

int updateScore(int id, double score);

注意事项

对应SQL

<update id="updateScore">
    update discuss_post set score = #{score} where id = #{id}
</update>

2 用户表 user

2.1 字段描述

描述 字段 类型
用户id id int
用户名 username varchar(50)
用户密码 password varchar(50)
salt varchar(50)
用户邮箱 email varchar(100)
用户类型:0-普通用户; 1-超级管理员; 2-版主; type int
用户状态:0-未激活; 1-已激活; status int
注册用户的激活码 activation_code varchar(100)
用户头像 header_url varchar(200)
用户创建时间 create_time timestamp

2.2 相关功能描述

2.2.1 根据用户ID查询用户

对应接口

User selectById(int id);

注意事项

对应SQL

<select id="selectById" resultType="User">
    select <include refid="selectFields"></include>
    from user
    where id = #{id}
</select>

2.2.2 通过用户名查询用户

对应接口

User selectByName(String username);

注意事项

对应SQL

<select id="selectByName" resultType="User">
    select <include refid="selectFields"></include>
    from user
    where username = #{username}
</select>

2.2.3 根据用户邮箱查询用户

对应接口

User selectByEmail(String email);

注意事项

对应SQL

<select id="selectByEmail" resultType="User">
    select <include refid="selectFields"></include>
    from user
    where email = #{email}
</select>

2.2.4 插入一条用户记录

对应接口

int insertUser(User user);

注意事项

对应SQL

<insert id="insertUser" parameterType="User" keyProperty="id">
    insert into user (<include refid="insertFields"></include>)
    values(#{username}, #{password}, #{salt}, #{email}, #{type}, #{status}, #{activationCode}, #{headerUrl}, #{createTime})
</insert>

2.2.5 更新用户状态

对应接口

int updateStatus(int id, int status);

注意事项

对应SQL

<update id="updateStatus">
    update user set status = #{status} where id = #{id}
</update>

2.2.6 更新用户头像

对应接口

int updateHeader(int id, String headerUrl);

注意事项

对应SQL

<update id="updateHeader">
    update user set header_url = #{headerUrl} where id = #{id}
</update>

2.2.7 更新用户密码

对应接口

int updatePassword(int id, String password);

注意事项

对应SQL

<update id="updatePassword">
    update user set password = #{password} where id = #{id}
</update>

3 登录凭证表 login_ticket

3.1 字段描述

描述 字段 类型
登录凭证id id int
用户id,谁的登录凭证 user_id int
登录凭证字符串,一串UUID,保证每个登录用户不重复 ticket varchar(45)
0-有效; 1-无效; status int
过期时间,一段时间后登录凭证会过期,用户需要重新登录 expired timestamp

3.2 相关功能描述

3.2.1 插入一条登录凭证记录

对应接口

int insertLoginTicket(LoginTicket loginTicket);

注意事项

在插入一条登录凭证信息后需要将主键id回填,useGeneratedKeys = true, keyProperty = “id”
我觉得这个回填功能并没有使用到

对应SQL

@Insert({
        "insert into login_ticket(user_id,ticket,status,expired) ",
        "values(#{userId},#{ticket},#{status},#{expired})"
})
// @Options(useGeneratedKeys = true, keyProperty = "id")  // 这个回填并没有被使用到。

3.2.2 根据凭证字符串查询登录凭证

对应接口

LoginTicket selectByTicket(String ticket);

注意事项

对应SQL

@Select({
        "select id,user_id,ticket,status,expired ",
        "from login_ticket where ticket=#{ticket}"
})

3.2.3 根据凭证字符串修改对应登录凭证的状态

对应接口

int updateStatus(String ticket, int status);

注意事项

对应SQL

@Update({
        "<script>",
        "update login_ticket set status=#{status} where ticket=#{ticket} ",
        "<if test=\"ticket!=null\"> ",
        "and 1=1 ",
        "</if>",
        "</script>"
})

以下是对代码的解释:

解释 MyBatis 注解中的 @Update 使用

这段代码是一个 MyBatis 框架中使用的数据库更新操作的注解定义。这里使用的是 MyBatis 的动态 SQL 特性来构造 SQL 更新语句。让我们逐一分析这个代码的组成部分:

  1. @Update 注解:

    • @Update 是用于标识一个方法执行数据库的更新操作(即 SQL 的 UPDATE 语句)。
    • 在大括号 {} 内部,你可以定义实际执行的 SQL 语句。
  2. 使用 <script> 标签:

    • <script> 标签在这里用来包围可能包含动态 SQL 部分的 SQL 语句。
    • MyBatis 使用 XML 类似的标签来处理动态 SQL 语句,即使在注解中也可以使用这些标签。
  3. 更新语句:

    • update login_ticket set status=#{status} where ticket=#{ticket} 是一个基础的 SQL 更新语句,它的作用是更新 login_ticket 表中的 status 字段。更新的条件是 ticket 字段等于方法参数 ticket 的值。
  4. 使用 <if> 标签进行条件判断:

    • <if test=\"ticket!=null\"> 是一个条件语句,用来检查输入参数 ticket 是否不为 null
    • 这里的条件实际上并没有改变 SQL 逻辑,因为 and 1=1 是一个总是为真的条件。这种写法通常用于测试或者作为编写更复杂逻辑的占位符。
  5. 方法签名:

    • int updateStatus(String ticket, int status); 这个方法接收两个参数:ticketstatus,并返回一个整型值,表示更新操作影响的行数。
    • 在 MyBatis 中,更新操作通常返回一个整数,表示 SQL 语句影响的行数。

总结来说,这段代码通过 MyBatis 注解定义了一个更新数据库中 login_ticket 表的操作。它使用动态 SQL 来确保只有当 ticket 不为 null 时才执行更新,虽然在这个特定的示例中,and 1=1 没有实际的过滤作用,更多的可能是为了展示如何在条件内部使用固定的真值条件。

4 评论表 comment

4.1 字段描述

描述 字段 类型
回帖/评论/回复id id int
用户id,这条回帖/评论/回复是谁发的 user_id int
在哪个实体类型下面:1-帖子;2-回帖 entity_type int
实体id entity_id int
被回复的用户id,0-不是回复,是回帖或评论,不为0-回复的用户id target_id int
回帖/评论/回复的内容 content text
回帖/评论/回复的状态:0-正常;1-删除 status int
回帖/评论/回复的创建时间 create_time timestamp

可以这样理解:在帖子下的评论,和在评论下的评论
也可以按照下面的理解
在这里插入图片描述

在这里插入图片描述

以这三条数据为例

在这里插入图片描述

在这里插入图片描述

以下是另外一组数据:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述)

4.2 相关功能描述

4.2.1 分页查询某个帖子的回帖,查询某个回帖下的所有评论和回复

对应接口

List<Comment> selectCommentsByEntity(int entityType, int entityId, int offset, int limit);

注意事项

  1. 查询的回帖/评论/回复都是存在的,未被删除的,即 status = 0
  2. 当 entityType = 1:表示需要分页查询某个帖子下所有的回帖,此时会利用offset和limit参数
  3. 当 entityType = 2:表示需要查询某个回帖下的所有评论和回复,此时ofsset = 0, limit = Integer.MAX_VALUE

对应SQL

<select id="selectCommentsByEntity" resultType="Comment">
    select <include refid="selectFields"></include>
    from comment
    where status = 0
    and entity_type = #{entityType}
    and entity_id = #{entityId}
    order by create_time asc
    limit #{offset}, #{limit}
</select>

4.2.2 查询某条帖子的回帖数量,查询回帖下的评论和回复数量

对应接口

int selectCountByEntity(int entityType, int entityId);

注意事项

  1. 当 entiyType = 1:查询某条帖子的回帖数量,用于分页显示计算回帖页数。
  2. 当 entiyType = 2:查询回帖下的评论和回复数量,用于前端页面显示某条回帖下的评论和回复数量。

对应SQL

<select id="selectCountByEntity" resultType="int">
    select count(id)
    from comment
    where status = 0
    and entity_type = #{entityType}
    and entity_id = #{entityId}
</select>

4.2.3 插入一条comment记录(回帖/评论/回复)

对应接口

int insertComment(Comment comment);

注意事项

对应SQL

<insert id="insertComment" parameterType="Comment">
    insert into comment(<include refid="insertFields"></include>)
    values(#{userId},#{entityType},#{entityId},#{targetId},#{content},#{status},#{createTime})
</insert>

4.2.4 根据comment 的 id查询回帖/评论/回复

对应接口

Comment selectCommentById(int id);

注意事项

对应SQL

<select id="selectCommentById" resultType="Comment">
    select <include refid="selectFields"></include>
    from comment
    where id = #{id}
</select>

5 消息表 message

5.1 字段描述

消息id id int
消息发送方id:1-系统;大于1-用户id from_id int
消息接收方用户id to_id int
对话id或通知事件类型:小用户id_大用户id,表示是对话id;like/follow/comment,表示是通知事件类型 conversation_id varchar(45)
消息的内容 content text
消息状态:0-未读;1-已读;2-删除; status int
消息创建时间 create_time timestamp

在这里插入图片描述
在这里插入图片描述
可以这样理解:在帖子下的评论,和在评论下的评论
在这里插入图片描述

5.2 相关功能描述

5.2.1 分页查询某个用户的所有私信,按会话id分组,每组只有一条最新的私信

对应接口

List<Message> selectConversations(int userId, int offset, int limit);

注意事项

  1. 这个查询比较复杂,要嵌套查询,先查出每个会话最大的消息id,再查询这些消息id对应的完整的信息,按时间降序排序,只显示offset开始的limit条记录。
  2. 要选择未被删除的消息,所以status != 2
  3. 要选择的是私信,所以from_id != 1
  4. 要查的是user_id的对话信息,所以是from_id = #{userId} or to_id = #{userId}

对应SQL

<select id="selectConversations" resultType="Message">
    select <include refid="selectFields"></include>
    from message
    where id in (
        select max(id) from message
        where status != 2
        and from_id != 1
        and (from_id = #{userId} or to_id = #{userId})
        group by conversation_id
    )
    order by id desc
    limit #{offset}, #{limit}
</select>

5.2.2 根据userId,查询某个用户所有会话的数量

对应接口

int selectConversationCount(int userId);

注意事项

  1. 用于分页显示用户会话
  2. 要选择未被删除的消息,所以status != 2
  3. 要查询的是会话的数量,所以from_id != 1
  4. 要查的是user_id的对话信息,所以是from_id = #{userId} or to_id = #{userId}

对应SQL

我觉得直接使用这个SQL要比课程里面的要好。

select count(*) from message
where status != 2
and from_id != 1
and (from_id = 111 or to_id = 111)
group by conversation_id

5.2.3 根据conversation_id查询消息列表

对应接口

int selectLetterCount(String conversationId);

注意事项

对应SQL

我觉得这里不用写from_id != 1

<select id="selectLetterCount" resultType="int">
    select count(id)
    from message
    where status != 2
    // and from_id != 1  
    and conversation_id = #{conversationId}
</select>

5.2.4 查询某个用户未读消息数量,查询某个用户的某个会话id下的未读消息数量

对应接口

int selectLetterUnreadCount(int userId, String conversationId);

注意事项

  1. 是查询未读消息,消息发送发一定是已读的,所以要用to_id筛选
  2. 未读消息,status = 0

对应SQL

<select id="selectLetterUnreadCount" resultType="int">
    select count(id)
    from message
    where status = 0
    and from_id != 1
    and to_id = #{userId}
    <if test="conversationId!=null">
        and conversation_id = #{conversationId}
    </if>
</select>

5.2.5 新增一条消息记录

对应接口

 int insertMessage(Message message);

注意事项

  1. 如果是私信,由程序执行,同步添加
  2. 如果是通知,由消息队列,然后异步添加

对应SQL

<insert id="insertMessage" parameterType="Message" keyProperty="id">
    insert into message(<include refid="insertFields"></include>)
    values(#{fromId},#{toId},#{conversationId},#{content},#{status},#{createTime})
</insert>

5.2.6 根据消息ids,修改一批消息的状态

对应接口

int updateStatus(List<Integer> ids, int status);

注意事项

对应SQL

<update id="updateStatus">
    update message set status = #{status}
    where id in
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</update>

5.2.7 查询某个用户的,某个通知事件类型的,一条最新通知

对应接口

Message selectLatestNotice(int userId, String topic);

注意事项

  1. 要查询的是通知,所以from_id = 1
  2. 不能是已经删除的通知,所以status != 2
  3. 查询某个用户的通知,所以to_id = #{userId}

对应SQL
也可以按时间降序排序,然后limit 1,只返回1条,就是最新的那条通知

<select id="selectLatestNotice" resultType="Message">
    select <include refid="selectFields"></include>
    from message
    where id in (
        select max(id) from message
        where status != 2
        and from_id = 1
        and to_id = #{userId}
        and conversation_id = #{topic}
    )
</select>

5.2.8 查询某个用户的,某个通知事件类型的,通知数量

对应接口

int selectNoticeCount(int userId, String topic);

注意事项

  1. 要查询的是通知,所以from_id = 1
  2. 不能是已经删除的通知,所以status != 2
  3. 查询某个用户的通知,所以to_id = #{userId}

对应SQL

<select id="selectNoticeCount" resultType="int">
    select count(id) from message
    where status != 2
    and from_id = 1
    and to_id = #{userId}
    and conversation_id = #{topic}
</select>

5.2.9 查询某个用户的未读通知数量,查询某个用户的某个通知事件类型的未读通知数量

对应接口

int selectNoticeUnreadCount(int userId, String topic);

注意事项

对应SQL

<select id="selectNoticeUnreadCount" resultType="int">
    select count(id) from message
    where status = 0
    and from_id = 1
    and to_id = #{userId}
    <if test="topic!=null">
        and conversation_id = #{topic}
    </if>
</select>

5.2.10 分页查询某个用户的,某个通知事件类型的通知

对应接口

List<Message> selectNotices(int userId, String topic, int offset, int limit);

注意事项

按照时间降序排序。

对应SQL

<select id="selectNotices" resultType="Message">
    select <include refid="selectFields"></include>
    from message
    where status != 2
    and from_id = 1
    and to_id = #{userId}
    and conversation_id = #{topic}
    order by create_time desc
    limit #{offset}, #{limit}
</select>

网站公告

今日签到

点亮在社区的每一天
去签到