问答功能设计思路

1. 功能背景

问答功能是在线学习平台中非常重要的一部分,它不仅能够促进用户之间的互动,还能帮助用户解决学习中遇到的问题,提升学习效果和平台的黏性。尤其是在课程学习场景下,用户可以基于具体的课程、章节或知识点提出问题,并得到回答。整个功能需求旨在为用户提供一个高效、便捷、结构清晰的互动环境。

在这种背景下,问答功能需要满足以下几个核心目标:

  1. 促进用户互动:用户可以提问、回答问题,并与其他用户进行交流。

  2. 知识共享与沉淀:用户的回答可以帮助其他用户解决类似的问题,形成一个知识库。

  3. 提升平台活跃度:通过点赞、评论、互动等形式,增强用户的参与感和粘性。

2. 需求分析

问题详细页面:

  • 顶部展示问题相关详细信息

  • 任何人都可以对问题做回复,也可以对他人的回答再次回复,无限叠楼。

  • 也没渲染只分两层:

    • 对问题的一级回复,称为回答

    • 对回答的回复、对回复的回复,作为第二级,称为评论

  • 问题详情页下面展示问题下的所有回答

  • 点击回答下的详情才展示二级评论

  • 可以对评论、回答点赞

3. 数据表设计

不难看出,这部分功能主要涉及两个实体:

  • 问题

  • 回答/评论:回答、评论可以看做一类实体

因此核心要设计的就是这两张表。

3.1 问题表

