Tengo una base de datos MySQL de tamaño mediano con una tabla primaria de "personas" que contiene información de contacto básica de cada ser humano conectado a la escuela de teatro y teatro para la cual soy responsable de mantener y desarrollar varios aplicaciones.Método de diseño de base de datos preferido para asignar roles de usuario? (Sombreros contra grupos)
Algunas personas son solo contactos, es decir, su registro de "personas" es toda la información que necesitamos almacenar sobre ellos. Sin embargo, muchos otros deben poder asumir diferentes roles para una variedad de sistemas. De estos, la mayoría comienza como estudiantes. Algunos comienzan como empleados. Las personas que son estudiantes pueden convertirse en pasantes o intérpretes; los empleados pueden convertirse en estudiantes; todos los profesores son empleados e intérpretes, etc.
En esencia, hay una variedad de diferentes "sombreros" que cualquier persona puede tener que usar para acceder e interactuar con las diferentes partes del sistema, así como también información sobre ellos disponible en las páginas públicas de nuestro sitio.
Mi elección para implementar este modelo es tener varias otras tablas que representen estos "sombreros", tablas que contienen metainformación para complementar la información básica de "persona", todas las cuales usan la identificación "personas" como su principal llave. Por ejemplo, una persona que es maestra tiene un registro en una tabla de maestros que contiene su breve información biográfica y la tasa de pago. Todos los profesores también son empleados (pero no todos los empleados son profesores), lo que significa que tienen un registro en la tabla de empleados que les permite enviar sus horas en nuestro sistema de nómina.
Mi pregunta es, ¿cuáles son los inconvenientes de implementar el modelo como tal? La única otra opción que puedo pensar es inflar la tabla de personas con campos que estarán vacíos e inútiles para la mayoría de las entradas y luego tener una tabla engorrosa de "grupos" a los que las personas pueden pertenecer, y luego tener casi todas las tablas por cada el sistema tiene una clave externa person_id
y luego depende de la lógica comercial para verificar que el id_individual al que se hace referencia pertenece al grupo apropiado; Pero eso es estúpido, ¿no?
Unas declaraciones ejemplo de mesa siguen a continuación, que esperemos que demostrar cómo estoy poniendo actualmente todo esto, y es de esperar mostrar por qué creo que es una manera más sensata para modelar la realidad de las distintas situaciones de los sistemas tienen que tratar con.
Cualquier y todas las sugerencias y comentarios son bienvenidos. Aprecio tu tiempo.
EDITAR Algunos encuestados han mencionado el uso de ACL para la seguridad - No he mencionado en mi pregunta original que de hecho estoy usando un paquete ACL separado para el control de acceso de grano fino para los usuarios reales de los diferentes sistemas. Mi pregunta es más acerca de las mejores prácticas para almacenar metadatos sobre las personas en el esquema de la base de datos.
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;
Gracias por la respuesta: estoy usando un paquete de ACL independiente para permisos detallados que determinan lo que un usuario puede o no hacer en el sitio, por lo que estoy 100% de acuerdo con usted sobre el enfoque combinado. – notneilcasey