2011-12-23 15 views
7

Quiero almacenar los detalles de los cursos universitarios en una base de datos (MySql) pero no estoy seguro de cómo mantener la relación entre módulos y selecciones .La estructura de diseño/normalización de la base de datos debe contener AND, OR, elementos opcionales y sus relaciones

Básicamente, un curso puede tener una sección obligatoria, un grupo de módulos opcionales, una sección de opciones y dentro de cada uno puede haber selecciones que contengan AND o OR entre los módulos.


ejemplo simple: curso de crédito
Un 60 tiene un par de módulos obligatorios que componen 40 créditos. Eso deja 20 créditos para ser seleccionados del grupo de módulos opcionales. (Los módulos mismos pueden contener diferentes cantidades de créditos). Eficazmente; ('Mandatory module 1' AND 'Mandatory module 2'... AND'Mandatory module N') AND (40 credits from 'optional modules'),

AND & OR:
Cuando digo módulos anteriormente, que podría ser un solo módulo o podría ser "Módulo de x o el módulo de Y" es decir, en la sección obligatoria. (Esos módulos obviamente tendrían que tener el mismo peso de crédito). O en la sección opcional puede haber módulos individuales o incluso una de las opciones podría ser algo como "module x AND module y".

Opciones:
Los estudiantes pueden tener que tomar los módulos obligatorios, además de una de las opciones n que puede o no contener AND, OR, y obligatorios & secciones opcionales; Es decir, una 'Opción' tiene todos los atributos de la selección global de los módulos del curso. La sección de Opciones se AND ANDARÍA con otras secciones como obligatoria u opcional; es decir, módulos obligatorios "más una de las siguientes opciones". Efectivamente, la sección de opciones es solo 'Option 1' OR 'Option 2'... OR 'Option N'.


El problema es cómo puedo almacenar toda la AND y OR relaciones cuando el operando puede ser otro y/u operación o de un solo módulo, y realizar un seguimiento de la cantidad de créditos permitidos para cada selección; p.ej. "20 créditos de los siguientes:" (grupo de módulos opcionales).

+0

¿Cada módulo constituye un crédito? – Jrod

+0

Sí. El más bajo es un módulo de 5 créditos. Lo más que he visto es un módulo de 15 créditos, pero podría haber uno con mayor ponderación –

+0

¿Dónde está su código real para este problema? Porque todo lo que estoy viendo aquí es OO thumb twlingdling. – jcolebrand

Respuesta

1

El diseño es bastante sencillo, solo necesita una tabla recursiva de "grupo" con restricciones.

Course 
- ID 
- Title 
- Credits 

Course_Group 
- CourseID 
- GroupID 

Group 
- ID 
- GroupID 
- Description 
- AtLeastNSelections 
- AtLeastNCredits 

Group_Module 
- GroupID 
- ModuleID 

Module 
- ID 
- Title 
- Credits 

Un ejemplo de estructura sería

Course: 1, "Math Major", 60 
Group: 1, NULL, "Core Modules", 2, 40 
Course_Group: 1, 1 
    Group: 2, 1, "Required (5) Core Modules", 5, 25 
    Course_Group: 1, 1 
    Group_Module: (1, 1), (1, 2), (1, 3), (1, 4), (1, 5) 
     Module: 1, "Calculus I", 5 
     Module: 2, "Calculus II", 5 
     Module: 3, "Calculus III", 5 
     Module: 4, "Stats I", 5 
     Module: 5, "Stats II", 5 
    Group: 3, 1, "Required (3) Of (N) Modules", 3, 15 
    Course_Group: 1, 3 
    Group_Module: (3, 6), (3, 7), (3, 8), (3, 9), (3, 10) 
     Module: 6, "Number Theory", 5 
     Module: 7, "Bridge Adv. Math", 5 
     Module: 8, "Calculus IV", 5 
     Module: 9, "Stats III", 5 
     Module: 10, "Finite Math", 5 
