如果EAV是邪恶的,那么动态值的用途是什么?

时间:2013-06-21 09:28:59

标签: c# database entity-framework database-design entity-attribute-value

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

这对我来说很难,因为我从来没有做过这样的事情,因为我做了我的研究,所有人都说EAV系统太可怕了,而且你应该设计不同的,问题是之后没有人告诉 - 如何?

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

这是我到目前为止所做的。

enter image description here

4 个答案:

答案 0 :(得分:20)

经验法则的问题在于,它们很快就会从“将 X ”改为“永远不会做 X ”这一点。

EAV通常一个坏主意,因为它在很多方面都违背了关系模式的目的,从而剥夺了关系DBMS的许多特性和优势,以及构建在RDBMS上的其他技术,例如像Entity Framework这样的ORM。

然而,有一些设计问题,RDBMS不适合。有些东西非常不合适,必须发明一种全新的技术(例如像MongoDB这样的NoSQL DB)。

有时EAV可能是一组不完美选项留给你的最佳选择。如果你不能(不能)知道你的架构是什么,那么EAV可能是你最好的选择。如果您的架构变得不重要,则尤其如此。例如,考虑一个在线产品目录,其中有大量的产品列表,每个产品都有一些功能。您无法提前预测哪些产品具有哪些功能。最后,您对产品功能的唯一做法是将它们转储到“feature:value”列表中。这种情况下架构并不是特别强大,因此用EAV击败它并不是特别具有破坏性。

最重要的是要了解您的设计选择将对您的功能和操作做些什么。所有设计都是权衡取舍。关键是要有意识地进行权衡。而不是“EAV是邪恶的”,而是反思:“EAV是一把装满枪的枪,确保你知道你指着它的脚。”

答案 1 :(得分:3)

嗯,在最简单的层面上,只需将值添加为列;也许在数据库中使用sparse column support,这样它就不会产生太大的影响。这避免了EAV和内部平台效应,并且意味着您将值存储为常规的类型值

答案 2 :(得分:2)

EAV不是“邪恶的” - 当其他解决方案可能更合适时,它有时会被滥用。

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


1 例如避免locking the table或因为你选择的ORM不能很好地使用它,或者因为它们太多了。

答案 3 :(得分:2)

当您开始使用EAV字段进行报告或BI时,您将需要自己拍摄。

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

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

  3. 例如

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

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