2009-02-07 16 views
7

Me he estado preguntando cuáles son las mejores prácticas o ramificaciones en la configuración de PK en una tabla M2M en SQL Server. Por ejemplo:Mejores prácticas para PK en SQL Server

Tengo 2 tablas

  • Usuarios
  • Roles

estoy haciendo una nueva tabla

  • UserRole

, que tiene 2 campos RoleId & ID de usuario

ahora debo

  1. crear un UserRoleID como el PK y hacer ID de usuario y RoleID los FKs
    • hacen que el ID de usuario PK Y RoleID y ponerlos como FKs
    • algo más

Me gustaría saber los problemas de rendimiento con cada una de las opciones y cuáles son las mejores prácticas recomendadas.

Respuesta

10

El procedimiento estándar para estos casos es tener dos índices. El PK único es el compuesto de dos campos, con el campo con la mayor cardinalidad primero, es decir, ID de usuario; y el segundo índice con solo el campo secundario (es decir, RoleID).

A continuación, agrupe en el que sea más probable que participe en más conjuntos de resultados multirecord (es decir, si consulta varios roles por usuario o varios usuarios por rol).

+0

¡Gracias por no recomendar una llave sustituta inútil! +1 –

1

Depende si espera colgar cualquier otro significado al hecho de que un usuario específico tiene un rol específico. Si no, solo crea un PK agrupado para abarcar los dos campos.

Agregue FK para ambos y agregue un índice al segundo campo. Analice en qué orden deben aparecer los campos. ¿Es más probable que esté recuperando un conjunto de funciones a las que pertenece un usuario o el conjunto de usuarios en un rol específico?

0

Depende de cómo los esté usando. La mayoría de las veces creo la clave principal como UserId y RoleId para asegurarme de que sean únicos. Lo que significa que el mismo usuario no puede tener el mismo rol.

Ahora aquí es donde entra en juego el "depende". Si va a vincular la tabla UserRole a otra tabla, aquí es donde creo la clave primaria UserRoleId. Y haga UserId y RoleId en una restricción única.

La razón para esto es no tener en la tabla que las referencias UserRole tengan tanto un UserId como un RoleId cuando no es necesario porque se está vinculando al UserRoleId y no a la tabla de usuario y la tabla de roles respectivamente.

+0

¿Prefiere unirse a dos tablas cada vez que quiera obtener información útil en lugar de agregar 4 bytes adicionales a otra fila de la tabla? –

+0

@TomH. Entiendo tu punto, pero ¿cuándo cambias? Si tiene una tabla m: m: m, ¿pondría las tres columnas en cada niño? ¿Qué tal 4 o 5? Eventualmente tus uniones se vuelven magníficamente feas, por lo que tememos la clave natural y queremos que las claves sustitutas hagan que las uniones sean columnas simples. –

2

Declare PK como (ID de usuario, ID de función).(Nota: el orden es importante)

Declare el ID de usuario como un FK con la referencia a la tabla Usuarios. Declara RoleID como un FK con la referencia a la tabla Roles.

Con un poco de suerte, su DBMS le dará un índice compuesto en (ID de usuario, RoleID) en ese orden.

Con un poco de suerte, esto acelerará las uniones entre usuarios y roles. Un buen DBMS le proporcionará una combinación de combinación para una unión sin más restricciones que la condición de unión. Una combinación de tres vías también debe ejecutarse bastante rápido, suponiendo que la cantidad de roles sea pequeña.

Cuando se une a UserRoles y Roles, sin unirse a Usuarios, puede encontrar que es decepcionantemente lento. ¿Con qué frecuencia lo hace y qué tan importante es la velocidad en este caso? Si es importante, puede crear un índice solo en RoleID.

0

Evite la PK compuesta y coloque un índice único en los dos FK (parece apropiado en este caso). No es un problema en este caso, pero sea consistente. Tener que recordar abordar los múltiples campos para unir cuando se escriben las consultas es un problema. Si su clave compuesta tiene que estar compuesta por datetime, char u otros tipos de campos, el rendimiento tiene éxito.

+0

La inclusión de otras columnas en un índice es algo bueno. Puede significar que una consulta se puede resolver solo con el índice y puede evitar todas las búsquedas de tabla. Creo que los usuarios de MSSS llaman a esas "consultas cubiertas". –

Cuestiones relacionadas