我是否应该将大量数据放入另一个 table 以节省性能
Should I put big amount of data to another table to save performance
我在 MySQL 中有一个数据库 ERD connections。这是一个简单的博客应用程序,作者可以在其中 post 篇文章。我想知道哪个是设计我的数据库的最佳实践。我有一个 post 和一个 post_body table,我把它们分开了,因为 post_body 可能包含很多数据。这个栏目我只用过几次,因为我用来列出文章,但除了用户点击post的名字访问完整文章外,不会显示内容。所以我认为分离可能对性能有好处。或者我错了,我应该合并这些 table 吗?
对于大多数数据库,列位置不是问题。有时,您可以通过数据类型提示数据管理:例如LARGE TEXT 类型在大多数情况下不会被文本索引(或者它只会被部分索引)并且实际上可能存储在一个单独的文件中。
换句话说,只要有意义,RDBMS 就已经完成了您描述的优化,并且以比您希望的更有效和透明的方式执行。除非在非常特殊的情况下,否则最好不要管它。
您真正需要做的是处理行的位置。在 MySQL 中,您可以通过分区处理大型表。然而,在此之前,您需要考虑您最常使用哪些查询 运行,并相应地计划索引。
在某些情况下有高度归一化("more tables")是好的,而且干净。如果将来这些一对一关系中的任何一个可能变成一对多或多对多,那么多table数据库就灵活多了。例如,如果您需要为某些客户存储多个地址,那么如果您有一个客户 table 和一个地址 table.
就容易多了
我遇到过几次。以下是一些需要考虑的事项。
- 您是否经常扫描'meta'数据('body'以外的列),不需要'body'?
- 您是否无法充分
INDEX
table,以至于您必须先获取并检查额外的元列,然后再决定您需要哪些行?
两者都会导致 "Am I stumbling over bulky bodies that I don't need?" 如果是,那么 "vertical partitioning" 可能 对性能来说是可取的。
如果您处于产品部署的早期阶段,我建议 "KISS";也就是说,在确定需要垂直分区之前,不要为垂直分区的复杂性而烦恼。
另一个考虑是
- 'body'(或其他什么)是"optional"吗?也就是说,您的许多行是否没有该列的值? (这将导致在获取 'body' 时执行
LEFT JOIN
。)
如果你决定这样做...
CREATE TABLE main (
id ... PRIMARY KEY -- perhaps AUTO_INCREMENT
)
CREATE TABLE bulky_stuff(
id ... PRIMARY KEY -- not AUTO_INCREMENT, but value matches `main.id`
body MEDIUMTEXT NOT NULL ...
)
在 MyISAM(您不应该使用它)中,垂直分区通常很有用;在 InnoDB 中,它不太有用,因为该引擎通常将大量列放在单独的块中。将 ROW_FORMAT
更改为 DYNAMIC
可能是更好的(即 'simpler')解决方案。
我在 MySQL 中有一个数据库 ERD connections。这是一个简单的博客应用程序,作者可以在其中 post 篇文章。我想知道哪个是设计我的数据库的最佳实践。我有一个 post 和一个 post_body table,我把它们分开了,因为 post_body 可能包含很多数据。这个栏目我只用过几次,因为我用来列出文章,但除了用户点击post的名字访问完整文章外,不会显示内容。所以我认为分离可能对性能有好处。或者我错了,我应该合并这些 table 吗?
对于大多数数据库,列位置不是问题。有时,您可以通过数据类型提示数据管理:例如LARGE TEXT 类型在大多数情况下不会被文本索引(或者它只会被部分索引)并且实际上可能存储在一个单独的文件中。
换句话说,只要有意义,RDBMS 就已经完成了您描述的优化,并且以比您希望的更有效和透明的方式执行。除非在非常特殊的情况下,否则最好不要管它。
您真正需要做的是处理行的位置。在 MySQL 中,您可以通过分区处理大型表。然而,在此之前,您需要考虑您最常使用哪些查询 运行,并相应地计划索引。
在某些情况下有高度归一化("more tables")是好的,而且干净。如果将来这些一对一关系中的任何一个可能变成一对多或多对多,那么多table数据库就灵活多了。例如,如果您需要为某些客户存储多个地址,那么如果您有一个客户 table 和一个地址 table.
就容易多了我遇到过几次。以下是一些需要考虑的事项。
- 您是否经常扫描'meta'数据('body'以外的列),不需要'body'?
- 您是否无法充分
INDEX
table,以至于您必须先获取并检查额外的元列,然后再决定您需要哪些行?
两者都会导致 "Am I stumbling over bulky bodies that I don't need?" 如果是,那么 "vertical partitioning" 可能 对性能来说是可取的。
如果您处于产品部署的早期阶段,我建议 "KISS";也就是说,在确定需要垂直分区之前,不要为垂直分区的复杂性而烦恼。
另一个考虑是
- 'body'(或其他什么)是"optional"吗?也就是说,您的许多行是否没有该列的值? (这将导致在获取 'body' 时执行
LEFT JOIN
。)
如果你决定这样做...
CREATE TABLE main (
id ... PRIMARY KEY -- perhaps AUTO_INCREMENT
)
CREATE TABLE bulky_stuff(
id ... PRIMARY KEY -- not AUTO_INCREMENT, but value matches `main.id`
body MEDIUMTEXT NOT NULL ...
)
在 MyISAM(您不应该使用它)中,垂直分区通常很有用;在 InnoDB 中,它不太有用,因为该引擎通常将大量列放在单独的块中。将 ROW_FORMAT
更改为 DYNAMIC
可能是更好的(即 'simpler')解决方案。