Group: 4, NULL, "Secondary Modules", 1, 20 
Course_Group: 1, 4 
    Group: 5, 4, "Comp. Sci.", 2, 0 
    Course_Group: 1, 5 
    Group_Module: (5, 11), (5, 12), (5, 13), (5, 14), (5, 15), (5, 16) 
     Module: 11, "Math in Hardware", 4 
     Module: 12, "Math in Software", 4 
     Module: 13, "Programming 101", 4 
     Module: 14, "Algorithms 101", 4 
     Module: 15, "Programming I", 5 
     Module: 16, "Programming II", 5 
    Group: 6, 4, "Physics", 0, 8 
    Course_Group: 1, 6 
    Group_Module: (6, 17), (6, 18), (6, 19), (6, 20) 
     Module: 17, "Physics Mechanics", 4 
     Module: 18, "Physics Thermodynamics", 4 
     Module: 19, "Physics Magnetism", 5 
     Module: 20, "Physics Theoretical", 5 
    Group: 7, 4, "Gen. Ed.", 0, 0 
    Course_Group: 1, 7 
    Group_Module: (7, 21), (7, 22), (7, 23), (7, 24) 
     Module: 21, "Business Writing", 3 
     Module: 22, "Ethics", 3 
     Module: 23, "Aesthetics", 3 
     Module: 24, "Graphic Design", 3 

Un rápido paseo por el curso ... "comandante de matemáticas" tiene dos grupos debajo de ella "módulos básicos" y "módulos secundarios". "Módulos principales" requiere AL MENOS 2 niños Y AL MENOS 40 créditos. "Módulos secundarios" requiere POR LO MENOS 1 niño Y POR LO MENOS 20 créditos.

Puede ver que las restricciones de los grupos en "Módulos principales" son más restrictivas que las restricciones de los grupos en "Módulos secundarios".

Para generar la estructura de ejemplo anterior sería algo así como.

SELECT c.Title, g.Description, m.Title FROM Course c 
INNER JOIN Course_Group cg ON c.ID = cg.CourseID 
INNER JOIN Group g ON cg.GroupID = g.ID 
INNER JOIN Group_Module gm ON g.ID = gm.GroupID 
INNER JOIN Module m ON gm.ModuleID = m.ID 
WHERE c.ID = 1 
ORDER BY g.GroupID, g.ID, m.Title 

Así que si usted tiene un curso y los módulos se pueden obtener todos los grupos para el curso de la mesa y obtener Course_Group qué grupo pertenecen los módulos a partir de la tabla Group_Module. Una vez que tenga los módulos en su (s) grupo (s), puede verificar las restricciones del grupo AtLeastNSelections AND AtLeastNCredits subiendo por la cadena de parentescencia Group.GroupID hasta que llegue a Group.GroupID = NULL.

+0

Entonces Group.GroupID hace referencia a Group.ID, ¿sí? –

+1

@ Adam Lynch - Sí, normalmente trato de mantener FK/referencias como Tabla + Columna para los nombres. –

1

Aquí puede crear una estructura de tabla recursiva, donde las Opciones hacen referencia a sus opciones principales.

  • Las opciones "principales" pueden identificarse mediante la consulta de esta tabla para todas las opciones con padres "nulos".

  • Las relaciones "y-o" pueden implementarse mediante una tabla de "conjunto de opciones" separada, donde la clave principal es una "opción". La tabla de opciones de conjunto con auto-referencias nulas es el punto "raíz" para definir las opciones de un curso. A partir de ese punto, seleccionará registros de conjunto de opciones con parent = root. Este será el primer "nivel" de opciones. Algunos serán obligatorios, otros no. Para expresar eso, deberá tener un atributo booleano en la tabla de opciones como indicador. Por lo tanto, cada conjunto de opciones se define en términos de conjuntos de opciones más pequeños. Por supuesto, en última instancia, una vez que llegue al final, el conjunto de opciones definirá una clase real en algún momento.

Yo sugeriría que este mucho más efectivamente puede ser modelado en JSON o XML, ya que esas estructuras de datos jerarquías de apoyo de una manera mucho más expresiva.

1

es probable que pueda hacer algo como esto:

TABLE course_definition (
    ID int, 
    num_mandatory_sections int, 
    mandatory_hours int, 
    num_optional_modules int, 
    optional_hours int, 
); 

TABLE modules (
    ID int, 
    Description varchar(max), 
    hours int, 
    .... 
); 

