Предпочитаемый метод проектирования базы данных для назначения пользовательских ролей? (Шляпы против групп) - PullRequest
7 голосов
/ 08 января 2009

У меня есть база данных 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;

Ответы [ 9 ]

9 голосов
/ 09 января 2009

Я прошел через подобное в прошлом году. Там был вопрос: мы моделируем наши сущности явно или обобщенно? В вашем примере это будет означать наличие сущностей / таблиц, таких как учитель, ученик и т. Д. С прямыми отношениями между ними.

В конце концов мы пошли на общую модель "партии". Модель партии выглядит следующим образом:

  • A Партия представляет лицо или организацию;
  • Большинство типов партий имели зависимую таблицу для хранения дополнительной информации в зависимости от типа партии, например, Персона, Организация, Компания;
  • Такие вещи, как ученик или учитель: Партийные роли . Партия может иметь любое количество партийных ролей. Например, человек может быть и учителем, и учеником;
  • Такие вещи, как классы обрабатываются как Партийно-ролевые отношения . Например, отношение между ролью учителя и ученика указывает на классовые отношения;
  • Партийные ролевые отношения могут иметь подтипы для дополнительной информации. Отношения между учителем и учеником в вашей модели - это регистрация, которая может иметь дополнительные атрибуты, о которых вы говорите;
  • Стороны не имеют прямых отношений друг с другом . Только партийные роли связаны друг с другом; и
  • Для общих групп информации мы создали представления, если это помогло, потому что SQL может быть немного запутанным, поскольку отношения являются более косвенными (например, между сущностями Стороны есть три таблицы для Учителя и Ученика).

Это чрезвычайно мощная модель, довольно распространенная в системах типа CRM. Эта модель в значительной степени взята из «Справочника по модели данных: том 1» , который является отличным ресурсом для таких вещей.

1 голос
/ 09 января 2009

Модели групп и шапок, которые вы описываете, являются конвертируемыми, одна в другую. Там нет никакого реального беспокойства о потере данных. В частности, таблица «основных групп» может быть создана с помощью внешних объединений таблицы «hat person» с различными таблицами «hat detail».

Если вы используете модель «шляпы», вам нужно убедиться, что данный «стол шляпы» точно отражает уникальные характеристики этой шляпы. Там гораздо меньше прощения, чем с моделью групп.

Возможно, вы захотите настроить несколько представлений для общих задач, если вы пойдете этим путем - например, если кто-то печатает в поле «имя учителя», и вы хотите вызвать несколько автозаполнений, имеющих представление, которое в основном

SELECT firstName, lastName 
FROM persons 
INNER JOIN teachers ON persons.id = teachers.person_id 

очень поможет.

На касательной ноте одна вещь, которая мне показалась полезной, это вызывать внешние ключи с тем же именем, что и первичный ключ в их исходной таблице. Таким образом, вы можете просто

INNER JOIN original_table USING (primary_key) 

в вашем ОТ вместо обезьяны с эквивалентностью WHERE или ON.

0 голосов
/ 18 июня 2009

Я использовал модель партии раньше. Я действительно решаю большинство недостатков.

0 голосов
/ 09 января 2009

Я использую пакет ACL для детализированных разрешений на сайте - суть моего вопроса больше в том, как хранить метаданные для людей, которые выполняют разные роли, и встроить в систему несколько мер защиты для целостности данных ( такой, что у человека должна быть запись учителя, чтобы быть учителем в классе - ограничение внешнего ключа ссылается на таблицу учителя, а не на таблицу личности).

0 голосов
/ 09 января 2009

В целях безопасности я предпочитаю использовать списки контроля доступа (ACL). С ACL у вас есть Принципалы (пользователи или группы пользователей), Ресурсы (например, файл, запись или группа записей) и Действия (например, чтение, обновление, удаление).

По умолчанию никто не имеет никаких привилегий. Чтобы предоставить разрешение, вы добавляете запись, такую ​​как Боб имеет доступ на чтение к файлу Abc.

Вы должны быть в состоянии найти код, который поможет вам реализовать нечто подобное. В Java JAAS поддерживает этот метод.

0 голосов
/ 08 января 2009

Я могу поменять учителей на сотрудников и добавить тип сотрудника.

Однако, ни при каких обстоятельствах я не буду хранить электронную почту, адрес, телефон в таблице личных данных. Все они должны быть отдельными таблицами, поскольку у людей есть несколько адресов электронной почты (рабочий и домашний), несколько телефонных номеров (рабочий, домашний, сотовый, факс) и несколько адресов (рабочий, домашний 1, домашний 2, школа и т. Д.). Я бы поместил каждую в свою таблицу и назначил ей тип, чтобы вы могли определить, какой тип адреса, телефон и т. Д.

Также для адреса, электронной почты, телефона вы можете захотеть установить флаг, который является основной записью, которую следует использовать для первого контакта. Мы называем нашу корреспонденцию, и это логическое значение, которое обновляется с помощью триггера, поскольку у каждого человека, имеющего запись, должна быть одна и только одна корреспонденция, поэтому, если она изменяется, старая должна автоматически сбрасываться, а также новый вводится, и если это первая запись, она устанавливается автоматически, и если запись корреспонденции удаляется, она будет назначена другой, если есть оставшиеся записи.

0 голосов
/ 08 января 2009

да, учителя - единственные люди, у которых есть ставка заработной платы как таковая. Это поле должно быть более точно названо "classPayRate" - это особый случай для преподавателей. Сотрудники, не являющиеся учителями, представляют общее количество часов в отдельной строке в нашей системе начисления заработной платы.

0 голосов
/ 08 января 2009

Мне нравится подход Hat. В прошлом я реализовал комбинацию шляп и групп. В основном, есть список всех возможных действий (разрешений), которые может выполнять пользователь. У меня тогда есть таблица групп. Каждая группа может иметь 1 или несколько действий (разрешений). Затем я назначаю пользователей в группы.

Это дает мне большую гибкость. Я могу получить очень мелкое зерно в моем разрешении. Я также могу быстро изменить права доступа многих людей, просто отредактировав группу. На самом деле, у меня есть настройки страницы разрешений, чтобы использовать те же разрешения. Это позволяет конечному пользователю (не мне) устанавливать разрешения для других пользователей.

0 голосов
/ 08 января 2009

Являются ли учителя единственным «человеком», у которого есть ставка заработной платы? Вы можете ограничить свой дизайн, делая это таким образом. То, что вы можете сделать, это иметь таблицу атрибутов, в которой хранятся дополнительные атрибуты для человека. Это позволит для будущих модификаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...