CREATE TABLE IF NOT EXISTS `interaction_question` (
  `id` bigint NOT NULL COMMENT '主键,互动问题的id',
  -- 每个问题的唯一标识,使用 `bigint` 类型以支持大规模数据增长。

  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '互动问题的标题',
  -- 问题的标题,限制长度为 255 个字符,采用 `utf8mb4` 编码支持多语言和表情符号。

  `description` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '问题描述信息',
  -- 问题的详细描述信息,长度限制为 2048 个字符,允许用户提供更详细的背景和补充信息。
  -- 设置默认值为空字符串,确保不会出现空值。

  `course_id` bigint NOT NULL COMMENT '所属课程id',
  -- 问题关联的课程 ID,表示用户在哪个课程下提出了问题。
  -- 用于快速查询某课程下的问题。

  `chapter_id` bigint NOT NULL COMMENT '所属课程章id',
  -- 问题关联的课程章节 ID,用于进一步细分问题的归属。

  `section_id` bigint NOT NULL COMMENT '所属课程节id',
  -- 问题关联的课程节 ID,帮助定位问题具体关联的学习内容。

  `user_id` bigint NOT NULL COMMENT '提问学员id',
  -- 提问者的用户 ID,用于记录问题的提出者身份,支持用户的问题管理功能。

  `latest_answer_id` bigint DEFAULT NULL COMMENT '最新的一个回答的id',
  -- 记录该问题最新回答的 ID,用于在前端快速显示最新回答。
  -- 如果问题还没有回答,该值为 NULL。

  `answer_times` int unsigned NOT NULL DEFAULT '0' COMMENT '问题下的回答数量',
  -- 该问题当前的回答总数,用于快速展示问题的活跃程度和排序。

  `anonymity` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否匿名,默认false',
  -- 标志是否匿名提问,`0` 表示非匿名,`1` 表示匿名。
  -- 匿名问题在展示时隐藏用户身份。

  `hidden` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否被隐藏,默认false',
  -- 标志该问题是否被管理员隐藏,`0` 表示正常,`1` 表示已隐藏。
  -- 用于屏蔽违规、无效或低质量的问题。

  `status` tinyint DEFAULT '0' COMMENT '管理端问题状态:0-未查看,1-已查看',
  -- 用于后台管理标记问题状态,`0` 表示问题未被管理员处理,`1` 表示已处理。

  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '提问时间',
  -- 记录问题的创建时间,用于前端排序展示和数据统计。

  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  -- 记录问题的最后更新时间,包括回答数或状态的修改。

  PRIMARY KEY (`id`) USING BTREE,
  -- 主键索引,保证问题 ID 的唯一性。

  KEY `idx_course_id` (`course_id`) USING BTREE,
  -- 课程 ID 的索引,用于快速查询某课程下的所有问题。

  KEY `section_id` (`section_id`),
  -- 节 ID 的索引,支持通过具体节筛选问题。

  KEY `user_id` (`user_id`)
  -- 用户 ID 的索引,用于查询用户提出的所有问题。
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='互动提问的问题表';

字段设计:

  • 基础信息

    • id:每条问题记录的唯一标识,采用 bigint 类型以支持海量数据。
    • titledescription:标题和描述是问题的主要内容,description 的长度更长,用于记录问题的详细背景。
  • 关联字段

    • course_idchapter_idsection_id:明确问题的归属范围(课程、章节、节),用于前端筛选和后端数据查询。
    • user_id:记录提问者的用户 ID,支持用户的问题历史查询。
  • 统计字段

    • latest_answer_id:记录最新回答的 ID,便于在前端快速展示最近的动态。
    • answer_times:记录回答数量,避免每次查询时进行复杂的统计操作。
  • 状态控制

    • anonymity:支持匿名提问,提升用户在敏感问题上的参与度。
    • hidden:支持管理员隐藏问题,用于屏蔽不符合规范的内容。
    • status:用于后台审核标记,便于管理未处理的提问。
  • 时间字段

    • create_timeupdate_time:支持问题的时间排序、更新检测以及统计功能。

3.2 回复表

回复表:回答和评论都是回复,在一张表

注意:

一个回答下会有很多评论,评论之间也会相互评论,但我们把回答下所有评论作为一层来展示。因此该回答下的所有评论都应记住所属的回答的id。

CREATE TABLE IF NOT EXISTS `interaction_reply` (
  `id` bigint NOT NULL COMMENT '互动问题的回答id',
  -- 每条回答或评论的唯一标识,采用 `bigint` 类型支持大量数据。

  `question_id` bigint NOT NULL COMMENT '互动问题问题id',
  -- 回答关联的问题 ID,用于确定该回答属于哪个问题。
  -- 这是表中最重要的外键字段,用于支持问题与回答的关系。

  `answer_id` bigint DEFAULT '0' COMMENT '回复的上级回答id',
  -- 如果是对回答的回复,则 `answer_id` 为上级回答的 ID;
  -- 如果是直接回答问题,则 `answer_id` 为 0。
  -- 这实现了层级回复结构。

  `user_id` bigint NOT NULL COMMENT '回答者id',
  -- 回答者的用户 ID,用于记录回答的作者。

  `content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '回答内容',
  -- 回答的内容,长度限制为 255 个字符,使用 `utf8mb4` 支持多语言及表情符号。

  `target_user_id` bigint DEFAULT '0' COMMENT '回复的目标用户id',
  -- 针对某个用户的回复目标。
  -- 如果是直接回答问题,则为 0;如果是对其他用户的回复,则记录目标用户 ID。

  `target_reply_id` bigint DEFAULT '0' COMMENT '回复的目标回复id',
  -- 指定回复的目标回答或评论 ID。
  -- 在评论嵌套场景下用于标明具体的父评论。

  `reply_times` int NOT NULL DEFAULT '0' COMMENT '评论数量',
  -- 当前回答下的评论数量(仅对一级回答有效),
  -- 避免动态统计回复数量,提升查询性能。

  `liked_times` int NOT NULL DEFAULT '0' COMMENT '点赞数量',
  -- 当前回答或评论的点赞次数,用于支持互动功能。

  `hidden` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否被隐藏,默认false',
  -- 标志是否被管理员隐藏,`0` 表示正常,`1` 表示隐藏。
  -- 隐藏的回答不会对用户展示。

  `anonymity` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否匿名,默认false',
  -- 标志是否为匿名回答,`0` 表示非匿名,`1` 表示匿名。
  -- 匿名回答在前端展示时隐藏用户信息。

  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  -- 回答的创建时间,用于排序和时间显示。

  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  -- 回答的最后更新时间,包括点赞数、评论数等的更新。

  PRIMARY KEY (`id`) USING BTREE,
  -- 主键索引,用于唯一标识每条记录。

  KEY `idx_question_id` (`question_id`) USING BTREE
  -- 索引字段,支持快速查询某个问题下的所有回答。
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='互动问题的回答或评论';

字段设计:

基础信息

  • id:每条回答或评论的唯一标识符,采用 bigint 类型支持海量数据。

  • content:回答内容,使用 utf8mb4 编码以支持多语言和表情符号,长度限制为 255 个字符。

关联字段

  • question_id:回答关联的问题 ID,用于将回答绑定到具体的问题。

  • answer_id:回答的层级关联字段。如果是直接回答问题,则 answer_id 为 0;如果是对其他回答的评论,则 answer_id 为该回答的 ID。

  • target_user_id:在对回答或评论的回复中,记录回复的目标用户 ID,支持多用户互动。

  • target_reply_id:指定回复的目标回答或评论 ID,用于嵌套回复的层次关系。

统计字段

  • reply_times:记录当前回答或评论下的评论数量,仅对一级回答有效,避免动态统计。

  • liked_times:记录点赞次数,支持互动功能。

状态控制

  • hidden:隐藏字段,用于管理员屏蔽低质量或违规回答。

  • anonymity:匿名字段,用于支持用户匿名互动需求。

时间字段

  • create_time:记录回答的创建时间,便于前端排序和时间显示。

  • update_time:记录回答的最后更新时间,包括内容修改、点赞数变化等。