Забудьте на минуту об объектах и по-настоящему подумайте, что такое ваши данные и как они соотносятся друг с другом (в конце концов, мы используем реляционную базу данных).
У вас здесь просто отношения.
У вас есть юристы, и у вас есть специальности. Отношения состоят в том, что юристы имеют специальности, а специальности принадлежат юристам (отношение n-to-n), и то же самое касается отношений между специальностями и узлами (n-to-n).
Во-первых, давайте сделаем более простую структуру отношения 1 к n:
CREATE TABLE lawyers_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
gender gen
);
CREATE TABLE specialties_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
lawyer_ID INTEGER
);
CREATE TABLE subspecialties_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
specialty_ID INTEGER
);
Это работает, но приводит к дублированию, потому что каждая специальность может принадлежать только одному юристу, поэтому, если два юриста специализируются на «Деловом праве», вам придется определять «Деловое право» дважды. Хуже того, для каждой специальности вам также придется продублировать узлы.
Решением является объединенная таблица (также называемая таблицей карты / сопоставления):
CREATE TABLE lawyers_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
gender gen
);
CREATE TABLE lawyer_specialties_tb (
name VARCHAR,
lawyer_ID INTEGER,
specialty_ID INTEGER
);
CREATE TABLE specialties_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR
);
CREATE TABLE specialty_subspecialties_tb (
name VARCHAR,
specialty_ID INTEGER,
subspecialty_ID INTEGER
);
CREATE TABLE subspecialties_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR
);
Таким образом, каждая специальность может принадлежать более чем одному юристу (истинное отношение n-to-n), а каждая узкая специальность может принадлежать более чем одной специальности.
Вы можете использовать объединения для получения всего набора данных:
SELECT lawyers_tb.name as name,
lawyers_tb.gender as gender,
specialties_tb.name as specialty,
subspecialties_tb.name as subspecialty
FROM lawyers_tb LEFT JOIN lawyer_specialties_tb
ON lawyers_tb.ID=lawyer_specialties_tb.lawyer_ID
LEFT JOIN specialties_tb
ON specialties_tb.ID=lawyer_specialties_tb.specialty_ID
LEFT JOIN specialty_subspecialties_tb
ON specialties_tb.ID=specialty_subspecialties_tb.specialty_ID
Да, запрос немного сложнее, но структура позволяет вам поддерживать каждый набор данных индивидуально и определяет правильные отношения между ними.
Вы также можете определить ключи в объединяемых таблицах как внешние ключи, чтобы обеспечить правильность набора данных.
person
slebetman
schedule
08.06.2016