我在选择一种数据库表设计方式之间陷入困境。场景是我需要制作手机和平板电脑规格的数据库。数据库可以有两种方式...
1- 长列方式,我会将每个规格字段添加为单独的列,这将产生 38 列,从而在一行中生成完整的产品规格。
2- 长行方式,我将只添加 5 列:id
、name
、value
、brand
和model
,将每个产品规格保存在名称值对中,这将导致每个规格有 38 行。
我应该走哪条路……为什么……?
我在选择一种数据库表设计方式之间陷入困境。场景是我需要制作手机和平板电脑规格的数据库。数据库可以有两种方式...
1- 长列方式,我会将每个规格字段添加为单独的列,这将产生 38 列,从而在一行中生成完整的产品规格。
2- 长行方式,我将只添加 5 列:id
、name
、value
、brand
和model
,将每个产品规格保存在名称值对中,这将导致每个规格有 38 行。
我应该走哪条路……为什么……?
第一个解决方案是更传统的。第二种称为“实体-属性-值”(EAV)。
对于大多数应用程序,第一个更可取。例如,在第二种方法中,所有值都必须是相同的类型。但一个可能是产品发布的日期,而其他可能是字符串。
第二个也导致更清晰的查询。必须将数十行的属性组合在一起来描述单个模型可能是低效的。至少,它会导致更繁琐的查询。
这样的数据结构也使得进行数据验证检查和与其他表建立外键关系变得更加困难。
最后,EAV 方法使用更多空间。
在某些情况下,EAV 非常有价值。例如,如果您有数千个属性,而任何给定产品只有少数属性被使用。但是,38 列对于单个表来说是相当合理的。
问题应该是您是否会预见到将来需要添加的任何列,或者是否不会使用许多列。
对于您的第二个选项,您可以走得更远:
phones: [id], brand, model
attributevalues: [(phone), (name)], value
attributenames: [name]
where[xx]
是主键,(xx)
是外键。
但是,要利用打字,第一种是首选方法。
您还可以对其进行一些非规范化,并在另一个表中引入相关属性块,并使用 1:1 关系将其链接起来;您可以使用它将较少使用的属性移动到另一个表中。请注意,这只是空间妥协。