在以下情况中:
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
。
第二种方法会更快,但涉及存储冗余数据。是否存在实施它的情况?
答案 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方法。几乎所有应用程序都足够快。话虽如此,对于某些高性能商店,您可能希望按照建议存储冗余数据,但这需要在写入时保持数据同步。