mysql - relacionar - Diseñar relaciones alrededor de una estructura de herencia
herencia mysql ejemplo (1)
Aquí hay una pregunta similar al usar un supertipo de Medios y agregar subtipos de CD, VCR, DVD, etc.
Esto es escalable porque al crear, por ejemplo, un subtipo BluRay, se crea la tabla para contener los datos específicos de BluRay y se agrega una entrada a la tabla MediaTypes. No se necesitan cambios para los datos o códigos existentes, excepto, por supuesto, para agregar el código que funcionará con los datos de BluRay.
En su caso, los Usuarios serían la tabla de supertipo con Profesores y Estudiantes, las tablas de subtipo.
create table Users(
ID int not null auto_generating,
Type char( 1 ) check( Type in( ''T'', ''S'' )),
-- other data common to all users,
constraint PK_Users primary key( ID ),
constraint UQ_UserType unique( ID, Type ),
constraint FK_UserTypes foreign key( Type )
references UserTypes( ID )
);
create table Teachers(
TeacherID int not null,
TeacherType char( 1 ) check( TeacherType = ''T'' )),
-- other data common to all teachers...,
constraint PK_Teachers primary key( TeacherID ),
constraint FK_TeacherUser foreign key( TeacherID, TeacherType )
references Users( ID, Types )
);
La composición de la tabla Estudiantes sería similar a la tabla Maestros.
Dado que tanto los profesores como los alumnos pueden emplear a otros profesores y estudiantes, la tabla que contiene esta relación se referirá a la tabla Usuarios.
create table Employment(
EmployerID int not null,
EmployeeID int not null,
-- other data concerning the employment...,
constraint CK_EmploymentDupes check( EmployerID <> EmployeeID ),
constraint PK_Employment primary key( EmployerID, EmployeeID ),
constraint FK_EmploymentEmployer foreign key( EmployerID )
references Users( ID ),
constraint FK_EmploymentEmployee foreign key( EmployeeID )
references Users( ID )
);
Según tengo entendido, las notificaciones se agrupan por empleador:
create table Notifications(
EmployerID int not null
NotificationDate date,
NotificationData varchar( 500 ),
-- other notification data...,
constraint FK_NotificationsEmployer foreign key( EmployerID )
references Users( ID )
);
Las consultas deberían ser lo suficientemente simples. Por ejemplo, si un usuario desea ver todas las notificaciones de su (s) empleador (es):
select e.EmployerID, n.NotificationDate, n.NotificationData
from Employment e
join Notifications n
on n.EmployerID = e.EmployerID
where e.EmployeeID = :UserID;
Este es un boceto inicial, por supuesto. Los refinamientos son posibles. Pero a tus puntos numerados:
- La tabla de Empleo relaciona a los empleadores con los empleados. El único control para hacer que los usuarios empleadores no puedan hacerlo ellos mismos, pero de lo contrario cualquier usuario puede ser un empleado y un empleador.
- La tabla Usuarios obliga a cada usuario a ser un maestro (''T'') o un alumno (''S''). Solo los usuarios definidos como ''T'' pueden colocarse en la tabla de profesores y solo los usuarios definidos como ''S'' pueden colocarse en la tabla de Estudiantes.
- La tabla de Empleo se une solo a la tabla Usuarios, no a las tablas Docentes y Estudiantes. Pero esto se debe a que tanto los profesores como los estudiantes pueden ser empleadores y empleados, no por ningún motivo de rendimiento. En general, no se preocupe por el rendimiento durante el diseño inicial. Su principal preocupación en este punto es la integridad de los datos. Las bases de datos relacionales son muy buenas con combinaciones. Si surge un problema de rendimiento, arréglenlo. No reestructure sus datos para resolver problemas que aún no existen y que tal vez nunca existan.
- Bueno, pruébalo y mira cómo funciona.
Tengo una pregunta conceptual sobre la mejor manera de organizar mi base de datos.
Actualmente tengo cuatro users
principales de tablas, teachers
, students
y notifications
. Sin embargo, tanto las tablas de teachers
como de students
heredan de la tabla de users
, por lo que contienen la clave externa user_id
.
La tabla de notifications
, como ya habrás adivinado, se refiere a las notificaciones. Estos deben aparecer para todos los usuarios que pertenecen a un grupo de empleados, es decir, bajo el empleo de otro.
Tanto los estudiantes como los profesores pueden emplear a otros usuarios.
Entonces, el quid es que necesito una forma elocuente de modelar esto. El flujo de trabajo básico del código sería el siguiente:
getCurrentUser->getAllEmployer(s)->getNotifications
Este es el Laravel Eloquent estoy acostumbrado a $user->employers()->notifications;
Lamentablemente, no es tan simple como eso, ya que en este caso un empleador puede referirse a dos tablas.
Entonces mis elecciones son las siguientes.
- Cree una Relación Elocuente para la relación entre el
student
y elteacher
como empleadores. El déficit es que necesito escribir si las pruebas comprueban si el usuario actual pertenece a cualquiera y este código se repite con frecuencia. - Agregue un
teacher_id
ystudent_id
a la tabla deusers
. Sin embargo, uno obviamente sería redundante en cada registro. La posibilidad de necesitar agregar otras columnas también es muy probable debido a la aparición de nuevas entidades de empleadores. - Cree una tabla
employer_employee
que contenga dos columnas queuser_id
referencia a unuser_id
. Una consulta SQL DEJARÍA UNIR tantostudent
tablas destudent
como las deteacher
con la tablaemployer_employee
y luego un JOIN connotifications
devolvería todas las relevantes. Sin embargo, tantas combinaciones reducirían la velocidad de la consulta en comparación con las otras opciones. - Algo que no he considerado.
Realmente estoy buscando la solución más eficiente y escalable .
Cualquier ayuda es apreciada. Si pudiera aclarar por qué su respuesta es la solución escalable más eficiente, sería excelente.