名称值对 table vs parent child

Name value pair table vs parent child

我想存储大约 10 万行数据,以及所有数据的一些公共字段。 所有数据都有一个类别,其他字段基于类别。

例如,如果数据属于类别 1,则它有 extrafield1extrafield2

我搜索并找到了两种存储数据的方式。

1-名称值对

Table1
ID    Name     Category   Field2           Field3
1     Name1    1          Value            Value
2     Name2    2          Value            Value

Table2 
ID    Table1_ID         Name           Value
1     1                 extrafield1    1
2     1                 extrafield2    2
3     1                 extrafield3    3
4     2                 extrafield4    4
5     2                 extrafield5    5

2-父子table

Table1
ID    Name     Category   Field2           Field3
1     Name1    1          Value            Value
2     Name2    2          Value            Value

Tableforcategory1 
ID    Table1_ID         extrafield1    extrafield2     extrafield3
1     1                 1              2               3


Tableforcategory2 
ID    Table1_ID         extrafield4    extrafield5
1     2                 4              5   

所以我的问题是什么时候使用方法1和什么时候使用方法2.

由于多种原因,通常首选方法 2:

  • 它更接近于对不同类别所代表的实体进行建模。
  • 它允许列具有不同的数据类型。
  • 它可以更轻松地为 value-only 列实施检查约束。
  • 更容易实现引用列的外键约束。
  • 如果合适的话,它可以更轻松地实施唯一约束。
  • 它更容易实现 not-NULL 和默认值。
  • 它可以更轻松地在特定属性值上添加列。

可能还有其他原因。

第一种方法——称为 entity-attribute-value 建模 (EAV)——绝对是一种替代方法。主要适用于两种情况:

  • 属性的数量超出了正在使用的数据库中的列限制。
  • 属性稀少,因此任何给定实体都只使用少数属性。

有时混合使用这两种方法是合适的,常用属性以关系格式存储,稀疏属性存储为 EAV。

还有其他方法,例如将值存储在 JSON 或 XML 对象中。这些通常不被推荐,但在某些情况下可能适用于某些数据库——特别是当所有属性需要被视为一个块并一起返回和设置时。

这取决于查询类型和数据模型的稳定性。

如果您的查询本质上是静态的,这意味着您知道何时要使用 "extrafield_x",那么方法 1 更简单、更高效,但灵活性较低。

如果你需要更多的动态查询,及时你可能会更多类别和更多"extrafields",方法 1 更灵活,不需要维护数据模型,但使用起来更复杂并且可能更慢。