[英]MYSQL schema for comment system
我正在使用下表设置创建的应用程序有一个基本的评论系统:
CREATE TABLE `meet_comment` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`meet_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`date_created` datetime NOT NULL,
`comment` mediumtext NOT NULL,
PRIMARY KEY (`id`),
KEY `meet_id` (`meet_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `meet_comment_ibfk_1` FOREIGN KEY (`meet_id`) REFERENCES `meet` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `meet_comment_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
meet_id
是对用户评论的 object 的引用。 这很好用,尽管目前如果用户编辑评论,我只是在更新comment
字段。
如果评论被编辑,我希望能够查看评论历史记录,go 对此的最佳方法是什么? 我猜我需要另一个包含评论和引用的表meet_comment.id
? 也许像:
CREATE TABLE `meet_comment` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`meet_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `meet_id` (`meet_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `meet_comment_ibfk_1` FOREIGN KEY (`meet_id`) REFERENCES `meet` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `meet_comment_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
CREATE TABLE `meet_comment_content` (
`revision` int(3) NOT NULL,
`meet_comment_id` int(11) NOT NULL,
`date_created` datetime NOT NULL,
`comment` mediumtext NOT NULL,
UNIQUE KEY `revision_2` (`revision`,`meet_comment_id`),
KEY `revision` (`revision`),
KEY `meet_comment_id` (`meet_comment_id`),
CONSTRAINT `meet_comment_content` FOREIGN KEY (`meet_comment_id`) REFERENCES `meet_comment` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
如果是这样,查询表的最佳方法是什么,我猜我可以进行连接以获取所需的数据?
修改历史导致拉锯战——
考虑以下“一般”原则:
有两张桌子:
Current
-- 评论的当前版本History
——评论的所有版本 Current
使主要查询更简单、更高效。
创建或编辑评论意味着在Current
中的INSERT
或UPDATE
,加上(总是)在History
中的INSERT
。
History
与Current
的架构略有不同,因为需要有一个修订号,可能还有其他日期/标志/等。
这不解决磁盘空间问题; 我怀疑你可以持续一段时间才需要担心这些。 一种技术是“压缩”主TEXT
列并将其放入BLOB
中。 (注意:另一个架构差异。并增加了代码的复杂性。)典型的文本缩小了 3:1。
旁注: int(3)
- (3)
什么也没说。 一个INT
总是 4 个字节。 建议使用SMALLINT UNSIGNED
,它占用 2 个字节,范围为 0..64K。
我会放弃FOREIGN KEYs
,尤其是CASCADE
; 这两个表中可能有一些参考资料会纠缠在一起。 无论如何,您需要仔细编写代码来处理各种任务,从而避免对 FK 的需求。
每个表都应该有一个PRIMARY KEY
。 对于数据的“聚类”,我推荐(comment_id, revision)
,而不是相反。
并且,考虑meet_id
是否是 PK 的一部分。
-- User USR exists.
--
user {USR}
PK {USR}
-- Meet MET exists.
--
meet {MET}
PK {MET}
-- User USR attended meet MET.
--
user_meet {USR, MET}
PK {USR, MET}
FK1 {USR} REFERENCES user {USR}
FK2 {MET} REFERENCES meet {MET}
如果用户对会议发表评论,则该用户参加了该会议。
-- User USR commented CMT_TXT on meet MET,
-- as comment number CMT_NO from that user on that meet.
--
comment {USR, MET, CMT_NO, CMT_TXT}
PK {USR, MET, CMT_NO}
FK {USR, MET} REFERENCES user_meet {USR, MET}
-- For any given (USR, MET), CMT_NO is in {1,2,3 ...}.
-- User USR commented CMT_TXT on meet MET,
-- in version number VER_NO of comment number CMT_NO
-- from that user on that meet.
--
comment_history {USR, MET, CMT_NO, VER_NO, CMT_TXT}
PK {USR, MET, CMT_NO, VER_NO}
FK {USR, MET, CMT_NO} REFERENCES
comment {USR, MET, CMT_NO}
ON UPDATE CASCADE
ON DELETE RESTRICT
-- For any given (USR, MET, CMT_NO), VER_NO is in {1,2,3 ...}.
我建议将删除评论视为新版本。 例如,您可以将comment.CMT_TXT
设置为空字符串。 这样,历史记录和数据完整性都得以保留。
如果comment_history
仅包含旧版本,并且当前在comment
中,则使用视图:
CREATE VIEW v_comment
AS
SELECT USR
, MET
, CMT_NO
, 'current' as VER
, CMT_TXT
FROM comment
UNION
SELECT USR
, MET
, CMT_NO
, concat('ver_', lpad(VER_NO,3,0)) as VER
, CMT_TXT
FROM comment_history ;
查询特定用户的评论和历史记录并满足:
SELECT *
FROM v_comment
WHERE USR = specific_user
AND MET = specific_meet
ORDER BY CMT_NO, VER
笔记:
All attributes (columns) NOT NULL
PK = Primary Key
FK = Foreign Key
如果你不想 go 有太多复杂的查询和实现,你可以用简单的实现 go。
喜欢 JOIN
SELECT
mc.id,
mc.meet_id as meet_id,
mc.user_id as user_id,
mcc.revision as revision,
mcc.date_created as date_created,
mcc.comment as comment
FROM
meet_comment as mc
LEFT JOIN
meet_comment_content as mcc
ON
mc.meet_id = mcc.meet_id
此查询将为您提供整个评论历史记录。
如果您想要某个特定用户的评论,那么您必须将其添加到
WHERE
mc.user_id = <User Id>
如果您只想要来自特定会议 ID 和用户的评论,您可以将其添加到WHERE
子句中。
WHERE
mc.meet_id = <Meet ID> AND
mc.user_id = <User ID>
设计数据库时的一些指示 -
comment
表应该只有评论,没有关于会面或用户的信息。comment
表中引入额外的parent_comment_id
列轻松地做到这一点。IMO应该有以下表格-
user
- user_id
和其他与用户相关的字段meet
- meet_id
和其他与会议相关的字段comment
- comment_id
、 revision_id
和其他与评论相关的字段,例如user_meet_mapping
- user_id
, meet_id
等。meet_comment_mapping
- meet_id
, comment_id
等。此模式是可以实现的最佳规范化。 就您的查询而言,您可以通过各种分页连接查询来提取它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.