📅  最后修改于: 2023-12-03 14:54:54.425000             🧑  作者: Mango
数据规范化是我们在设计数据库时最常使用的技术之一,它分解表为更小的部分以消除冗余的数据。但对于某些情况,非规范化设计是必须的。
非规范化设计指在设计数据库时,不采用范式化(normalization)方法来保证数据表的设计符合规范化形式。通常出于以下考虑:
数组类型的字段通常被用来储存在数量不确定的数据。通常,我们会将数据以comma-separated-values (CSV)的形式存储。例如,一个名为“employees”的表包含以下两个字段:name和hobbies。hobbies字段可能包含多个爱好,储存在一个数组中。
| name | hobbies |
|------|------------------------|
| Bob | reading, running, hiking|
| Tom | swimming, cycling |
| Lucy | eating, shopping |
这种情况下,我们可能会发现查询人员根据爱好会比较困难,通常我们需要将hobbies字段分割存储到独立表中以便更容易进行查询。但如果我们数据量较小, 少于10000条记录,而且经常需要查询人员的爱好,那么使用非规范化设计也许是正确的方法,可以减少数据表的关联查询。
某些字段可能会包含集合类型的数据,例如一个会员表会包含会员资格信息、会员所属组织信息等等。集合型字段可以使用数组来组织,而非规范化设计可以使查询语句更加直观和容易编写。例如下面是一个包含会员id和所属组织信息字段的表。
| Member ID | Organizations |
|-----------|----------------|
| 101 | Org A, Org B, Org C |
| 102 | Org C, Org D |
| 103 | Org B |
这种情况下,如果我们需要根据组织名查询会员信息,可能需要使用比较复杂的查询语句,例如使用`LIKE '%Org A%'`。但如果每个会员仅属于一个组织,那么使用非规范化设计不仅没有什么好处,反而会使查询更加麻烦。
一些字段是基于数据聚合的,例如一个sales表包含以下字段:salesrep ID、month、product ID和sales amount。我们可能需要每个Salesrep月度销售总额, 这可以通过对表进行分组计算得到。但对于某些查询,我们可能需要单独查询每个Salesrep单月的销售情况,这时我们可以通过创建新表来储存这些聚合值,避免每次查询时重新计算。这种方式在数据量大,或者查询需求比较特殊时可能更有效率。
非规范化的设计也有明显的缺点,以下是一些可能存在的问题:
在数据库设计时,非规范化设计应该是一个必要的考虑因素。如果数据量较小,查询需求明确,采用非规范化设计能让我们获得更好的查询效率。但如果数据很大,非规范化设计可能会导致查询效率低下,更新插入等操作更加困难。在设计过程中,需要根据实际场景来进行权衡取舍。
下面是示例代码展示如何使用非规范化设计:
--创建一个employees表,包含名称和hobbies字段
CREATE TABLE employees (
name VARCHAR(50),
hobbies VARCHAR(128)
);
--插入数据
INSERT INTO employees (name, hobbies)
VALUES ('Bob', 'reading, running, hiking'),
('Tom', 'swimming, cycling'),
('Lucy', 'eating, shopping');
--查询名叫Tom的员工的姓名和爱好
SELECT name, hobbies FROM employees WHERE name = 'Tom';