一尘不染

两个表结构之间的区别

mysql

我对这两种结构感到非常困惑。这两个表的优缺点是什么?哪一个更好,为什么?

表格1

id,         name,       age,        birthdate,      address
somedata1   somedata1   somedata1   somedata1       somedata1
somedata2   somedata2   somedata2   somedata2       somedata2
somedata3   somedata3   somedata3   somedata3       somedata3

表2

id,         col_name,   col_value

somedata    name        somedata
somedata    age         somedata
somedata    birthdate   somedata
somedata    address     somedata

somedata2   name        somedata2
somedata2   age         somedata2
somedata2   birthdate   somedata2
somedata2   address     somedata2

somedata3   name        somedata3
somedata3   age         somedata3
somedata3   birthdate   somedata3
somedata3   address     somedata3

阅读 225

收藏
2020-05-17

共1个答案

一尘不染

反模式?

通常,第二个表在数据库设计的上下文中是 反模式的 。而且,它还有特定的名称: 实体属性值
(EAV)。在某些情况下,使用这种设计是有道理的,但是这种情况很少见,甚至可以避免。

为什么EAV不好

数据完整性支持

尽管事实是这样的结构似乎更加“灵活”或“先进”,但这种设计仍存在缺陷。

  • 不可能设置强制属性 。您不能使某些属性为强制性的,因为属性现在存储为一行-并且未设置该属性的唯一标志-表中没有相应的行。SQL不允许您本机构建这样的约束-因此,您必须在应用程序中进行检查-是的, 每次都查询表
  • 混合数据类型 。您将无法使用SQL标准数据类型。因为您的value列必须是其中所有存储值的“超类型”。这意味着-通常,您必须将所有数据存储为 原始字符串 。然后,您将看到像字符串一样处理日期,每次转换数据类型,检查数据完整性等等都是多么痛苦的事情。
  • 不能强制执行参照完整性 。在正常情况下,您可以使用外键通过在父表中定义的值来限制您的值。但这不是这种情况-这是因为引用完整性应用于表中的每一行,而不应用于行值。所以-您将失去这一优势-这是关系数据库中 的基础 之一
  • 无法设置属性名称 。这意味着-您不能在数据库级别适当限制属性名称。例如,您将"customer_name"在第一种情况下将其写为属性名称-另一个开发人员会忘记使用它"name_of_customer"。并且..没关系,DB会通过它,并且您将花费数小时来调试这种情况。

行重建

此外,在常见情况下,行重构将很糟糕。例如,如果您有5个属性-这将是5个自我表JOIN-s。对于如此简单的情况-乍一看-
情况来说太糟糕了。因此,我什至都不想想象您将如何维护20个属性。

可以辩解吗?

我的意思是-不。在RDBMS中,总会有避免这种情况的方法。这太糟糕了。而且,如果打算使用EAV,则最佳选择可能 是非关系 数据库。

2020-05-17