Justin S. wrote:
But my index on ‘people’ would be ‘source_id’ – not ‘name’ –
referring to the primary key (‘id’) of the two other tables. I’d use
the ‘gender’ column to determine which table (‘boys’ or ‘girls’) the
‘source_id’ should reference.
If I’ve understood correctly, you are trying to use tables along the
lines of (in PostgreSQL syntax, ‘serial’ is like auto_increment in
MySQL)
CREATE TABLE boys(
id SERIAL PRIMARY KEY,
name TEXT UNIQUE NOT NULL
);
CREATE TABLE girls(
id SERIAL PRIMARY KEY,
name TEXT UNIQUE NOT NULL
);
CREATE TABLE people(
id SERIAL PRIMARY KEY,
gender CHAR(1) NOT NULL,
source_id INTEGER NOT NULL,
CONSTRAINT ‘sane_gender’ CHECK (gender = ‘m’ or gender = ‘f’)
);
And some data:
SELECT * FROM boys;
id | name
----±-----
1 | Tom
2 | Bob
3 | Jessie
SELECT * FROM boys;
id | name
----±-----
1 | Sue
2 | Jane
3 | Jessie
SELECT * from people
id | gender | source_id
----±-------±----------
1 | ‘m’ | 1
2 | ‘f’ | 1
Ok. Expanding this, there is one guy named Tom, and one gal named Sue.
Works so far — well, except for repeating yourself with “Jessie” in
both the “boys” and “girls” tables. Now, a guy named Jane — yes, a
guy named Jane — comes along, so you add:
INSERT INTO PEOPLE(gender, source_id) VALUES(‘m’, ‘2’);
But wait! That doesn’t work; he’s now Bob. Instead, you have to first
add ‘Jane’ to the boys table. So why not use:
CREATE TABLE names (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
CREATE TABLE people (
id SERIAL PRIMARY KEY,
gender CHAR(1) NOT NULL,
name_id INTEGER NOT NULL REFERENCES names,
CONSTRAINT ‘sane_gender’ CHECK(gender = ‘m’ or gender = ‘f’)
);
Now, maybe you want to be able to find names for only one sex; if so:
CREATE TABLE names (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
is_boy_name BOOLEAN NOT NULL,
is_girl_name BOOLEAN NOT NULL
);
Now, you’ve got the ability to find which names are generally boys,
which are generally girls, and even which (like Jessie) can be either.
Not only that, you can handle exceptions — a boy with a girl’s name,
or vice versa.
And, you can query for other information. For example, to find all the
guys who don’t have a guy’s name:
SELECT p.id, n.name
FROM people p, names n
WHERE
p.name_id = n.id AND (p.gender = ‘m’ AND NOT n.is_boy_name)