2012-08-02 18 views
6

estoy haciendo una base de datos de los estudiantes en una school.Here es lo que tengo hasta ahora: enter image description here¿Cómo hacer que una clave compuesta sea única?

Si no te gusta leer salto a la "En pocas palabras" parte

El problema es que no estoy contento con este diseño. Deseo que la combinación de grade, subgrade y id_class sea única y que sirva como clave principal para la tabla de estudiantes. Puedo eliminar student_id y crear una clave compuesta de 3, pero tampoco quiero eso. Tal vez debería hacer otra tabla digamos combination_id donde grade, subgrade y id_class son claves externas y hay una columna adicional comb_id que sirve como ID para la tabla. Y todas las columnas serán Claves primarias. Pero el problema es que esas 3 columnas todavía se pueden repetir debido a esa columna adicional (comb_id). Por ejemplo, puedo tener el mismo grade, subgrade y class_id pero diferente comb_id que hará que la fila sea válida debido a la clave compuesta de las 4 columnas de la tabla (combination_id).

En pocas palabras quiero students_id seguir siendo la única clave primaria de la tabla pero para ser una clave externa a otra tabla, que es de alguna manera combinación única de grades, subgrade y class_id.

Si no fui lo suficientemente clara, pregunte en los comentarios debajo y gracias de antemano.

PS lo siento por el título indescriptive pero yo soy malo en nombrar

EDIT 1: Para ser más claro: grade puede ser del 1 al 12 subgrade puede ser una de j id_class puede ser del 1 al 30 y es su número en clase

Así que un estudiante puede ser de clase 7b y su número en la clase - 5

+0

No entiendo, ¿todos los estudiantes de una clase tienen diferentes calificaciones? – Jodrell

+0

¿Qué harás cuando los alumnos cambien de clase o esto nunca ocurra? – Jodrell

+0

¿Qué pasa con una columna 'student_id'? – Jodrell

Respuesta

17

No mezcle los conceptos de claves únicas y claves principales. Puede agregar un unique key que abarca las tres columnas grades, subgrade y class_id. De esta manera, no hay dos filas could have los mismos valores para estas tres columnas. A medida que escribe que no desea tener estos tres como una clave primaria compuesta, no estoy seguro de si una clave suplementaria única compuesta sería mejor. De lo contrario, deberá aclarar cuándo las claves compuestas son aceptables.

Para crear una clave única, puede utilizar el siguiente código SQL statement:

ALTER TABLE students ADD UNIQUE gsc (grades, subgrade, class_id); 

La palabra gsc no es sólo un nombre que inventé de las iniciales de las columnas de clave; utilice el nombre que desee, ya que apenas importa a menos que desee identificar la clave en alguna salida de EXPLAIN o similar.

+0

gracias Lo intentaré y probablemente confundiré a las personas con los nombres de 'grade',' subgrade' y 'id_class', pero en mi país el sistema educativo es diferente. – Bosak

+0

OK Lo intenté pero cuando hice las 3 columnas 'UNIQUE' obtuve un error para las entradas duplicadas. Tenía muchos 'grades' 3 pero tenían diferentes' subgrades', así que los trataba como claves separadas 'unique'. Además, ¿qué es complementario? – Bosak

+0

No convierta todas las columnas en únicas por sí mismas, sino que juntas: 'ALTER TABLE students ADD UNIQUE gsc (grades, subgrade, class_id)'. 'gsc' es solo un nombre, usa lo que quieras. Entonces los duplicados solo ocurren si los tres son iguales. Utilicé el término * suplementario * en oposición a * primario *: una clave definida con este comando no es primaria, pero sigue siendo única. – MvG

2

No tengo muy claro por qué quieres lo que has descrito, pero miraría el modelo de la siguiente manera ...

Usted tiene estudiantes
- Ellos son entidades distintas, no una combinación de otras entidades
- Ellos tienen sus propias propiedades; nombre, fecha de nacimiento, etc.

Usted tienen clases
- Estos son los grupos de estudiantes
- Cada año la misma académicos de tipo "clase" tiene diferentes estudiantes en ella
- Ellos también tienen sus propias propiedades; grado, sub-base, etc

Usted tiene una propiedad adicional en su modelo que no iba a utilizar normalmente
- Si una clase tiene 20 alumnos, cada uno de ellos se identifica con un identificador secundario del 1 al 20


Esto daría me las siguientes tablas de dimensiones

Student     Class      Grade    SubGrade 
----------------------- ------------------------ ----------------- ----------------- 
id   INT PK  id   INT PK  id INT PK  id INT PK 
first_name VARCHAR(45) name   VARCHAR(45) name VARCHAR(45) name VARCHAR(45) 
last_name VARCHAR(45) grade_id  INT FK  desc VARCHAR(45) desc VARCHAR(45) 
etc, etc     subgrade_id INT FK  etc, etc   etc, etc 

La tabla Class w debería tener una restricción única en (grade_id, subgrade_id) para que solo una clase pueda ser alguna vez 7b.

Luego hay que relacionar los estudiantes a sus clases utilizando una tabla de hechos ...

Class_Membership 
----------------------- 
id    INT PK 
student_id  INT FK 
class_id   INT FK 
academic_year INT 

Si un estudiante debe ser sólo alguna vez en una clase en un año académico, que le pone una restricción única en (student_id, academic_year).

Alternativamente, podría tener el año académico en la tabla Class. Esto significaría que tendría la misma clase repetida para cada año, pero que en algunos años la clase 7g no puede existir (ya que hay menos estudiantes ese año, por ejemplo).

Igualmente, podría tener estudiantes que pasen de 7b a 7c a mediados de año. En cuyo caso, la tabla Class_Membership podría tener un campo start_date y posiblemente un campo end_date.


Nada de eso, sin embargo, crea directamente el campo id_class (1-20 para una clase con 20 estudiantes). Personalmente, no tendría ese campo, el campo id de la tabla Class_Membership puede cumplir la mayoría de la misma funcionalidad y probablemente una funcionalidad adicional. Donde es necesario, sin embargo, usted podría simplemente añadirlo a la tabla Class_Membership ...

Class_Membership 
----------------------- 
id    INT PK 
student_id  INT FK 
class_id   INT FK 
academic_year INT 
class_member_id INT 

entonces también podría tener una restricción única en (academic_year, class_id, class_member_id).


Hay un buen montón de flexibilidad aquí, dependiendo de su mundo-modelo real y exacta a sus necesidades particulares.Pero espero que este ejemplo sea un buen comienzo para ti; Tablas de dimensiones que enumeran las entidades y una tabla de hechos (o tablas) que relacionan estas entidades y/o describen con mayor detalle las entidades.

+1

Como queston el esquema tal como está, agregaré mis pensamientos aquí. @Bosak, en mi entender, el "subgrado" es solo una letra para distinguir diferentes clases en el mismo grado. Por lo tanto, mientras que el grado y la subrasante identifican una clase, una subrasante en sí misma no es realmente una entidad. Rara vez le interesarán "todas las clases con subgrado b", e incluso menos interesado en almacenar atributos comunes para todas las clases b, ¿verdad? En ese caso, soltaría la tabla SubGrade. – MvG

0
alter table <TableName> add constraint <ConstraintName> unique(<col1>, <col2>) 

Modified the answer due to syntax mistakes. Mentioned above is correct. 
Cuestiones relacionadas