У меня есть база данных MySQL среднего размера с первичной таблицей «лица», которая содержит основную контактную информацию о каждом человеке, связанном с театром и театральной школой, за которую я отвечаю за поддержку и разработку ряда веб-приложений.
Некоторые люди являются просто контактами, то есть их записи в таблице "персон" - это вся информация, которую мы должны хранить о них. Тем не менее, многие другие должны иметь возможность брать на себя разные роли для различных систем. Из них большинство начинаются как студенты. Некоторые начинают как работники. Люди, которые являются студентами, могут стать интернами или исполнителями; сотрудники могут стать студентами; все учителя являются работниками и исполнителями и т. д.
По сути, это различные «шляпы», которые любой человек может надеть, чтобы получить доступ к различным частям системы и взаимодействовать с ними, а также разместить информацию о них на общедоступных страницах нашего сайта. сайт.
Мой выбор для реализации этой модели состоит в том, чтобы иметь несколько других таблиц, которые представляют эти "шляпы" - таблицы, которые содержат метаинформацию для дополнения базовой информации о "персоне", причем все они используют идентификатор "персоны" в качестве своего первичного ключа. , Например, человек, который является учителем, имеет запись в таблице учителей, содержащую его или ее краткую биографическую информацию и ставку оплаты. Все учителя также являются сотрудниками (но не все сотрудники являются преподавателями), то есть они имеют запись в таблице сотрудников, которая позволяет им отправлять свои часы в нашу систему расчета заработной платы.
Мой вопрос: каковы недостатки реализации модели как таковой? Единственный другой вариант, который я могу придумать, - это заполнить таблицу лиц полями, которые будут пустыми и бесполезными для большинства записей, а затем иметь громоздкую таблицу «групп», к которой могут принадлежать люди, и затем иметь почти каждую таблицу для каждого. система имеет внешний ключ человека person_id
и затем зависит от бизнес-логики, чтобы убедиться, что указанный person_id принадлежит к соответствующей группе; Но это глупо, не правда ли?
Ниже приведены несколько примеров объявлений таблиц, которые, надеюсь, должны продемонстрировать, как я в настоящее время собираю все это вместе, и, надеюсь, показать, почему я считаю, что это более разумный способ моделирования реальности различных ситуаций, с которыми приходится сталкиваться системам. с.
Любые предложения и комментарии приветствуются. Я ценю ваше время.
РЕДАКТИРОВАТЬ Несколько респондентов упомянули использование ACL для безопасности - я не упомянул в своем первоначальном вопросе, что на самом деле я использую отдельный пакет ACL для детального управления доступом для реальных пользователей различных системы. Мой вопрос больше о лучших методах хранения метаданных о людях в схеме базы данных.
CREATE TABLE persons (
`id` int(11) NOT NULL auto_increment,
`firstName` varchar(50) NOT NULL,
`middleName` varchar(50) NOT NULL default '',
`lastName` varchar(75) NOT NULL,
`email` varchar(100) NOT NULL default '',
`address` varchar(255) NOT NULL default '',
`address2` varchar(255) NOT NULL default '',
`city` varchar(75) NOT NULL default '',
`state` varchar(75) NOT NULL default '',
`zip` varchar(10) NOT NULL default '',
`country` varchar(75) NOT NULL default '',
`phone` varchar(30) NOT NULL default '',
`phone2` varchar(30) NOT NULL default '',
`notes` text NOT NULL default '',
`birthdate` date NOT NULL default '0000-00-00',
`created` datetime NOT NULL default '0000-00-00 00:00',
`updated` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `lastName` (`lastName`),
KEY `email` (`email`)
) ENGINE=InnoDB;
CREATE TABLE teachers (
`person_id` int(11) NOT NULL,
`bio` text NOT NULL default '',
`image` varchar(150) NOT NULL default '',
`payRate` float(5,2) NOT NULL,
`active` boolean NOT NULL default 0,
PRIMARY KEY (`person_id`),
FOREIGN KEY(`person_id`) REFERENCES `persons` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB;
CREATE TABLE classes (
`id` int(11) NOT NULL auto_increment,
`teacher_id` int(11) default NULL,
`classstatus_id` int(11) NOT NULL default 0,
`description` text NOT NULL default '',
`capacity` tinyint NOT NULL,
PRIMARY KEY(`id`),
FOREIGN KEY(`teacher_id`) REFERENCES `teachers` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY(`classstatus_id`) REFERENCES `classstatuses` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
KEY (`teacher_id`,`level_id`),
KEY (`teacher_id`,`classstatus_id`)
) ENGINE=InnoDB;
CREATE TABLE students (
`person_id` int(11) NOT NULL,
`image` varchar(150) NOT NULL default '',
`note` varchar(255) NOT NULL default '',
PRIMARY KEY (`person_id`),
FOREIGN KEY(`person_id`) REFERENCES `persons` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB;
CREATE TABLE enrollment (
`id` int(11) NOT NULL auto_increment,
`class_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
`enrollmenttype_id` int(11) NOT NULL,
`created` datetime NOT NULL default '0000-00-00 00:00',
`modified` timestamp NOT NULL,
PRIMARY KEY(`id`),
FOREIGN KEY(`class_id`) REFERENCES `classes` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY(`student_id`) REFERENCES `students` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY(`enrollmenttype_id`) REFERENCES `enrollmenttypes` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB;