我有一个x
这样定义的表:
CREATE TABLE x (
xid INTEGER NOT NULL PRIMARY KEY,
yid INTEGER NOT NULL REFERENCES y(yid),
is_principal BOOLEAN NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
该定义遗漏了一个必须满足的约束x
。用英语来说,这个约束可以这样描述:
字段中可能有一行或多行具有给定值
yid
,但其中必须始终有一行的is_principal
字段为TRUE
1。
我正在寻找一种方法来强制执行此约束。
(如果重要的话,我对适用于 SQLite3 和 PostgreSQL 的解决方案特别感兴趣。)
编辑:为了清楚起见,上面的描述并不排除 table 中存在y
其值yid
在 table 中根本没有提及的行x
。对于 的此类值,yid
根本没有任何价值xid
,无论是本金价值还是其他价值。仅对于yid
表中出现的 x
那些值,表中必须有且只有一行x
具有is_principal = TRUE
。
1表达相同约束的另一种方法是以下两个查询应始终产生相同的输出:
SELECT DISTINCT yid FROM x ORDER BY yid; …
Run Code Online (Sandbox Code Playgroud) (我对将下面的问题视为问题的特例的答案特别感兴趣: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 …
Run Code Online (Sandbox Code Playgroud)