如何强制执行矩形阵列数据的结构约束?

kjo*_*kjo 5 schema database-design constraint

(我对将下面的问题视为问题的特例的答案特别感兴趣:RDBMS 应该如何强制执行比“一对多”和“多对多”更具体的结构约束?

生物医学研究中的许多实验数据都是在矩形排列的“孔”的“板”中收集的。这些孔阵列板有几种标准尺寸的市售:2 × 3、4 × 6、8 × 12、16 × 24 和 32 × 48。

考虑以下两种替代方案,用于在 RDB 中存储 2 × 3 板孔的测量值:

-- alternative 1
CREATE TABLE measurement_foo (
    plate_id FOREIGN KEY REFERENCES plate(plate_id),
    plate_row CHAR(1),
    plate_column INTEGER,
    value REAL
);

-- alternative 2
CREATE TABLE measurement_foo (
    plate_id FOREIGN KEY REFERENCES plate(plate_id),
    a1 REAL,
    a2 REAL,
    a3 REAL,
    b1 REAL,
    b2 REAL,
    b3 REAL
);
Run Code Online (Sandbox Code Playgroud)

我的直觉是采用替代方案 1:它可以推广到任何尺寸的板,并且可以以一种直接的方式进行修改,以记录每个孔的多个不同测量值,如

CREATE TABLE measurement (
    plate_id FOREIGN KEY REFERENCES plate(plate_id),
    plate_row CHAR(1),
    plate_column INTEGER,
    foo FLOAT,
    bar FLOAT,
    baz FLOAT
);
Run Code Online (Sandbox Code Playgroud)

相比之下,要使替代方案 2 适应 16 × 24 孔格式(例如),需要定义一个包含 1 + 384 列的表:plate_id, a01, ..., a24, b01, ... , b24, ..., p01, 。 .., p24. 此外,需要为每种类型的测量定义不同的此类表。

什至考虑备选方案 2 的主要原因是,它单独执行了每个板恰好包含 6 个孔的约束;备选方案 1 没有。

(此外,备选方案 2 中表的一条记录将包含与备选方案 1 中的一条记录的多达 6 条记录一样多的信息,这让我怀疑备选方案 1 中的表是否已完全规范化。)

对于备选方案 1,我可以想象如何强制执行较弱的约束,即一个板最多包含6 个孔,即通过对(plate_id、plate_row、plate_column)施加唯一性约束,并将plate_row 和plate_column 列限制为域('a ', 'b') 和 (1, 2, 3) 分别。但数据中仍有可能遗漏油井。

数据库应该如何加强板和孔之间的结构关系?

Sto*_*leg 2

当前所有 RDBMS 的表都可以有CONSTRAINTSon 列。每次将数据插入表中时都会检查这些约束。它还可以根据其他表检查数据。

我们知道每种板类型都有一定数量的行和列。我们可以枚举每种板类型的所有行和列。因此,当插入数据时,数据库可以检查给定板类型是否存在特定的行/列组合。

让我们创建一组表:

create table Plate_Types (
Plate_Type_id int,
Plate_Size int,
Plate_row int,
Plate_col int)
Run Code Online (Sandbox Code Playgroud)

该表包含每个板尺寸的描述,如下所示:

Id     Size   Row     Col
1       6       1       1    -- 2x3
1       6       1       2
...
1       6       2       3
5       1536    1       1    -- 32x48
...
5       1536    32      32
Run Code Online (Sandbox Code Playgroud)

然后,在替代方案 1 的主表中,我们引入了一个外键 - 一个指向另一个表的“链接”,用于检查行和列对于该板尺寸是否有效。

create table MyTable (
well_id int,
plate_id int, 
plate_size int,
row_id int,
col_id int,
value real);

ALTER TABLE MyTable  
ADD CONSTRAINT FK_Plate_SizeCheck 
   FOREIGN KEY (Plate_size_id, Row_id, Column_id)
    REFERENCES Plate_Types (Plate_type_id, Plate_row, Plate_col);
Run Code Online (Sandbox Code Playgroud)

这里的约束执行以下操作:对于每个插入的行,DB 都会转到表 Plate_Types 并查找Plate_size_id, Plate_row和的组合Plate_col。换句话说,它检查此印版尺寸是否可以具有 I 行和 J 列。如果不匹配,则 DB 会触发错误。

请注意,对于您的示例,这是强制执行数据完整性的几种可能的解决方案之一。医疗数据通常数量巨大,而这种特定设计的性能是不同的问题。

附言。这是针对非开发人员的简短解释。代码和表格设计仅用于概念说明。