TABLE course (
    Course_ID int FOREIGN KEY (course_definition.id), 
    module_id int FOREIGN KEY (modules.id) 
); 

TABLE course_module_relationship (
    Course_ID int FOREIGN KEY (course_definition.id), 
    module_ID int foreign key (modules.id), 
    Requirement_flag ENUM ("MANDATORY", "OPTIONAL") 
); 

TABLE Student_to_course (
    Student_ID int, 
    Course_ID int foreign key (course_definition.id) 
); 

TABLE Student_to_module (
    Student_ID int, 
    Module_ID int FOREIGN KEY (module.id) 
); 

Si usted realmente necesita para ser capaz de crear módulos de grupo también conocido como módulo único creado a partir de los múltiples otros módulos a continuación, la tabla module tendrá que tener un campo de marca:

group_module boolean 

y la siguiente tabla se debe añadir:

TABLE module_groupings (
    group_module_ID int foreign key (module.id) 
    dependant_module_id int foreign key (module.id) 
); 

Esto es más de pseudo código, pero se entiende la idea. La tabla course y course_module_relationship no tendrá claves y almacenará sus relaciones, ya que pueden ser muchas para muchos ya que entiendo el problema. Así que, básicamente, el código que leerá el proceso de las selecciones tendrá que verificar si cumple o no los criterios para el course_definition.

Si la sección Obligatoria de Curso es una relación 1 a 1, puede separar su sección obligatoria en una tabla separada, pero deberá analizar sus datos más a fondo.

+0

¿Pero esto puede ser recursivo? es decir, las opciones son como el modelo general y pueden tener secciones obligatorias, etc. dentro de ellas –

+0

¿Módulos dependiendo de los módulos? Mi comprensión de tu problema es que básicamente tratas de implementar un currículum universitario en la base de datos, en cuyo caso el curso o los módulos son los átomos que intentas construir. Pero si necesita una tabla de requisitos previos que sea fácil de hacer. – Karlson

+0

¿Qué? Ejemplo: los estudiantes pueden tener que tomar 4 módulos obligatorios más 1 de 3 opciones (cada opción tiene 2 módulos obligatorios y un grupo de módulos de los cuales se deben elegir 10 créditos) más 20 créditos de un grupo de módulos opcionales –

3

Un muy simple, primer enfoque sería utilizar sólo 4 mesas:

TABLE Course 
(CourseId 
, Title 
, TotalCredits 
, ... other stuff 
, PRIMARY KEY (CourseId) 
) ; 

TABLE Module 
(ModuleId 
, Description 
, Hours 
, Credits 
, ... other stuff 
, PRIMARY KEY (ModuleId) 
) ; 

y las combinaciones permitidas a través de estos 2:

TABLE Course_Module 
(CourseID     --- for this course 
, ModuleID     --- this module is allowed (optional or mandatory) 
, PRIMARY KEY (CourseID, ModuleId) 
, FOREIGN KEY (CourseId) 
    REFERENCES Course (CourseId) 
, FOREIGN KEY (ModuleId) 
    REFERENCES Module (ModuleId) 
) ; 

TABLE Course_MandatoryModule 
(CourseID     --- for this course 
, ModuleID     --- this module is mandatory 
, PRIMARY KEY (CourseID, ModuleId) 
, FOREIGN KEY (CourseID, ModuleId) 
    REFERENCES Course_Module (CourseID, ModuleId) 
) ; 

Ahora, si sus combinaciones permitidas de módulos y los cursos son más complicados, como lo sugiere su descripción, en lugar de las tablas Course_Module y Course_MandatoryModule, podría definir un modelo jerárquico complejo:

Cursos:

TABLE Course      --- same as previous model 
(CourseId 
, Title 
, TotalCredits 
, ... other stuff 
, PRIMARY KEY (CourseId) 
) ; 

Módulos y grupos de (módulos):

TABLE ModuleEntity     --- the supertype for both 
(ModuleEntityId     --- modules and group of modules 
, PRIMARY KEY (ModuleEntityId) 
) ; 

