10

我需要创建数据库,其中Accountgroup表将具有动态字段,以便Accounts可以在需要时输入这些动态字段值。这可能并不重要,但我将 C# 与 EF 和 Linq 一起使用。

这对我来说很难,因为我从来没有做过这样的事情,而且因为我做了我的研究,每个人都说 EAV 系统很糟糕,你应该以不同的方式设计它,问题是事后没人告诉 - 怎么做?

所以也许你可以帮助我,告诉我如何在不做 EAV 的情况下实现类似的东西?

这就是我到目前为止所拥有的。

在此处输入图像描述

2020年编辑:

我只想编辑这篇文章,因为现在是 2020 年,对此有明确的答案:带有 jsonb 类型的 Postgres。EF Core 支持它,因此您实际上可以毫无问题地保存和查询动态 json。

4

4 回答 4

23

经验法则的问题在于,它们很快就从“做 X 通常是个坏主意变成了“从不做X ”。

EAV通常是一个坏主意,因为在许多方面它违背了关系模式的目的,因此它剥夺了关系 DBMS 以及其他基于 RDBMS 的技术的特性和优势,例如像实体框架这样的 ORM。

但是,RDBMS 不适合某些设计问题。有些非常不合适,以至于必须发明一种全新的技术(例如,像 MongoDB 这样的 NoSQL DB)。

有时 EAV 可能是您在一系列不完善的选项中的最佳选择。如果您事先不(不能)知道您的架构是什么,那么 EAV 可能是您的最佳选择。如果您的架构被证明是不重要的,则尤其如此。例如,考虑一个在线产品目录,其中包含大量产品,每个产品都有一些功能。您无法提前预测哪些产品将具有哪些功能。最后,您对产品功能所做的唯一事情就是将它们转储到“功能:价值”列表中。在这种情况下,模式不是特别强大,因此用 EAV 击败它并不是特别有害。

最重要的是了解您的设计选择将对您的能力和运营产生什么影响。所有的设计都是权衡。关键是有意识地进行权衡。与其说“EAV 是邪恶的”,不如想一想:“EAV 是一把上膛的枪,确保你知道你指的是谁的脚。”

于 2013-06-21T10:40:40.740 回答
3

好吧,在最简单的级别,只需将值添加为列;也许在数据库中使用稀疏列支持,这样它就不会产生太大的大小影响。这避免了 EAV 和内部平台效应,并且意味着您将值存储为常规的类型化值

于 2013-06-21T09:46:19.260 回答
3

EAV 不是“邪恶的”——它只是有时在其他解决方案可能更合适时被滥用。

如果您的属性是真正动态的并且您希望避免动态添加列1,那么 EAV 是合适的。


1例如,为了避免锁定表,或者因为您选择的 ORM 不能很好地使用它,或者因为它们太多了。

于 2013-06-21T10:31:38.483 回答
2

当您开始将 EAV 字段用于报告或 BI 时,您会想要朝自己的脸开枪。

  1. 使用 XML 字段。大多数数据库都具有良好的 XML 支持、XPath 查询、索引。

  2. 为租户的用户设计字段创建新架构。让用户使用该模式(在合理范围内)做他们想做的事。

例如

create table account_group (
  id primary key references real_schema.accountgroup(id),
  super_important_note_field text not null
);

是的,您可以跨模式执行外键。

于 2013-06-21T17:43:39.750 回答