Mysql Isn';当存在多个联接时,是否可以更好地使用非规范化设计?
以下是我的表格结构:Mysql Isn';当存在多个联接时,是否可以更好地使用非规范化设计?,mysql,sql,performance,join,Mysql,Sql,Performance,Join,以下是我的表格结构: // posts +----+-----------+---------------------+-------------+ | id | title | body | keywords | +----+-----------+---------------------+-------------+ | 1 | title1 | Something here | php,oop | | 2 | tit
// posts
+----+-----------+---------------------+-------------+
| id | title | body | keywords |
+----+-----------+---------------------+-------------+
| 1 | title1 | Something here | php,oop |
| 2 | title2 | Something else | html,css,js |
+----+-----------+---------------------+-------------+
// tags
+----+----------+
| id | name |
+----+----------+
| 1 | php |
| 2 | oop |
| 3 | html |
| 4 | css |
| 5 | js |
+----+----------+
// pivot
+---------+--------+
| post_id | tag_id |
+---------+--------+
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
| 2 | 5 |
+---------+--------+
如您所见,我以两种方式存储关键字。既可以作为字符串输入到名为关键字的列中,也可以作为关系输入到其他表中
现在我需要选择所有具有特定关键字的帖子(例如php
和html
标签)。我可以通过两种方式做到这一点:
1:使用非规范化设计:
2:使用规范化设计:
看到了吗?第二种方法使用两个JOIN
s。我想它比在庞大的数据集中使用REGEXP
要慢
你觉得怎么样?我的意思是你的建议是什么?为什么?在小表格中,你可以根据自己的判断使用这两种方法
如果你希望表增长,你真的需要第二选择。背后的原因是,regexp永远不能在MySQL中使用索引。索引是快速查询的关键。
join如果在列上声明索引,则将使用索引 在小表格中,您可以自行决定使用这两种方法
如果你希望表增长,你真的需要第二选择。背后的原因是,regexp永远不能在MySQL中使用索引。索引是快速查询的关键。
join如果在列上声明索引,则将使用索引
第二种方法使用两个连接。我想它会比以前慢
在大型数据集中使用REGEXP
你的直觉完全错误。数据库被设计用来进行连接。它们可以利用索引和分区来加速查询。更高级的数据库(比MySQL)使用表的统计信息来选择执行查询的最佳算法
您的第一个查询总是需要对posts
进行完整的表扫描。您的第二个查询可以通过各种方式进行优化
此外,使用第一种方法,维护数据中数据的一致性要困难得多。您可能需要实现触发器来处理所有表上的更新和插入。这会减慢速度
在某些情况下,这样做是值得的——想想汇总计数或美元或时间的总数。将标记放入带分隔符的字符串中的好处要小得多,因为在SQL中解析字符串相对于其他成本来说不太可能是一个真正大的好处
第二种方法使用两个连接。我想它会比以前慢
在大型数据集中使用REGEXP
你的直觉完全错误。数据库被设计用来进行连接。它们可以利用索引和分区来加速查询。更高级的数据库(比MySQL)使用表的统计信息来选择执行查询的最佳算法
您的第一个查询总是需要对posts
进行完整的表扫描。您的第二个查询可以通过各种方式进行优化
此外,使用第一种方法,维护数据中数据的一致性要困难得多。您可能需要实现触发器来处理所有表上的更新和插入。这会减慢速度
在某些情况下,这样做是值得的——想想汇总计数或美元或时间的总数。将标记放入带分隔符的字符串中的好处要小得多,因为与其他成本相比,在SQL中解析字符串不太可能是一个真正大的好处。当我们以较低的规模谈论数据时,所有这些都看起来不错。对OLTP系统来说,表的非规范化是非常基本的理论。当您希望表能够扩展并希望数据不冗余且一致时,标准化就是答案。当然,join需要付出代价,但这对于所有这些问题来说都是微不足道的。
让我们谈谈您的场景:
优点:
- 查询一个表时可用的所有数据
缺点:
- 跨列包装的函数强制查询优化器扫描整个表,而不考虑列索引。从数据缩放的角度来看,这非常重要
- 关键字在您的情况下重复多次前导数据冗余
- 关键字多次出现会导致数据不一致,如果要删除/更新关键字,则需要搜索列并替换每行中的所有位置。而且,如果在任何地方留下关键词,都会导致数据完整性问题
还有很多。在RDBMS中进行数据规范化。当我们谈论低规模的数据时,所有这些看起来都很好。对OLTP系统来说,表的非规范化是非常基本的理论。当您希望表能够扩展并希望数据不冗余且一致时,标准化就是答案。当然,join需要付出代价,但这对于所有这些问题来说都是微不足道的。
让我们谈谈您的场景:
优点:
- 查询一个表时可用的所有数据
缺点:
- 跨列包装的函数强制查询优化器扫描整个表,而不考虑列索引。从数据缩放的角度来看,这非常重要
- 关键字在您的情况下重复多次前导数据冗余
- 关键字多次出现会导致数据不一致,如果要删除/更新关键字,则需要搜索列并替换每行中的所有位置。而且,如果在任何地方留下关键词,都会导致数据完整性问题
还有很多。在RDBMS中进行数据标准化。一个简单的标准化。不可以。在MySQL中,函数不能使用索引。此外,这实际上是对GROUP BY子句的滥用-尽管令人沮丧的是,它比正确的对应语句快。第一个查询可能看起来快,但实际上它将比
SELECT * FROM posts WHERE keywords REGEXP 'php|html';
SELECT posts.id, posts.title, posts.body, posts.keywords
FROM posts
INNER JOIN pivot ON pivot.post_id = posts.id
INNER JOIN tags ON tags.id = pivot.tag_id
WHERE tags.name IN ('html', 'php')
GROUP BY posts.id