使用InfluxDB进行基础设施监控 | 现场演示
数据库反规范化
什么是数据库反规范化?
数据库反规范化是一个设计数据库的过程,旨在实现更快的读取速度。实现这一目标的一种方法是在必要的地方引入冗余数据。
为了进一步解释反规范化的概念,考虑一个存储学校学生记录的数据库表。每个学生要么不属于任何部门,要么最多属于一个部门,并且学生从所属的部门提供一定数量的课程。为了设计一个反规范化的学生数据库表,您可以添加一个<强>部门强>字段和一个<强>总课程数强>字段。对于未分配部门的学生的<强>部门强>和<强>总课程数强>可以留空,或为null。对于分配到一个部门的学生,正确的部门和总课程数将存储在这些字段中。
以下说明了<强>学生强>表
学生ID | 学生 | 部门 | 总课程数 |
---|---|---|---|
43 | 吉米 | 化学 | 5 |
44 | 山姆 | ||
45 | 玛莎 | 历史 | 6 |
注意,由于山姆没有部门,他的部门值留空。因此,山姆的总课程数为0。
这种数据库设计的主要优点是您可以通过单个查询检索学生的部门和提供课程的总数。
与上述设计相比,具有规范化设计的表可能有一个独立的<强>部门强>表,其中每一行代表每个学生的部门和总课程数。然后要检索学生的姓名和他们的部门,您需要编写一个更复杂的查询,使用<强>连接强>。这可能会导致读取速度变慢。
反规范化和规范化的区别
反规范化是规范化的相反。以下表格并列比较了这些数据库设计过程。
反规范化 | 规范化 |
---|---|
在SQL数据库中,反规范化涉及向表中添加更多列,这可能导致数据重复。 | 规范化通过创建更多表来促进减少数据冗余和不一致性。 |
编写和更新更困难,因为可能存在重复数据,并且未能更新特定数据的每个实例可能导致不一致。 | 在规范化数据库设计中,编写和更新操作更容易。 |
反规范化简化了查询并加快了读取操作。 | 规范化数据库设计通常需要多个连接查询来读取数据,这可能导致性能下降。 |
反规范化在NoSQL数据库系统中是一种常见做法。大多数NoSQL数据库以文档的形式而不是关系表来存储数据。 | 大多数关系数据库管理系统(或SQL数据库)默认促进规范化。数据通常存储在多个表中,这些表可以使用主键连接。 |
为什么需要反规范化数据?
反规范化数据库的一个主要原因是提高大型数据库的读取速度。此外,反规范化通过减少连接多个表的需要来降低读取查询的复杂性。
应该反规范化哪些数据?
适合反规范化的好数据是在与其他表一起工作时需要频繁使用的表中的值。您可以通过在当前表中作为字段重复此类数据来进行规范化。
另一种去规范化数据的方法是对大表中数据的计算结果,例如库存中物品的总数。将此结果的副本存储为表中的一个字段,与查询表中的项目并每次需要该结果时计算所有特定项目的行数相比,可以加快读取操作。
哪些数据不应去规范化?
尽管去规范化可以提升读取操作的性能,但在某些情况下,去规范化会给数据库设计增加不必要的复杂性。
例如,在一个存储客户列表以及他们订购的杂货的数据库中,你不希望通过在客户表中为每个订单添加额外的列来去规范化每个客户的订单。由于一个客户可能不确定次数地订购杂货,而表只能有特定数量的列,每次更改表结构都需要进行修改,因此去规范化在这里可能效果不佳。以下表格展示了尝试去规范化客户表的努力
customer | order1 | order2 | order3 | order4 |
---|---|---|---|---|
Tom | Rice | Orange Juice | Tea | Egg |
Ola | Beans | Bread |
如果Tom下第五个订单,你需要通过添加新列来更改整个customers表,以便存储新的订单。对于其他没有第五订单的客户,新列的值将为空或null。除了更改表结构外,你还可能需要更新应用程序代码以识别新列。这显然比使用单独的表更昂贵:一个用于客户,另一个用于他们的订单。
去规范化策略
有许多方法可以设计去规范化表以提升性能。以下是三种策略。
1. 引入重复或冗余数据
这涉及到添加一个字段,该字段存储另一个表中已存储的值,以减少使用JOIN操作并加快读取速度。
以一个社交媒体应用为例,该应用有一个users表和一个profile_pictures表。要在页面上显示用户的详细信息和个人资料图片,就需要在两个表上执行一个JOIN操作。这种复杂性可以通过去规范化来消除。将一个profile_picture字段添加到用户表中,以保存个人资料图片文件的路径,将允许执行更简单的查询,其性能应该比使用一个JOIN操作更快。
2. 在新字段中存储预计算的数据
通过在字段中存储计算结果,可以提高数据库的性能。这消除了每次查询数据时执行计算的需求。例如,在一个标准化的数据库中,有一个用于学生的表和一个用于课程的表,计算选修某门课程的学生的总数的一种方法是通过使用WHERE子句查询学生表。
但去规范化通过在课程表中将选修该课程的学生总数作为列来简化任务。因此,一个查询可以找到选修该课程的学生总数,并返回有关该课程的其他详细信息。
3. 创建报告生成表
在需要从大型数据库生成报告的系统中获得性能提升时,创建存储数据摘要的额外表将比每次需要报告时从实际数据中进行计算更高效。
一个很好的例子是一个表,该表存储基于具有数千条记录的销售表数据的月度销售报告。可以通过创建一个名为monthly_sales的另一个表来规范化这个表,该表存储每个月的销售摘要。因此,一行可能代表一个月,如一月,而列可以存储该月的销售额。
常见问题解答
1. 为什么需要对数据进行反规范化?
数据反规范化可以加快读取操作,并减少查询中的复杂JOIN操作。
2. 反规范化的例子是什么?
反规范化的一个很好的例子是在表中添加一个额外的字段来重复另一个表中的可用数据。
3. 何时应该对数据进行反规范化?
当读取速度比数据冗余更重要时,反规范化可以改善数据库设计。换句话说,当重复数据不会真正破坏事物,并且通过消除额外的JOIN来使查询更有效时,就可以进行反规范化,减少从多个表中读取数据的需求。
要了解时间序列数据库,请查看InfluxDB。