表列问题 - 具有ID或否的重复名称?

时间:2011-01-30 07:48:20

标签: database-design

我对查询不太熟悉,但问题是: 我的'邻居'表有列:

n_id, name, country_id, continent_id, city_id. 

其中n_id = PK和country_id,continent_id,city_id是他们自己的表格的FK。

示例数据是:

34, Brooke, 23, 3, 1456

此输出适用于数据关系,但不适用于用户输出。在用户方面,当他们在网站上看到Brooke时应该是; 布鲁克,纽约 - 美国。 (所以在本质上:布鲁克,1456 - 23)。

问题是:如果我只在邻居表中存储ID,那么每次我必须加入2个表来提取ID的名称。因此,为避免这种情况,最好将名称再次存储为表中的副本,以便列为:

n_id, name, country_id, country_name, continent_id, city_id, city_name

两种方式的性能差异是什么?或者优缺点?

**如果有帮助,网站就是一个社交网络。

5 个答案:

答案 0 :(得分:1)

在邻居表中添加重复名称时,您将对其进行反规范化。反规范化将使查询更快,尤其是在系统负载非常高的情况下。但是,非规范化需要付出代价,因为您必须编写和维护其他代码以使冗余数据保持同步。

我会记住两件事:

  1. 作为一般规则,永远不要优化某些东西,直到你证明需要优化它(Abrash的规则#1)
  2. 如果您发现联接需要更快,首先尝试的优化是调整索引。这将允许您快速连接而不会失去规范化设计的好处。

答案 1 :(得分:0)

数据库设计最重要的规则是数据不应重复。你的设计看起来很好。不必为必须编写两个连接来获取需要显示的数据而烦恼,有几百行的查询:)

至于性能,来自单个表的数据自然比来自两个表的数据快。

答案 2 :(得分:0)

作为一般规则,最好正确地规范化数据,然后进行反规范化以解决特定的性能问题。你有性能问题吗?你能设置ID-only选项并进行测试吗?

您的第一个表设计具有规范化数据(Google插入,删除和更新异常)的所有常规优势。如果你有名字(以及附近表中的ID或没有ID,你必须有一个确保它始终相同的过程(例如从未预先填充的预先填充的下拉列表等中选择)和一个​​更新的方法如果名称改变,等等。

如果您遇到真正的性能问题,这可能值得额外考虑。其他问题仍然存在于您的标准化解决方案中。

答案 3 :(得分:0)

不要在交易数据库中重复数据。

正确规范化,如果您担心连接性能,可以通过在适当的位置添加索引,排序连接条件等来相应地调整查询。有些工具可以帮助理解供应商选择的查询计划。另请注意,现代数据库在优化查询方面做得非常出色,例如选择连接首先过滤掉更多数据的表,以便减少额外的连接条件。

另一方面,数据仓库通常会复制数据以优化对不变历史信息的报告。

答案 4 :(得分:0)

您提出的非规范化设计的主要缺点是正确的参照完整性约束和更新操作变得过于复杂。如果与City_ID 1456关联的数据发生更改,则您不仅需要更改City表中的一行,还必须更改交叉引用City表的每个NBighbourhood行中的存储值(包含City_ID = 1456) 。这些“更新异常”是规范化的主要原因。

衡量表现很棘手;它将取决于DBMS和表的大小,但可以想象加入较小的表比扫描所有大表更快(其中'大表'是你提出的修改后的邻居表被所有人淹没您要添加的额外数据)。除非您将邻居表中的City_ID和City_Name列都编入索引(因此在索引中使用的空间比使用规范化设计时更多),您对单个城市中所有人的扫描可能需要更长时间(因为整个必须按顺序读取邻居表,而不是城市表上的索引查找以查找City_ID,然后在邻居表中精确搜索正确的City_ID的索引扫描。

因此,您的非规范化,“高效”设计有可能通过几种不同的度量而不是当前的标准化设计来降低效率。

如果您决定更改当前的规范化设计,请确保衡量真实成本 - 更新操作的复杂性和使用的磁盘空间以及查询速度。反规范化可能仍然会更好;这不一定是扣篮。随着数据大小的变化,您的成本等式可能会随着时间的推移而发生变化,因此您可能需要多次进行测量。