我被要求为应用程序提出逻辑数据模型。我已经确定了所有实体,并使用ERD记录了它们。现在一位同事提出了一些我不同意的变化,我需要有理由反对我和他的方法,以便能够找到问题的最佳解决方案。
所以基本上讨论就是这样的:我有一个像这样的实体:
The_Entity
我的同事建议做
The_Entity
属性
所以基本上将属性建模为实体。
我认为我的方法在语义上更有意义,但它也更加静态(在实现中,添加属性需要向表中添加列)。你对此有何看法?
答案 0 :(得分:2)
您的同事所倡导的内容称为“实体 - 属性 - 值”或EAV,并且通常被视为反模式。 (谷歌周围的“EAV邪恶”,你会发现许多的例子。)如果你想要弹药为什么你不应该按照你的同事建议的方式去做,你会毫不费力地找到它。
话虽如此,你会发现如果你看看我在SO和DBA.SE上的答案,我在某些特定情况下是EAV的罕见支持者,其中关于EAV的坏事不适用。尽管如此,由于我们不知道您的特定型号是否符合这些特殊条件,我认为避免使用EAV是非常安全的。
答案 1 :(得分:2)
同意已经给出的答案。
针对EAV的最明显的案例是当涉及您提及的属性的业务规则时。比方说,在您的示例中,“属性1和属性2不能都长于......字符。”。
如果使用单个三列表实现示例,那么实现该业务规则就像在该表上定义单个CHECK约束一样简单明了。该规则将简单明了,也适用于稍后阅读您的设计的其他人的解码,并且在运行时,检查约束将像swoosh一样。
如果使用EAV方法实现示例,则无法以声明方式 实现相同的业务规则 ,因此需要(相当多)额外代码,对于那些稍后阅读设计的人来说,解码起来会更加困难,因为它有更多的错误机会,特别是在事务序列化的舞台上,在运行时,它最终可能成为使系统运行的性能噩梦就像没有腿的狗一样。
你也可以问你的朋友他打算如何在他的设计中包含属性,如果这些属性的值是整数,或者是日期,浮点数,布尔值,还是DBMS必须提供的任何其他类型。 (他不能在没有创建性能问题的情况下坚持一个表,不必在读取时解串任何数字,并在写入时串起任何数字。这就是CPU噩梦。)
您的朋友“发现”了,实际上设计使用了DBMS本身的 来记录用户数据库的结构。 DBMS目录已经知道了几十年的结构(除了'V'部分,当然,目录是EA,可以这么说,没有V的EAV),所以它在任何意义上都不是一个“新”的想法。
所以是的,当他声称使用他的设计时,更容易调整数据库的结构,从某种意义上说,他是对的。但是,如果您还考虑实际的附加价值(通常低于EAV支持者建议的价值),那么增加灵活性的价格在大多数情况下都会非常高, 尤其 )“增加灵活性”。
EAV方法 可能 可接受的典型案例是处理问卷。如果问卷的确不是99.99%稳定(可以随着时间的推移而扩展很多),并且没有很多“规则”适用于“如何填写”(如果问题7的答案是“是”,那么必须回答问题8),问卷的答案通常在“隔离”中比在“组合”中更多地检查,那么EAV的大部分缺点都不适用,并且可以有效地被考虑。