2009-01-08 13 views
7

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; 

Respuesta

0

¿Los profesores son la única "persona" que tiene una tasa de pago? Puede limitar su diseño al hacerlo de esta manera. Lo que puede querer hacer es tener una tabla de atributos que almacene atributos adicionales para una 'persona'. Esto permitirá modificaciones futuras.

0

Me gusta el enfoque Hat. En el pasado, implementé una combinación de sombreros y grupos. Básicamente, hay una lista de todas las acciones posibles (permisos) que un usuario puede hacer. Luego tengo una tabla de grupos. Cada grupo puede tener 1 o muchas acciones (permisos). Luego asigno usuarios a grupos.

Esto me proporciona mucha flexibilidad. Puedo obtener grano muy fino en mi permiso. También puedo cambiar los permisos de muchas personas rápidamente editando el grupo. De hecho, tengo la configuración de la página de permisos para usar los mismos permisos.Esto le permite al usuario final (no a mí) configurar los permisos para otros usuarios.

+0

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

0

sí, los profesores son las únicas personas que tienen una tasa de pago como tal. Ese campo debería llamarse con más precisión "clasePayRate": es un caso especial para los empleados docentes. Los empleados no docentes envían sus horas totales como una línea separada en nuestro sistema de nómina.

0

Podría cambiar maestros a empleados y agregar tipo de empleado.

Sin embargo, de ninguna manera forma o forma voy a almacenar correo electrónico, dirección, teléfono en la mesa de persona. Estas deben ser tablas separadas, ya que las personas tienen múltiples direcciones de correo electrónico (trabajo y hogar), múltiples números de teléfono (trabajo, hogar, celular, fax) y múltiples direcciones (trabajo, hogar1, hogar 2, escuela, etc.). Pondría cada una en su propia tabla y le asignaré un tipo para que pueda identificar cuál es el tipo de dirección, teléfono, etc.

También para dirección, correo electrónico, teléfono, puede querer una bandera para identificar cuál es el el registro principal a usar para contactar primero. Calculamos nuestra correspondencia y es un booleano que se mantiene actualizado con un desencadenador ya que cada persona que tiene un registro debe tener una y solo una correspondencia, por lo que si cambia, la anterior debe reiniciarse automáticamente así como también el nuevo entra y si es el primer registro se configura automáticamente y si se borra el registro de correspondencia, se asignará al otro si hay registros restantes.

0

Por seguridad, prefiero usar las Listas de control de acceso (ACL). Con ACL tiene Principals (usuarios o grupos de usuarios), Recursos (como un archivo, registro o grupo de registros) y Acciones (como leer, actualizar, eliminar).

Por defecto nadie tiene ningún privilegio. Para otorgar un permiso, agregue una entrada como Bob tiene acceso de lectura a archivo Abc.

Debería poder encontrar un código que lo ayude a implementar algo como esto. En Java, el JAAS admite este método.

0

estoy usando un paquete de ACL para permisos específicos en el sitio - el corazón de mi pregunta es más acerca de cómo almacenar los metadatos para las personas que tienen diferentes funciones y construir unas pocas garantías en el sistema para la integridad de los datos (de modo que una persona debe tener un registro de maestro para establecerse como el maestro de una clase; la restricción de clave externa hace referencia a la tabla de maestro, no a la tabla de persona).

1

Los modelos de grupos y sombreros que describes son convertibles, uno para el otro. No hay una preocupación real por la pérdida de datos. Específicamente, la tabla "grupos maestros" puede producirse mediante combinaciones externas de la tabla "persona sombrero" con las diversas tablas "detalles de sombrero".

Si está utilizando un modelo de "sombrero", debe asegurarse de que una "tabla de sombrero" concreta encapsula con precisión las características únicas de ese sombrero. Hay mucho menos perdón allí que con el modelo de grupos.

Probablemente desee configurar algunas vistas para tareas comunes si va de esta forma; por ejemplo, si alguien está escribiendo en un campo para "nombre del profesor" y desea mostrar algunas autocompletas, tener una vista que es básicamente

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

le ayudará enormemente.

En una nota tangencial, una cosa que he encontrado útil es llamar a las claves externas con el mismo nombre que la clave primaria en su tabla original.De esa manera usted puede simplemente

INNER JOIN original_table USING (primary_key) 

en su de en vez de monerías con WHERE o EN equivalencias.

9

Pasé por algo similar el año pasado. Allí la pregunta era: ¿modelamos nuestras entidades de manera explícita o genérica? En su ejemplo, eso significaría tener entidades/tablas como profesor, estudiante, etc. con relaciones directas entre ellos o no.

Al final optamos por un modelo genérico de "Fiesta". El modelo Partido es como sigue:

  • A Party representa a una persona u organización;
  • La mayoría de los tipos de partes tenían una tabla dependiente para almacenar información adicional según el tipo de parte, por ejemplo, persona, organización, empresa;
  • Cosas como Estudiante o Maestro son Roles de fiesta. Una Parte puede tener cualquier número de Roles de Fiesta. Una Persona puede ser tanto un Maestro como un Estudiante, por ejemplo;
  • Cosas como clases se manejan como Relaciones de roles de fiesta. Por ejemplo, una relación entre un rol de Profesor y Estudiante indica una relación de clase;
  • Las relaciones de roles de las partes pueden tener subtipos para obtener información adicional. Una relación profesor-alumno en su modelo es una inscripción y podría tener los atributos adicionales de los que está hablando;
  • Las partes no tienen relaciones directas entre ellas. Solo los roles de partido se relacionan entre sí; y
  • Para agrupaciones de información comunes, creamos vistas si ayuda porque el SQL puede ser un poco intrincado ya que las relaciones son más indirectas (p. ej., hay tres tablas entre las entidades Party para un Profesor y Estudiante).

Es un modelo extremadamente potente, que es bastante común en sistemas de tipo CRM. Este modelo prácticamente proviene de "The Data Model Resource Book: Volume 1", que es un excelente recurso para tales cosas.

+0

¡Hiciste mi pregunta mejor que yo, gracias! Esta es una idea muy intrigante, gracias por el resumen y la recomendación del libro. ¡Si pudiera votar, lo haría! – notneilcasey

0

He utilizado antes el modelo de fiesta. Realmente resuelvo la mayoría de las deficiencias.

Cuestiones relacionadas