为科学数据设计。具有数百列的数据表或具有通用值列和数百行 (EAV) 的数据表?

mre*_*tko 5 schema database-design eav

我正在尝试改进我最近开始工作的生物医学科学实验室的数据存储。现有的工作流程非常糟糕,涉及许多不同格式的 Excel 工作表,所有这些工作表都通过复制粘贴和错误宏的过程进行聚合。

我的目的是创建一个简单的 python 脚本,它将实验的所有数据聚合到 SQLite 数据库中,然后生成必要的 CSV/XLSX 输出。

我的问题是,对于我们实验的单次试验,我们最终在大约 10 个不同的时间点记录了大约 100 个变量。我最初的冲动是创建一个valuevariable表:

CREATE TABLE value (val_id INTEGER PRIMARY KEY, 
                    value TEXT, 
                    var_id INTEGER,
                    event_id INTEGER,
                    exp_id INTEGER,
                    FOREIGN KEY (var_id) REFERENCES variable(var_id),
                    FOREIGN KEY (event_id) REFERENCES event(event_id),
                    FOREIGN KEY (exp_id) REFERENCES experiemnt(exp_id)
);

CREATE TABLE variable (var_id INTEGER PRIMARY KEY,
                      var_name TEXT,
                       var_type TEXT
);

value:
val_id | value | var_id | ...
0      | 10    | 0
1      | "ROSC"| 5

variable:
var_id | var_name | var_type
0      | Pressure | DECIMAL
...
5      | Outcome  | TEXT
Run Code Online (Sandbox Code Playgroud)

但这感觉不对,我预感到这样做的“正确”方法是拥有一个包含数百列的单个数据表,否则这些列将在variable表中进行描述,因为这样可以更轻松地进行类型检查(是的,我知道 SQLite 不这样做,但原则上)。

任何有关如何解决此问题的见解将不胜感激。

Vér*_*ace 5

您所描述的是大多数数据库专业人员都会运行的 EAV(实体属性值)模型。它也被讽刺地称为 OTLT(一个真实的查找表),是一个典型的新手错误。你的预感是对的!

这里(和这里)是 Joe Celko(一位经验丰富的 SQL 程序员,他是/曾经是 SQL 标准委员会的成员。他用“破坏的 EAV”这个短语来命名他的文章的事实应该给你一个线索:- )。Celko 也将此称为大规模统一代码密钥。

首字母缩略词是 MUCK 绝非巧合!:-)

以这种方式存储数据破坏了关系数据库的许多优点,例如 DRI(声明性引用完整性)、CHECK 约束和 DEFAULT 值。

请创建一个包含 100 个字段和 10 行的表 - 如果这是您的数据所需要的,那就去做吧。也许其他一些带有实验 ID、日期时间和实验者 ID 的字段也有用?这样你就可以在给定的时间段内执行分析,各种其他聚合 - 基本上是对所有数据进行切片和切块。

< 个人意见> 如果你还没有选择你的数据库并且乐于使用 F/LOSS,那么我可以推荐 PostgreSQL - 它的 SQL 方言是迄今为止最丰富的开源数据库(我与该项目没有关系) . 请点击这里了解如何执行数据类型在SQLite的,但PostgreSQL的报价超过SQLite的-这是多用户,例如,无需通过箍来执行数据类型跳</个人意见>

[编辑1]

再补充一句,为了完整起见,只有一个重要的系统使用 EAV 模型——那就是 Magento ( 1 , 2 )。它的主要利基是时尚行业,其中 EAV 模型可能适用于稀疏的桌子(时尚单品往往有多种颜色、款式、尺寸……)。它很受欢迎(1 , 2),但 MySQL 也是如此,它在很多方面都不如 PostgreSQL、Firebird 和(除了多用户功能)SQLite。