是否存在将冗余数据存储在数据库中以提高速度的情况?

时间:2013-05-25 19:20:18

标签: database relational-database

在以下情况中:

user has many bags
bag has many items

users
-id

bags
-id
-user_id

items
-id
-bag_id

有两种方法可以访问用户的项目。

1)可以向用户添加实例方法,该方法迭代每个用户的行李,并将行李的项目收集到数组中以返回。在Ruby on Rails中,类似于:

#in user.rb
def items
    items = []
    bags.includes(:items).each { |bag| items += bag.items }
end

2)直接在items表中添加user_id属性,并添加其他关系,以便user has many items。然后只需user.items

第二种方法会更快,但涉及存储冗余数据。是否存在实施它的情况?

4 个答案:

答案 0 :(得分:4)

是的,在某些情况下,为了提高性能,引入一些受控冗余是有意义的。通常,只有在数据库无法满足其性能要求时才能执行此操作。这被称为“非规范化”,您必须考虑的是:

  • 可以使实施更加复杂
  • 经常牺牲灵活性
  • 可能会加快检索速度但会降低更新速度(因为您现在必须更新多个位置)

因此,在性能不理想且关系具有较低的更新率和较高的查询率的情况下,需要考虑这一点。

还有一些非规范化的数据库设计,例如星型模式,用于数据库仓库。

答案 1 :(得分:1)

除非你没有告诉我们什么,否则就像这样的表

create table bagged_items (
  user_id integer not null,
  bag_id integer not null,
  item_id integer not null,
  primary key (user_id, bag_id, item_id)
);

至少为5NF。这都是关键。那里没有一点冗余数据。

你所做的不是正常化;规范化基于识别某些类型的依赖关系,并通过投影减少它们的影响。而你所做的不是非规范化;非规范化是对规范化的一种解除。

您只需将主键拆分为多个部分即可。我不会假装知道你遵循什么原则来证明这一点。 看起来有点像“没有表可能有多个外键”的正常形式。 (但是,当然,没有这样的事情。)

答案 2 :(得分:1)

是。特别是,报告数据库,数据集市和数据仓库通常使用故意偏离某些规范化规则的设计原则。结果是一个数据库中有一些冗余,但不仅查询速度更快,而且更容易。

当数据库和数据库用户之间存在分析GUI时,易于查询尤为重要。如果在数据库设计中遵循某些设计原则,则可以更容易地掌握这些分析工具。在这方面,规范化并不是特别有用。

非标准化设计并不意味着没有纪律的设计。特别是,如果您计划构建报告数据库,数据集市或数据仓库,则值得在星型模式和雪花模式设计上进行剔除。必须仔细编写星形或雪花模式保持最新的过程,有时称为ETL(提取 - 变换 - 加载),以防止受控冗余导致自相矛盾的数据。

在面向事务的数据库中,规范化通常会更好,尽管许多专家并不试图超越Boyce-Codd正常形式。

答案 3 :(得分:0)

为了组合来自两个SQL表的记录,数据库实现了可以JOIN的高效used from Ruby on Rails方法。几乎所有应用程序都足够快。话虽如此,对于某些高性能商店,您可能希望按照建议存储冗余数据,但这需要在写入时保持数据同步。