У меня есть вопрос по поводу дизайна базы данных. Я спрашиваю здесь, потому что я энтузиаст / любитель, а не "профессионал", поэтому я не хочу публиковать его в обмене стеками "Администраторы баз данных", специально предназначенном для профессионалов. Я надеюсь, что это правильное место.
Я хотел бы создать систему для отслеживания встреч между заключенными и сотрудниками исправительных учреждений. Пытаясь спроектировать реляционную базу данных, я придумал следующие пять таблиц:
CREATE TABLE `encounters` (
`id` INT NOT NULL,
`encounterdate` DATETIME NULL,
`officers_id` INT NOT NULL,
`prisoners_id` INT NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `officers` (
`id` INT NOT NULL,
`badgenumber` VARCHAR(10) NULL,
`lastnames_id` INT NOT NULL,
`firstnames_id` INT NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `prisoners` (
`id` INT NOT NULL,
`regnumber` VARCHAR(10) NULL,
`lastnames_id` INT NOT NULL,
`firstnames_id` INT NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `firstnames` (
`id` INT NOT NULL,
`name` VARCHAR(45) NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `lastnames` (
`id` INT NOT NULL,
`name` VARCHAR(45) NULL,
PRIMARY KEY (`id`)
);
со следующими отношениями:
Эта установка помешала бы мне хранить все имена и фамилии дважды (один раз для офицеров и один раз для заключенных), но я не уверен, как получить имя / фамилию конкретного офицера И имя / фамилию конкретного заключенного для данной встречи. В идеале я хотел бы использовать инструкцию SELECT, чтобы получить запись, которая выглядит как одна из строк ниже:
Я могу использовать внутренние объединения, чтобы получить имя и фамилию любого из офицеров:
SELECT
encounters.encounterdate,
officers.badgenumber,
prisoners.regnumber,
fnames.name,
lnames.name
FROM
encounters
INNER JOIN prisoners ON encounters.prisoners_id = prisoners.id
INNER JOIN officers ON encounters.officers_id = officers.id
INNER JOIN fnames on officers.firstnames_id = fnames.id
INNER JOIN lnames on officers.lastnames_id = lnames.id
WHERE
officers.badgenumber = "b503"
или заключенный:
SELECT
encounters.encounterdate,
officers.badgenumber,
prisoners.regnumber,
fnames.name,
lnames.name
FROM
encounters
INNER JOIN prisoners ON encounters.prisoners_id = prisoners.id
INNER JOIN officers ON encounters.officers_id = officers.id
INNER JOIN fnames on prisoners.firstnames_id = fnames.id
INNER JOIN lnames on prisoners.lastnames_id = lnames.id
WHERE
officers.badgenumber = "b503"
но я не могу понять, возможно ли получить ОБА для данного столкновения, используя только одну инструкцию SELECT.
Конечно, я мог бы сделать это с помощью хранимой процедуры / функции и пары SELECT, но мне интересно узнать, есть ли более простой способ сделать это с помощью одного SELECT. Или это просто плохой способ создать базу данных?
Спасибо за вашу помощь.