首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将评论和回复存储在单独的表中,而不是将一元关系存储在注释表中,会有什么好处吗?

将评论和回复存储在单独的表中,而不是将一元关系存储在注释表中,会有什么好处吗?
EN

Stack Overflow用户
提问于 2011-12-01 17:13:00
回答 4查看 686关注 0票数 2

选项1:评论{commentid,replyto,comment} //很多帖子的回复都是空的

选项2:评论{commentid,评论}回复{replyid,replyto,回复}

目前,这看起来像是一个选择问题,而不是线性效益分析。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-16 03:13:15

事实上,这不是“唯一”的选择问题,而是有意识的决定。关系数据库不擅长解决层次化的问题。关于这一点有大量的讨论、文章甚至书籍,所以让我们将问题缩小到您的案例中。

第二种选择只有在允许回复评论而不是回复本身的情况下才能正常工作,因此这将是一个最多具有2个级别的树。这可能没问题,但如果您要这样做,更好的解决方案是将所有内容都放在COMMENTS表中,并添加两列: THREAD_ID (具有相同THREAD_ID的所有评论将属于同一主题),SEQ_NUM (或者简单地说,DATE将告诉我们哪个评论是第一个评论)。在SO上实现了类似的组织评论的方式。

第一种选择非常简单和通用-但实现了递归及其所有缺点。让我们停下来想一想...请注意,我们实际上不是在构建一棵树,而是一片“森林”。我们将有许多公共线程,每个单独的线程都将是一个单独的树-相对较少的数据量来组织。在这种情况下,我将向COMMENTS表添加一个THREAD_ID列,并仅使用该表(最好在包含THREAD_ID和COMMENTID列的COMMENTS表上设置复合索引-完全按照该顺序)。

所以在上面我会选择“选项1”。

下一步应该决定在哪里进行处理和评论树构造?我只是从表中获得所有的注释,并在控制器(MVC)端组织它们,即JAVA或C++。遍历注释列表并在主内存中构建树(使用对象和指针或哈希表)将是一件容易的事情。这也是一个很好的选择,因为只有少量的节点(一个线程中的评论和回复)。

票数 1
EN

Stack Overflow用户

发布于 2011-12-01 18:05:29

第一个选项看起来很简单,但问题是您在SQL中构建一个树结构。

并且SQL不支持分层数据。

不推荐使用- ever

代码语言:javascript
复制
TABLE comment
-------------
id unsigned integer auto_increment primary key,
reply_to unsigned integer, 
comment text,
foreign key FK_comment_reply_to(reply_to) references comment.id 
ON UPDATE CASCADE ON DELETE CASCADE

推荐使用-如果您想要一个2层深的树

如果您使用2个表构建它

代码语言:javascript
复制
TABLE main_post
----------------
id unsigned integer auto_increment primary key,
body text,

TABLE reply
-------------
id unsigned integer auto_increment primary key,
reply_to unsigned integer, 
body text,
foreign key FK_reply_reply_to(reply_to) references main_post.id 
ON UPDATE CASCADE ON DELETE CASCADE

然后,您将构建一个简单得多的结构,该结构可以很容易地在SQL中查询,因为树只有1层深。

出于这个原因,我推荐2号选择。

用于更深层次树的替代方案

如果你想要一个层次化的结构,我会考虑嵌套的集合,参见:

http://www.pure-performance.com/2009/03/managing-hierarchical-data-in-sql/

票数 2
EN

Stack Overflow用户

发布于 2012-09-13 21:39:32

1)针对TEXT表的查询总是比针对VARCHAR表的查询慢3倍(平均:VARCHAR表为0.10秒,TEXT表为0.29秒)。差异是100%可重复的。

代码语言:javascript
复制
CREATE TABLE varcharTable (a varchar(255) NOT NULL, PRIMARY KEY (a)) ENGINE=MyISAM; 
CREATE TABLE textTable (a text NOT NULL, PRIMARY KEY (a(255))) ENGINE=MyISAM; 

mysql> explain SELECT SQL_NO_CACHE count(*) from varcharTable where a LIKE "n%"; 
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ 
| 1 | SIMPLE | varcharTable | range | PRIMARY | PRIMARY | 257 | NULL | 5882 | Using where; Using index | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ 
1 row in set (0.00 sec) 


mysql> explain SELECT SQL_NO_CACHE count(*) from T where a LIKE "n%"; 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 
| 1 | SIMPLE | T | range | PRIMARY | PRIMARY | 257 | NULL | 5882 | Using where | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 
1 row in set (0.00 sec) 


Index is being used for the VARCHAR table, but not for the TEXT table (in the Extra column)

2)在评论table.So上不需要搜索,也不需要查询,因为它太长了。它的类型最好是 text ,然后因为它的文本您不能在它上面搜索.So,所以将评论(不可搜索并影响性能)和回复放在单独的表中。因此,and表将正常运行,comments表将仅用于存储目的,而不会对它们执行搜索。

结论:,将它们放在一个单独的表中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8338849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档