两个表结构的区别

时间:2013-12-26 09:58:02

标签: mysql sql database database-design

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

TABLE1

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

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

3 个答案:

答案 0 :(得分:18)

反模式?

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


为什么EAV不好

数据完整性支持

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

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

行重建

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


可以证明这是合理的吗?

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

答案 1 :(得分:2)

在第二种情况下(table2)这很复杂,在我们查询数据时需要花费很多时间来查找数据。如果您不知道列数或它们是不同的,则使用这种情况,如果您有固定长度的列然后使用第一种情况(table1),因为在这种情况下数据可以快速找到。

答案 2 :(得分:1)

包含idnameagebirthdateaddress列的表格是您在部署之前所知道的,要存储的信息关于一个实体。

如果您在部署后只知道要存储的有关实体的信息,则可以使用包含idcol_namecol_value列的表格(例如,如果非技术人员应该能够定义他们希望捕获的字段)。效率较低,但允许您在不更改数据库架构的情况下定义新字段。