同时强制存在多对多和一对一的信息(PostgreSQL)

时间:2014-03-09 04:09:44

标签: sql postgresql many-to-many relation

天文学家发现恒星的关系是m:n,因为天文学家可以发现许多恒星,并且许多天文学家也可以发现恒星。

无论如何,每个星星都会有一个发现日期。如果有很多天文学家正在研究它,它们应该同时进行,否则,只有第一个获得发现的信誉。

所以,在PostgreSQL中,我们有:

CREATE TABLE astronomer ( 
    astronomer_id serial PRIMARY KEY,
    astronomer_name text NOT NULL UNIQUE
);

CREATE TABLE star ( 
    star_id serial PRIMARY KEY,
    star_name text NOT NULL UNIQUE,
    discovery_date date
);

CREATE TABLE discovered ( 
    star_id integer NOT NULL REFERENCES star,
    astronomer_id integer NOT NULL REFERENCES astronomer,
    CONSTRAINT pk_discovered PRIMARY KEY (star_id, astronomer_id) 
);

现在的诀窍问题是:我想强制执行,只要有星的发现日期,发现的表中至少会有一个条目,反之亦然。

我可以在表格中创建一个唯一键(star_id,discovery_date),然后将该组合用作发现的表中的外键而不是star_id。这样可以解决问题的一半,但仍然可以让没有天文学家的本发明日期。

除了使用触发器检查,或者只允许通过存储过程输入数据时,我看不到任何简单的解决方案,同时将discovery_date和条目插入到已发现的表中。

有什么想法吗? 谢谢!

1 个答案:

答案 0 :(得分:1)

我只需将discovery_date列移至discovered

即可
CREATE TABLE astronomer ( 
    astronomer_id serial PRIMARY KEY,
    astronomer_name text NOT NULL UNIQUE
);

CREATE TABLE star ( 
    star_id serial PRIMARY KEY,
    star_name text NOT NULL UNIQUE
);

CREATE TABLE discovered ( 
    star_id integer NOT NULL REFERENCES star,
    astronomer_id integer NOT NULL REFERENCES astronomer,
    discovery_date date not null,
    CONSTRAINT pk_discovered PRIMARY KEY (star_id, astronomer_id) 
);

现在您遇到同一个星星的多个日期问题,但正如您在问题中所说的那样,只有第一个星级会得到信用。