Comencé algunos proyectos con EF, pero tenía algunas preguntas sobre unir tablas y claves, etc. Digamos que tengo una tabla de aplicaciones y una tabla de permisos. Las aplicaciones tienen muchos permisos y cada permiso puede pertenecer a muchas aplicaciones (muchas a muchas).
Ahora, las tablas de Solicitud y Permisos son fáciles:
Applications
--------------
PK ApplicationID
Name
Permissions
--------------
PK PermissionID
Name
Pero, ¿cuál es la MEJOR forma de hacer la mesa de unión? Tengo estas dos opciones:
ApplicationPermissions
-----------------------
PK ApplicationPermissionID
CU ApplicationID
CU PermissionID
O
ApplicationPermissions
-----------------------
CPK ApplicationID
CPK PermissionID
PK = Primary Key
CPK = Composite Primary Key
CU = Composite Unique Index
¿Alguna vez te has quemado haciéndolo de un lado a otro? ¿Es estrictamente preferencia? Se me ha ocurrido que muchas de las "diferencias" serán eliminadas por mi patrón de repositorio (por ejemplo, casi nunca crearía un objeto de permiso completo y lo agregaría a una aplicación, sino que lo haría por ID o nombre único o algo), pero creo que estoy buscando historias de terror, de una forma u otra.
fuente
A lo largo de los años, adquirí el hábito de dar a cada tabla "TableName" una clave primaria autogenerada "TableNameID", sin excepciones, ni siquiera para las tablas de unión. Puedo decir que nunca me arrepentí, porque hace muchas cosas más fáciles al crear código genérico que hace algo para "todas las tablas" o "algunas tablas", o para "muchas filas de varias tablas diferentes".
Por ejemplo, si alguien le pide que almacene algunas filas de tablas diferentes (o referencias a ellas) en un archivo o en la memoria, por ejemplo, para fines de registro, es muy útil cuando sabe de antemano que solo necesita almacenar exactamente una nombre de la tabla y exactamente un ID entero, y no tiene que lidiar con ningún "caso especial".
Otra cosa, cuando comienza con PK combinados, probablemente algunas veces más tarde se encontrará con la necesidad de claves foráneas combinadas (ya que puede llegar a un punto en el que desea agregar una referencia FK a su
ApplicationPermissions
tabla). Entonces, el siguiente requisito puede ser que este FK sea único junto con otros atributos o claves foráneas, lo que resultará en una mayor complejidad en general. Nada que no sea posible manejar para la mayoría de los sistemas de DB modernos, por supuesto, pero una solución uniforme facilita mucho la vida de los programadores.Y finalmente, una declaración como
SELECT ... FROM TABLE WHERE TableNameID IN (id1,id2,...)
funciona bien con una sola columna como clave principal, pero nunca he visto un dialecto SQL hasta ahora que le permita hacer esto con teclas combinadas. Si sabe de antemano que nunca necesitará una consulta como esta, está bien, pero no se sorprenda si mañana obtiene un requisito que se resolverá más fácilmente con este tipo de SQL.Por supuesto, cuando espera que su
ApplicationPermissions
tabla contenga varios cientos de millones de filas, debe considerar evitar algo como aApplicationPermissionsID
.fuente
Si bien la respuesta de Mike es buena, estas son las razones por las que agregaría un campo de ID por separado o no.
Considere utilizar un campo de ID separado para la tabla de unión / unión si contiene campos distintos al ID . Esto tiende a notar que es una entidad de primera clase.
Considere usar un campo de ID separado si las API o cualquier lógica existente tienden a usar campos únicos para recuperar / editar entidades. Eso puede ayudar a otras personas a seguir su código en el contexto de un proyecto más grande.
No lo use si no hay un beneficio específico (KISS). EF sabe cómo manejar este tipo de tabla y a veces se puede pasar por alto una restricción única compuesta cuando otras personas intentan comprender este tipo de relación. Además, al normalizar, trato de usar la clave más pequeña posible que define de forma única la tupla . En su segundo ejemplo, efectivamente tiene 2 claves principales candidatas separadas.
fuente
Recuerde crear un índice y una clave externa en ambos
PersonId
yAddressId
.No importa lo que otros piensen que es "mejor" o "debería", esta es la forma más simple y fácil de permitir que la base de datos funcione correctamente.
fuente
PersonAddress
filas con idénticaPersonId
yAddressId
valores.