增加列还是增加行更有效率?

10

我目前正在重新设计一个可能包含大量数据的数据库 - 我可以选择在数据库中包含许多不同的列,或者使用许多行代替。如果我提供以下概述,可能会更容易理解:

item_id | user_id | title | description | content | category | template | comments | status
-------------------------------------------------------------------------------------------
1       | 1       | ABC   | DEF         | GHI     | 1        | default  | 1        | 1
2       | 1       | ZYX   |             | QWE     | 2        | default  | 0        | 1
3       | 1       | A     |             | RTY     | 2        | default  | 0        | 0
4       | 2       | ABC   | DEF         | GHI     | 3        | custom   | 1        | 1
5       | 2       | CBA   |             | GHI     | 3        | custom   | 1        | 1

与以下结构中的某个内容相比:
item_id | user_id | attribute   | value
---------------------------------------
1       | 1       | title       | ABC
1       | 1       | description | DEF
1       | 1       | content     | GHI
...     | ...     | ...         | ...

我可能会在未来创建更多的属性(以50个为例),如果使用多列,则可能会有很多空单元格。在不同类型的内容中,属性名称将尽可能地重复使用,例如博客文章、事件和画廊 - 标题 将很容易被重复使用。

所以我的问题是,在查询速度和磁盘空间方面,使用多列还是多行更有效率?或者您是否建议使用关系表,因此有一个用于博客的表,一个用于事件等等。我只是想提出一个易于扩展的解决方案,理想情况下,我不想为每种内容创建一个表,因为我考虑开发人员通过应用程序/API系统创建新的内容种类(其中属性受到严格控制)。

如果使用多行,补充问题:

如何在MySQL中将多行转换为可用的列格式(我猜是临时表)- 例如,我可以按内容类型进行一些过滤。


1
请注意,第二个模型(EAV的一个版本)非常难以处理。 - Strawberry
1
@Strawberry 为什么它很难处理?我是新手,即将开始一个项目,正在尝试在这两种设计之间做出决定。 - eric
3个回答

3
基本上,MySQL的行长度是可变的,只要不在每个表级别上更改。因此,空列将不占用任何空间(嗯,几乎没有)。
但对于BLOB或文本列,最好将它们归一化,因为这些可能具有存储大量数据的大型数据需要每次扫描表时进行读取/跳过。即使该列不在结果集中,并且您正在执行索引外的查询,它也会花费时间来处理大量行。
作为一个好的实践,我认为将所有管理和经常使用的列放入一个表中并归一化所有其余内容将会很快。类似于您第二个示例中的“垂直”设计将很难阅读,并且一旦您使用临时表,您迟早会遇到性能问题。

2

对于传统的基于行的存储方式,浏览行的成本将取决于它们的宽度,因此扫描具有宽行的表将比具有窄行的表需要更长时间。

话虽如此,如果您使用索引来定位感兴趣的行,则这不会是一个大问题。

如果您通过将列替换为其他表中的行键来规范化数据,则可以减少存储量,如果关联表最终比原始表小得多,则可以进一步减少存储量,但是任何查询都需要包括所需连接到相关表的成本。

与所有这些事情一样,这是一个平衡的过程,取决于您的要求,但是了解底层发生的事情肯定可以帮助您做出更加明智的决策。


2
这个问题很难回答,因为它完全取决于您要寻找什么以及您的数据库在时间上如何增长和复杂化。我发现回答这些类型的问题的最佳方法是阅读其他成功站点的案例研究。例如,Reddit将是一个案例研究,他们使用了大量的行,但很少用表和/或列。文章在这里,有关其的问题在这里
另外,还可以探索NoSQL解决方案,这可能更适用于您想要实现的内容。
谷歌一下与您自己结构类似的网站的案例研究,并查看他们如何完成,因为他们很可能已经遇到了您将会遇到的所有问题并已经克服了它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接