【问题标题】:Database normalization vs wildcard queries数据库规范化与通配符查询
【发布时间】:2014-01-12 10:31:46
【问题描述】:

我一直想知道是否需要标准化。我主要关心的不是这些表的可读性和易用性,而是速度。以汽车桌为例。假设这个汽车表有超过 10,000 条记录。

我的问题是:进行多次连接所花费的时间是否值得更好地设计数据库系统?以及执行 '%%' 查询与联接有什么区别

汽车

-------------------------------------------------------------
|CarID  |Car_Name   |         Car_Features                   |
------------------------------------------------------------- 
|F31344 | Corolla   | Sedan - Sun Roof Power Lock Manual 4WD |
-------------------------------------------------------------

并进行如下查询:

  1. 从 Car_Features 类似 '%4WD'% 的汽车中选择 Car_ID、Car_Name、Car_Features;
  2. 从 Cars where Car_Features like '%Manual Sun Roof%' 中选择 Car_Name;

持续时间/获取时间相对较快。

与标准化方法相比。

汽车

------------------------------------------
|Car_ID | Car_Name |Transmission|Features|
------------------------------------------
|F31344 | Corolla  | M4WD       | EX1    |
------------------------------------------

传输

---------------------------------
|ID           | Drive | Manual  |
--------------------------------
|M4WD         | 4WD   |   1     |
--------------------------------


Features
---------------------------------
|Features | Sun_Roof | Power_lock|
---------------------------------
|EX1      | 1         |     0    |
---------------------------------

现在我必须编写连接来完成同样的事情。以及在我的原始表中引入两个新表和两个查找列。

> 1.Select Car_ID,Car_Name,Drive From Cars inner join Transmission
> ON Cars.Transmission = Transmission.ID
> Where Drive = '4WD'; 

【问题讨论】:

  • 这完全取决于一千件事,没有足够的时间在这里分享。我能给出的最佳答案是一个意见:根据需要开始规范化和非规范化。
  • 规范化用于减少数据冗余,在某些情况下,数据被非规范化以提高性能。但请记住您的业务需求,您可以在中间的某个地方解决,而不会在两端做出太大的妥协。
  • 为什么这个标签同时用于 MySQL 和 SQL Server?您使用的是哪个数据库?
  • 10k 行很小。尽管如此,表达式like '%4WD'% 是不可分割的。 (它不能使用索引。)另请注意,您已经考虑(或错误考虑)可读性、易用性和速度,但您没有考虑数据完整性。
  • 我赞同@MikeSherrill'Catcall' 所说的话。加入实际上会比全表扫描(您现在拥有的)更快。对于仅 10000 行可能不太重要,但在较大的表上可能意味着毫秒和分钟(或更多)之间的差异。

标签: database database-design


【解决方案1】:

规范化与性能无关,尽管在大多数情况下,提高性能是正确规范化数据库的副作用。主要是关于数据的完整性和一致性。

在非规范化方法中,您将无法正常维护(例如,始终向所有汽车记录添加新功能或更新现有功能)和查询数据(当您开始混合和匹配汽车功能时)。而您的第二个查询就是一个完美的例证

Select Car_Name from Cars where Car_Features like '%Manual Sun Roof%';

此查询不会返回任何内容。

这里是SQLFiddle演示

推荐阅读:

【讨论】:

  • 对不起,我的意思是Select Car_Name from Cars where Car_Features like '%Manual%' OR Features like '%Sun Roof%' ;
  • 想象一下“Sun Roof”是个错误。编写查询以从特征中删除“Sun Roof”。
  • 如果一个或两个记录中拼写错误的功能或roof 出现在sun 之前怎么办?现在如果一个特性有一个相似的复合名称——比如sun glass?你怎么区分一个和另一个???这是数据维护的噩梦。现在尝试在这些重新规范化的数据之上构建任何真实世界的报告......
  • 非规范化方法的巨大缺点 - 您无法制定一个查询来为您执行简单的动态聚合,例如 给我每种颜色的可用汽车数量 我们有库存。试着写一个查询来回答这个简单的问题
  • @peterm 我看到你的点维护确实是一场噩梦,我想我会采用标准化方法
猜你喜欢
  • 2011-10-07
  • 1970-01-01
  • 2011-11-15
  • 2012-12-25
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
相关资源
最近更新 更多