同一属性的多种可能数据类型:空条目、EAV 或存储为 varchar?
Multiple possible data types for the same attribute: null entries, EAV, or store as varchar?
我正在为燃烧实验创建一个数据库。每个实验都有一些我称之为 'details' 的科学元数据。例如 ('Fuel', 'C2H6') 或 ('Pressure', 120)。因为相同的详细名称(如 'Fuel')出现了很多次,所以我创建了一个 table 来存储名称和单位。这是一个简化版本:
CREATE TABLE properties (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
units NVARCHAR(15) NOT NULL DEFAULT 'dimensionless',
);
我还创建了一个名为 'details' 的 table,它将 'properties' 映射到值。
CREATE TABLE details (
id INT AUTO_INCREMENT PRIMARY KEY,
property_id INT NOT NULL,
value VARCHAR(30),
FOREIGN KEY(property_id) REFERENCES properties(id)
);
这并不理想,因为 value
属性有时是化学名称,有时是浮点数。将来,甚至可能会有具有整数值的新条目。将所有内容存储在 VARCHAR 中似乎很浪费。因为以后很难改变,所以我想现在就做出正确的决定。
我已经为此研究了几个小时,并考虑了四个选项:
- 在
value
下将所有内容存储为 varchar(开发最简单)
- 使用 EAV 模型(开发最复杂)。
- 为每种类型创建一个列,并有大量的 NULL 条目。
value_float, value_int, value_char
- 使用 JSON 数据类型。
仔细观察每一个,似乎它们都以不同的方式表现不佳。 (1) 不好,因为它占用了额外的 space 并且我必须执行额外的操作才能将字符串解析为数值。 (2) 不好,因为复杂性大幅增加(四个额外的 tables 和更多的连接操作),而且我听说要避免使用 EAV。 (3) 是复杂性的中间地带,但每个 table 条目将有两个 NULL 值。 (4) 似乎与 (1) 相似,我不确定它可能更好还是更差。
我不希望这个数据库或数百万条目有巨大的增长。它只需要对研究人员来说是快速和可搜索的。为了 better/faster 用户体验,我愿意有更多的后端复杂性。
现在我意识到在数据库设计中没有那么多明确的答案。我只是想了解一下我的三个选项,或者我没有想到的另一个选项。
编辑:添加了JSON选项。
嗯,你必须牺牲一些东西。要么高清space,要么性能,要么specific/general维度,要么easy/complex开发维度。根据您的需要和情况选择 mix suitable。 - 我在 2000 年用一种通用的 EAV 解决方案解决了这个问题:基本记录有一个大多数事件共享的共同属性,然后连接到没有值的属性(关联 table),那些非常具体 properties/values 我存储在 XML 中的 BLOB 标签中。通过这种方式,我将常用属性与那些非常具体的属性结合起来。由于这是非常通用的解决方案,您可能不需要,我会牺牲 space,它现在很便宜。谁在乎你拿的 space 多于 "correct according to data modeling theory"。好的数据模型会很难看,那又怎样? - 您仍然需要决定 specific/general 维度 - 如何解决特定属性 - 作为特定列(是的,如果它们经常重复)或 属性-TypeOf属性- table.
的值类型
我正在为燃烧实验创建一个数据库。每个实验都有一些我称之为 'details' 的科学元数据。例如 ('Fuel', 'C2H6') 或 ('Pressure', 120)。因为相同的详细名称(如 'Fuel')出现了很多次,所以我创建了一个 table 来存储名称和单位。这是一个简化版本:
CREATE TABLE properties (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
units NVARCHAR(15) NOT NULL DEFAULT 'dimensionless',
);
我还创建了一个名为 'details' 的 table,它将 'properties' 映射到值。
CREATE TABLE details (
id INT AUTO_INCREMENT PRIMARY KEY,
property_id INT NOT NULL,
value VARCHAR(30),
FOREIGN KEY(property_id) REFERENCES properties(id)
);
这并不理想,因为 value
属性有时是化学名称,有时是浮点数。将来,甚至可能会有具有整数值的新条目。将所有内容存储在 VARCHAR 中似乎很浪费。因为以后很难改变,所以我想现在就做出正确的决定。
我已经为此研究了几个小时,并考虑了四个选项:
- 在
value
下将所有内容存储为 varchar(开发最简单) - 使用 EAV 模型(开发最复杂)。
- 为每种类型创建一个列,并有大量的 NULL 条目。
value_float, value_int, value_char
- 使用 JSON 数据类型。
仔细观察每一个,似乎它们都以不同的方式表现不佳。 (1) 不好,因为它占用了额外的 space 并且我必须执行额外的操作才能将字符串解析为数值。 (2) 不好,因为复杂性大幅增加(四个额外的 tables 和更多的连接操作),而且我听说要避免使用 EAV。 (3) 是复杂性的中间地带,但每个 table 条目将有两个 NULL 值。 (4) 似乎与 (1) 相似,我不确定它可能更好还是更差。
我不希望这个数据库或数百万条目有巨大的增长。它只需要对研究人员来说是快速和可搜索的。为了 better/faster 用户体验,我愿意有更多的后端复杂性。
现在我意识到在数据库设计中没有那么多明确的答案。我只是想了解一下我的三个选项,或者我没有想到的另一个选项。
编辑:添加了JSON选项。
嗯,你必须牺牲一些东西。要么高清space,要么性能,要么specific/general维度,要么easy/complex开发维度。根据您的需要和情况选择 mix suitable。 - 我在 2000 年用一种通用的 EAV 解决方案解决了这个问题:基本记录有一个大多数事件共享的共同属性,然后连接到没有值的属性(关联 table),那些非常具体 properties/values 我存储在 XML 中的 BLOB 标签中。通过这种方式,我将常用属性与那些非常具体的属性结合起来。由于这是非常通用的解决方案,您可能不需要,我会牺牲 space,它现在很便宜。谁在乎你拿的 space 多于 "correct according to data modeling theory"。好的数据模型会很难看,那又怎样? - 您仍然需要决定 specific/general 维度 - 如何解决特定属性 - 作为特定列(是的,如果它们经常重复)或 属性-TypeOf属性- table.
的值类型