我有染色体表(有长度的对象)和染色体上区域(例如基因)的表(对象的范围定义为两个整数-位置开始和位置结束)。我想禁止插入坐标大于特定染色体长度的数据库区域。
这在SQLite中可能吗?如果不能,是否可以在任何其他SQL系统中使用(最好是免费的)?
DROP TABLE IF EXISTS chromosomes;
CREATE TABLE chromosomes
(
chromosome_id INTEGER UNIQUE NOT NULL CHECK(TYPEOF(chromosome_id) = 'integer'),
name VARCHAR UNIQUE NOT NULL CHECK(TYPEOF(name) = 'text'),
length INTEGER NOT NULL CHECK(TYPEOF(length) = 'integer' AND length > 0),
PRIMARY KEY (chromosome_id)
);
DROP TABLE IF EXISTS genes;
CREATE TABLE genes
(
gene_id INTEGER UNIQUE NOT NULL CHECK(TYPEOF(gene_id) = 'integer'),
symbol VARCHAR NOT NULL CHECK(TYPEOF(symbol) = 'text'),
refseq_id VARCHAR NOT NULL CHECK(TYPEOF(refseq_id) = 'text'),
chromosome_id INTEGER NOT NULL CHECK(TYPEOF(chromosome_id) = 'integer'),
start INTEGER NOT NULL CHECK(TYPEOF(start) = 'integer' AND start > 0 AND start < end),
end INTEGER NOT NULL CHECK(TYPEOF(end) = 'integer' AND end > 0 AND end > start),
external_db_link VARCHAR NOT NULL CHECK(TYPEOF(external_db_link) = 'text'),
PRIMARY KEY (gene_id)
FOREIGN KEY (chromosome_id) REFERENCES chromosomes(chromosome_id)
);
2条答案
按热度按时间7rfyedvj1#
这种类型的约束在任何数据库中都不“容易”可用。通常,这将使用触发器来处理。问题是它是两个表之间的约束,但它不使用相等。
触发器在SQLite和其他数据库中都可用。
一种解决办法是使用用户定义函数的检查约束。该函数可以查找
chromosomes
表,并在check
约束中使用。SQLite实际上并没有用户定义的函数。支持这一点的一个数据库是postgres。另一种选择是将所有数据修改 Package 在存储过程中(这往往是我设计系统的方式)。然后,存储过程可以执行所需的所有检查。
v64noz0r2#
冗余--使用外键将‘LENGTH’引入子表。那么您的CHECK约束就可以引用它了。