两个表结构的区别

Cin*_*y93 7 mysql sql database database-design

我对这两种结构非常困惑.这两张表有什么优缺点?哪一个更好,为什么?

表格1

id,         name,       age,        birthdate,      address
somedata1   somedata1   somedata1   somedata1       somedata1
somedata2   somedata2   somedata2   somedata2       somedata2
somedata3   somedata3   somedata3   somedata3       somedata3  
Run Code Online (Sandbox Code Playgroud)

TABLE2

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
Run Code Online (Sandbox Code Playgroud)

Alm*_* Do 18

反模式?

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


为什么EAV很糟糕

数据完整性支持

尽管事实上,这种结构似乎更"灵活"或"先进",但这种设计存在缺陷.

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

行重建

另外,在一般情况下,行重建会很糟糕.例如,如果您有5个属性 - 那将是5个自助表JOIN.这种简单 - 乍一看 - 太糟糕了.所以我甚至不想想你将如何保持20个属性.


它有道理吗?

我的观点是 - 不.在RDBMS中总会有一种方法可以避免这种情况.这太糟糕了.如果打算使用EAV,那么最佳选择可能是非关系型数据库.