Таблица SQL действительно требует первичного ключа. Теоретически таблица без ключа бессмысленна. (на практике таблица с 3G-строками без PK является катастрофой)
В вашем случае естественный ключ выглядит как комбинация столбцов (gene_id,sample_id,probe_id)
. Значения для этих трех столбцов необходимы, чтобы однозначно адресовал value
.
Проблема заключается в вашем if probe is absent; measurement was directly on the gene
антиограничении. Это запретит ключ из трех столбцов. Удаление этого исключения позволит использовать первичный ключ с несколькими столбцами. Теперь трюк с данными состоит в том, чтобы вставить одну фиктивную строку в зонд, например, с id = 0.
INSERT INTO probe(probe_id, probe_when, probe_name)
VALUES( 0, '1901-01-01 00:00:00', 'Dummy probe');
А теперь ОБНОВЛЯЙТЕ gene_measurements, меняя probe IS NULL
на probe=0
.
CREATE TABLE gene_measurements (
gene INTEGER NOT NULL REFERENCES genes(gene_id) ON DELETE CASCADE
, sample INTEGER NOT NULL REFERENCES samples(sample_id) ON DELETE CASCADE
, probe INTEGER NOT NULL REFERENCES probes (probe_id)
, value REAL NOT NULL
, PRIMARY KEY ( gene_id, sample_id,probe_id)
);
Возможно, добавьте еще несколько индексов с другим порядком, чтобы помочь определить c запросы, например:
CREATE UNIQUE INDEX ON gene_measurements (sample_id,gene_id,probe_id);
И вам понадобится вспомогательный индекс для зонда FK, подойдет любой индекс с зондом в качестве первого столбца:
CREATE INDEX ON gene_measurements (probe_id, ...);