我在染色体上有染色体(具有长度的物体)和带有区域(例如基因)的表格(具有定义为两个整数的范围的对象 - 位置开始和位置结束)。我想禁止插入坐标大于特定染色体长度的数据库区域。
在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)
);
答案 0 :(得分:1)
此类约束在任何数据库中都不能轻松。通常,这将使用触发器来处理。问题是它是两个表之间的约束,但它不使用相等。
SQLite以及其他数据库中都提供了触发器。
一种解决方法是使用用户定义的函数进行检查约束。该函数可以查找chromosomes
表并在check
约束中使用。 SQLite实际上没有用户定义的函数。一个支持这个的数据库是Postgres。
另一种选择是将所有数据修改包装在存储过程中(这往往是我设计系统的方式)。然后存储过程可以执行所需的所有检查。