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

Handling optional fields of a record in a Relational Database

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

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

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

一个例子是苹果。对于某些食谱,任何苹果都可以。但是苹果有不同的品种,例如 "Granny Smith" 和 "Red Delicious"。一些苹果派食谱要求混合 Granny Smith 和 MacIntosh 品种。

为了解决这个难题,品种是可选的。

我目前的模式是有两个 tables:Optional_Variety 和 Variety:

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

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

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

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

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

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

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

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

问题是:
处理带有可选字段的记录的模式是什么,这样当该字段存在时,它与没有该字段的记录不同(a.k.a。具有唯一标识符)?

平台:MySql Windows 7,64 位; MySQL Windows Vista,32 位;
我正在使用带有 Object 关系映射的 C++ ODB 来连接数据库。

您将使用三个表:

base_ingredient (id_base_ingredient, ingredient_name, ....)

品种 (id_variety, id_ingredient, variety_name)

成分(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)

In addition, while a NULL itself does not require any storage space, NDBCLUSTER reserves 4 bytes per row if the table definition contains any columns defined as NULL, up to 32 NULL columns. (If a MySQL Cluster table is defined with more than 32 NULL columns up to 64 NULL columns, then 8 bytes per row is reserved.)