Frage

The relation "astronomers discover stars" is m:n, as an astronomer can discover many stars, and a star can as well be discovered from many astronomers.

In any case however, there will be a single date of discovery for every star. If there are many astronomers working on it, they should do it simultaneously, otherwise, only the first one gets the credits of the discovery.

So, in PostgreSQL, we have:

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) 
);

Now the trick question: I want to enforce that whenever there is a discovery date for a star, there will be at least one entry in the discovered table, and vice versa.

I could create a unique key (star_id, discovery_date) in table star, and then use that combination as a foreign key in table discovered instead of the star_id. That would solve half of the problem, but still leave it possible to have a discovered_date without astronomers for it.

I can't see any simple solution other than using a trigger to check, or only allowing data enter via a stored procedure that will at the same time insert a discovery_date and entries into the table discovered.

Any ideas? Thank you!

War es hilfreich?

Lösung

I would just move the discovery_date column to the discovered table

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) 
);

Now you have the problem of multiple dates for the same star but as you say in the question only the first one(s) will get the credit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top