Задавайте вопросы, мы ответим
Вы не зашли.
Приветствую, коллеги!
"ТЗ" моей задачи звучит следующим образом.
В системе есть региональные разделы, где размещаются наблюдения определенных видов трав.
Наблюдение содержит в себе один вид.
Каждый раздел "описывает" лишь несколько видов из общего множества.
При этом один и тот же вид может присутствовать в нескольких разделах, то есть ромашка может быть и в алтайском и в красноярских разделах.
Хотелось бы, чтобы наблюдение ссылалось напрямую на раздел и на вид, чтобы не делать лишних джоинов в запросах. В то же время, чтобы структура была нормализованной.
Придумал следующий вариант:
Виды (species) и разделы (section) - это явно многие ко многим =>
Таблица rel_section_species содержит в себе два поля - (species_id,section_id), их связка образует собой первичный ключ.
Таблица наблюдений - observation содержит в себе вторичный ключ, который ссылается на первичный ключ rel_section_species.
DROP TABLE IF EXISTS `observation`;
DROP TABLE IF EXISTS `rel_section_species`;
DROP TABLE IF EXISTS `species`;
DROP TABLE IF EXISTS `section`;
CREATE TABLE `section` (
`id` bigint(20) NOT NULL primary key,
`name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `section` values(1,'section1'),(2,'section2');
CREATE TABLE `species` (
`id` bigint(20) NOT NULL primary key,
`name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `species` values(1,'species1'),(2,'species2');
CREATE TABLE `rel_section_species` (
`section_id` bigint(20) NOT NULL,
`species_id` bigint(20) NOT NULL,
PRIMARY KEY (`section_id`,`species_id`),
KEY `section_id` (`section_id`),
KEY `species_id` (`species_id`),
CONSTRAINT `constraint__section_id` FOREIGN KEY (`section_id`) REFERENCES `section` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `constraint__species_id` FOREIGN KEY (`species_id`) REFERENCES `species` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into rel_section_species values(1,1),(2,1),(1,2);
CREATE TABLE `observation` (
`id` bigint(20) NOT NULL primary key auto_increment,
`section_id` bigint(20) NOT NULL,
`species_id` bigint(20) NOT NULL,
KEY `section_id` (`section_id`),
KEY `species_id` (`species_id`),
CONSTRAINT `observation__rel_ss__section_id__species_id` FOREIGN KEY (`section_id`,`species_id`) REFERENCES `rel_section_species` (`section_id`,`species_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into observation(section_id,species_id) values(1,1),(2,1),(1,2);
Первый вид может находиться и в первом и во втором разделе,
а второй вид - есть только в первом разделе.
Тем самым (судя по проведенному эксперименту) добился того, что нельзя создать
наблюдение во втором разделе второго вида, что и требовалось.
В то же время таблица наблюдений содержит в себе id раздела и id вида, что сильно упрощает запросы.
Вот. Покритикуйте пожалуйста, если какие-то блохи видны.
Или я чего-то упустил и можно как-то проще?
Неактивен
Данил, все нормально, вроде бы
Неактивен