TABLE Module      --- subtype 
(ModuleId 
, Description 
, Hours 
, Credits 
, ... other stuff 
, PRIMARY KEY (ModuleId) 
, FOREIGN KEY (ModuleId) 
    REFERENCES ModuleEntity (ModuleEntityId) 
) ; 

TABLE ModuleGroup     --- group of modules 
(ModuleGroupId     --- subtype of the supertype (entity) 
, GroupDescription   
, PRIMARY KEY (ModuleGroupId) 
, FOREIGN KEY (ModuleGroupId) 
    REFERENCES ModuleEntity (ModuleEntityId) 
) ; 

y de relación (módulo pertenece a grupo):

TABLE Module_in_Group 
(ModuleEntityId    --- this module or group 
, ModuleGroupId    --- is in this group 
, PRIMARY KEY (ModuleEntityId, ModuleGroupID) 
, FOREIGN KEY (ModuleEntityId) 
    REFERENCES ModuleEntity (ModuleEntityId) 
, FOREIGN KEY (ModuleGroupId) 
    REFERENCES ModuleGroup (ModuleGroupId) 
) ; 

y curso (finalmente) puede tiene grupo de módulos:

TABLE Course_ModuleGroup 
(CourseId     --- for this course 
, ModuleGroupId   --- this module group is allowed 
, PRIMARY KEY (CourseID, ModuleGroupId) 
, FOREIGN KEY (CourseId) 
    REFERENCES Course (CourseId) 
, FOREIGN KEY (ModuleGroupId) 
    REFERENCES ModuleGroup (ModuleGroupId) 
) ; 
+0

Ok, pero ¿cómo puedo almacenar un grupo dentro de un grupo? Por lo que puedo ver para cada nivel, ¿tiene que haber algunas tablas más en su solución? –

+0

No, la tabla 'Module_in_Group' se ocupa de eso. Incluso puede tener un grupo dentro de sí mismo con este modelo. O un ciclo del 'grupo A en B, grupo B en C, grupo C en A' que obviamente no quieres! –

+0

Gracias por responder. Ahora, antes de aceptar esto, ¿para qué sirve 'GroupDescription' en' ModuleGroup'? ¿Es solo un lugar para una descripción/nombre textual?si es así, ¿cómo puedo manejar diferentes tipos de agrupaciones en tu respuesta? P.ej. Un tipo de grupo es que tengo que seleccionar una cantidad de créditos del grupo, otra que los selecciono a todos (Y) y otro que selecciono uno (O y Opciones). ¡Una respuesta a esto sería muy apreciada! –

0

Un sistema de calidad de producción que utiliza y/o (como su sistema) que puede revisar de forma gratuita es entlib 5.0 Bloque de seguridad. http://entlib.codeplex.com/

Cada regla es recuperada por nombre para obtener el expresión completa. los patrones & equipo de práctica crearon su propio corto DSL para la expresión para evitar complicar la estructura xml estructura/db.

esto está dentro de los ejercicios prácticos de laboratorio ex02 app.config. Para almacenar reglas dentro de la base de datos, deberá implementar un AuthorizationRuleProvider personalizado.

R: = nombre de rol; T: = nombre de usuario

<securityConfiguration defaultAuthorizationInstance="RuleProvider" 
defaultSecurityCacheInstance=""> 
<authorizationProviders> 
    <add type="Microsoft.Practices.EnterpriseLibrary.Security.AuthorizationRuleProvider, Microsoft.Practices.EnterpriseLibrary.Security" 
    name="RuleProvider"> 
    <rules> 
     <add expression="R:Employee OR R:Developer OR R:Manager" name="Raise Bug" /> 
     <add expression="R:Manager" name="Assign Bug" /> 
     <add expression="R:Developer OR R:Manager" name="Resolve Bug" /> 
    </rules> 
    </add> 
</authorizationProviders> 

uso dev

public static AssignBug Create() 
    { 
     // TODO: Check Authorization 
     if (!SecurityHelper.Authorized(AuthRule.Assign)) 
     { 
      throw new SecurityException(); 
     } 

     return new AssignBug(); 
    } 

Aunque no es una respuesta inmediata Creo que este es un buen ejemplo de cómo poner en práctica los sistemas basados ​​en reglas de expresión.

Cuestiones relacionadas