处理关系数据库中记录的可选字段

Posted

技术标签:

【中文标题】处理关系数据库中记录的可选字段【英文标题】:Handling optional fields of a record in a Relational Database 【发布时间】:2015-01-15 21:23:04 【问题描述】:

我正在寻找一种模式来处理可选字段。存在该字段的记录与没有该字段的记录是唯一的。

让我们以一种成分为例。 成分具有名称(标题)、类别名称和可选的品种名称。

+---------------+-------+----------+  
| ID_Ingredient | Title | Category |  
+---------------+-------+----------+  

一个例子是苹果。对于某些食谱,任何苹果都足够了。但是苹果有不同的品种,例如“Granny Smith”和“Red Delicious”。一些苹果派食谱要求混合格兰尼史密斯和麦金托什品种。

为了处理这种困境,品种是可选的。

我目前的架构是有两个表:Optional_Variety 和 Variety:

+------------+--------------+  
| ID_Variety | Variety Name |  
+------------+--------------+  

+---------------+------------+
| ID_Ingredient | ID_Variety | // Optional_Variety table  
+---------------+------------+  

如果一种成分有品种,可以通过搜索Optional_Variety 表找到该品种。

我的困境是,如果一种成分有多种,那么它应该有一个唯一的ID_Ingredient 标识符。毕竟,Granny Smith 苹果与 Red Delicious 苹果不同(外观和味道),所以它们应该是独特的成分。

我的另一个解决方案是在成分记录中包含品种字段:

+---------------+-------+----------+---------+  
| ID_Ingredient | Title | Category | Variety |  
+---------------+-------+----------+---------+  

我对这个架构的问题是许多成分没有多样性,而且我会因为有空字段而浪费数据库空间。

在我的实际实现中,成分的可选字段有很多,因此空字段浪费的数据库空间量会成倍增加。

问题是:处理带有可选字段的记录的架构是什么,这样当该字段存在时,它与没有该字段的记录不同(也就是具有唯一标识符)?

平台:Windows 7 上的 mysql,64 位; MySQL Windows Vista,32 位; 我正在使用带有对象关系映射的 C++ ODB 与数据库交互。

【问题讨论】:

【参考方案1】:

你会选择三张桌子:

base_ingredient(id_base_ingredient,成分名称,...)

品种(id_variety、id_ingredient、品种名称)

成分(id_ingredient - PK,id_base_ingredient - FK NOT NULL,id_variety NULL)

并且您不需要为每个品种使用不同的 id_ingredient,因为您将存储成分

我只是想知道别的。您希望存储多少成分和变体,因为 Oracle 表示存储空值非常便宜 (http://dev.mysql.com/doc/refman/5.5/en/storage-requirements.html)

此外,虽然 NULL 本身不需要任何存储空间,但如果表定义包含定义为 NULL 的任何列,NDBCLUSTER 保留 每行 4 个字节,最多 32 个 NULL 列。 (如果 MySQL Cluster 表定义有超过 32 个 NULL 列,最多 64 个 NULL 列,则每行保留 8 个字节。)

【讨论】:

引用指的是 MySQL Cluster 使用的 NDB 存储引擎。 This reference 可能是更好的选择。不管NULL 值的存储要求如何,可空列正是对“可选字段”建模的方式。存储要求不应决定架构设计。 那里看起来像一个循环引用。为了存储variety,必须知道id_ingredient。为了确定id_ingredient 的值,必须保存ingredient,但它有一个id_variety 字段,在提交variety 记录之前无法解析。

以上是关于处理关系数据库中记录的可选字段的主要内容,如果未能解决你的问题,请参考以下文章

实体框架代码优先关系 - 如何定义两个对象之间的关系:两个实体之间的可选一对一

实体框架中的可选一对多关系[关闭]

CoreData 对多的可选关系永远不能为零?

实体框架核心 - 无法删除可选的可为空关系

约束和约束关系

ManyToManyField 上的可选附加数据