朋友圈(广场设计)
这是一份历史设计草案,围绕文章、一级评论、二级回复和点赞说明数据关系。表结构与 Go 片段保留原稿;未完整声明的类型、字段和拼写属于伪结构,不能直接编译。先看点赞与计数规则,再对照下方 DDL;评论归属与分页见读取边界。
点赞
创建点赞表设计
mysql
CREATE TABLE `t_like` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,-- 表ID
`statistics_id` bigint(20) NOT NULL, --文章ID
`user_id` bigint(20) NOT NULL DEFAULT '0', --点赞人ID
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `user_id` (`user_id`,`statistics_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;go
Id int64 `json:"id"` //ID
Statistics *Statistics `json:"statistics"` //喜欢的信息
UserId int64 `json:"user_id"` //喜欢人
CreateTime time.Time ` json:"create_time"` //添加时间
UpdateTime time.Time `json:"update_time"` //修改时间- 对
(user_id, statistics_id)设置联合唯一索引,防止同一用户重复点赞同一文章。 - 插入前仍须检查用户身份、文章存在性与访问权限;唯一索引只负责去重。
- 仅当本次确实新增点赞记录时,文章点赞数才加一;重复请求返回已点赞状态,不重复加数。
- 取消点赞也只在实际删除记录时减一;记录和计数在同一数据库时应在同一事务内更新。
评论
一级评论
mysql
CREATE TABLE `t_comment` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`statistics_id` bigint(20) NOT NULL,
`user_image` varchar(255) NOT NULL DEFAULT '',
`user_name` varchar(255) NOT NULL DEFAULT '',
`user_id` bigint(20) NOT NULL DEFAULT '0',
`app_user_id` bigint(20) NOT NULL DEFAULT '0',
`content_info` varchar(255) NOT NULL DEFAULT '',
`comment_time` varchar(255) NOT NULL DEFAULT '',
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;go
Id int64 `orm:"auto" json:"id"` //id
Statistics *Statistics ` json:"statistics"` // 共享信息 一对多关系
CommentSubset []*CommentSubset `json:"comment_subset"` //一堆多二级评论
UserImage string ` json:"user_image"` //用户头像
UserName string ` json:"user_name"` //用户名字
UserId int64 `json:"user_id"` //uid
AppUserId int64 `json:"app_user_id"` //appUserId
ContentInfo string `json:"content_info"` //评论内容
CommentTime string `json:"comment_time"` //评论时间
CreateTime time.Time `json:"create_time"` //添加时间
UpdateTime time.Time `json:"update_time"` //修改时间二级评论
mysql
CREATE TABLE `t_comment_subset` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`state` bigint(20) NOT NULL DEFAULT '0',
`p_id` bigint(20) NOT NULL DEFAULT '0',
`comment_id` bigint(20) NOT NULL,
`user_id` bigint(20) NOT NULL DEFAULT '0',
`app_user_id` bigint(20) NOT NULL DEFAULT '0',
`user_name` varchar(255) NOT NULL DEFAULT '',
`user_image` varchar(255) NOT NULL DEFAULT '',
`content_info` varchar(255) NOT NULL DEFAULT '',
`comment_time` varchar(255) NOT NULL DEFAULT '',
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;go
Id int64 `orm:"auto" json:"id"` //id
State int64 `orm:"" json:"state"` //状态
PId int64 `orm:"" json:"p_id"` //父级Id
Comment *Comment `orm:"rel(fk)" json:"comment"` //与一级id绑定
UserId int64 `orm:"" json:"user_id"` //uid
AppUserId int64 `orm:"" json:"app_user_id"` //appUserId
UserName string `orm:"" json:"user_name"` //评论者名字
UserImage string `orm:"" json:"user_image"` //评论者头像
ContentInfo string `orm:"" json:"content_info"` //评论内容
CommentTime string `orm:"" json:"comment_time"` //评论时间
CreateTime time.Time `orm:"auto_now_add;type(datetime)" json:"create_time"` //添加时间
UpdateTime time.Time `orm:"auto_now;type(datetime)" json:"update_time"` //修改时间- 评论列表
- 通过文章ID查询所有的一级评论内容
- 通过一级评论ID查询二级评论内容
mysql
CREATE TABLE `t_statistics` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`image_url` varchar(600) NOT NULL DEFAULT '',
`release_time` varchar(255) NOT NULL DEFAULT '',
`completion_time` varchar(255) NOT NULL DEFAULT '',
`info_state` varchar(50) NOT NULL DEFAULT '',
`nick_name` varchar(255) NOT NULL DEFAULT '',
`user_id` bigint(20) NOT NULL DEFAULT '0',
`app_user_profile_id` bigint(20) NOT NULL DEFAULT '0',
`is_delete` bigint(20) NOT NULL DEFAULT '0',
`title` varchar(128) NOT NULL DEFAULT '',
`content` varchar(500) NOT NULL DEFAULT '',
`content_image` varchar(600) NOT NULL DEFAULT '',
`integral` varchar(500) NOT NULL DEFAULT '',
`share_address` varchar(500) NOT NULL DEFAULT '',
`longitude` varchar(255) NOT NULL DEFAULT '',
`grade` varchar(50) NOT NULL DEFAULT '',
`latitude` varchar(255) NOT NULL DEFAULT '',
`circle_id` bigint(20) NOT NULL,
`release_type` varchar(50) NOT NULL DEFAULT '',
`category` varchar(255) NOT NULL DEFAULT '',
`transaction_type` varchar(50) NOT NULL DEFAULT '',
`share_type` varchar(255) NOT NULL DEFAULT '',
`transaction_result` varchar(255) NOT NULL DEFAULT '',
`product_name` varchar(255) NOT NULL DEFAULT '',
`source` varchar(255) NOT NULL DEFAULT '',
`chat_content` varchar(255) NOT NULL DEFAULT '',
`week` bigint(20) NOT NULL DEFAULT '0',
`like_number` bigint(20) NOT NULL DEFAULT '0',
`collection_number` bigint(20) NOT NULL DEFAULT '0',
`info_number` bigint(20) NOT NULL DEFAULT '0',
`comment_number` bigint(20) NOT NULL DEFAULT '0',
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
`name` varchar(255) NOT NULL DEFAULT '',
`address` varchar(255) NOT NULL DEFAULT '',
`number` bigint(20) NOT NULL DEFAULT '0',
`return_date` bigint(20) NOT NULL DEFAULT '0',
`first_name` varchar(255) NOT NULL DEFAULT '',
`check` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;朋友圈(广场)
登录者每次请求需要带token,再token中提取uid 或者用户其他唯一值
go
type info struct {
文章基本内容
文章媒体路径
comments []*comment 一级评论
user profile(uid ...)
点赞数量
评论数量(次评论数量是一级评论还是二级评论,还是all)
预览者是否点赞状态校验(以点赞 true反之)「次字段不存入数据库」
发布时间(时间戳 毫秒)
状态(删除 软删除)
// 更新时间「预留」(如果支持修改就需要次字段)
// 预览数量「预留」
// 收藏「预留」
// 地理位置「预留」()基站定位或者经纬度定位附近人发布
// 文章类型 「预留」
// 权限「预留」(公开、只有好友可见、自定义好友可见)
}
// 点赞(文章ID和uid设置联合索引)
type like struct{
id
文章ID
uID
点赞时间
}
// 一级评论
type comment strcut {
infoId 文章ID
comment []*commentSubsets 二级评论
user profile(uid ...)
评论内容
}
// 二级评论
type commentSubsets struct{
user profile(uid ....)
评论内容
}涉及api接口
- 发布文章接口
- 媒体文件上传接口返回URL
- 媒体文件AI识别
发布文章字数限制校验、AI识别(媒体文件、以及文章敏感校验)OK才入库
- 文章列表接口
规则为一次为固定条数,往上翻或者点击跟多返回跟多数据,依据为分页分准 - 点赞接口
- 文章评论接口
- 评论返回数据接口
需要和业务逻辑结合
点赞唯一性与计数一致性
联合唯一索引解决的是同一用户对同一文章重复建记录,不能替代文章存在、可见性和用户权限检查。并发两次点赞时,只有实际插入成功的一次才增加计数;取消点赞也只有实际删掉记录时才能减一。若记录与计数在同一数据库,可在同一事务内更新;若计数异步投影,则要接受短暂延迟并具备按事实表重算能力。
去重检查与存在性、可见性检查分别承担不同职责。请求应表示“设为已点赞”或“设为未点赞”,避免把重试的 toggle 再翻回原状态。
查看图表代码
文章与评论的读取边界
文章、一级评论和二级回复分别有归属关系。读取二级回复时不能只按回复ID查询,还应验证它属于当前文章可见的评论树,避免绕过文章权限。原表保存昵称和头像属于快照还是缓存必须明确;若是发布时快照,改名后不自动变化不算错误。
分页可采用稳定的发布时间与ID复合游标,并明确删除项如何影响翻页;仅按时间排序会在同毫秒发布时产生不稳定顺序。评论计数必须决定只数一级还是所有回复,再用相同口径维护与重算。以下是逻辑归属图,不声明现有DDL已设置数据库外键。
查看图表代码
继续阅读
- 应用实践MySQL数据库设计规范 · 历史版本
- 应用实践
- 应用实践