2011-01-27 19 views
5

Tengo una tabla de usuario con userid y username, y ambas son únicas. Entre userid y username, ¿cuál sería mejor usar como clave foránea y por qué? Mi jefe quiere usar cadena? ¿Eso esta bien?¿Se prefiere cadena o int para claves externas?

+0

¿Puedo preguntar por qué tiene dos columnas únicas en la tabla? –

+2

Por qué no puede tener dos columnas únicas. Como tener una identificación, un correo electrónico y un nombre de usuario. Pueden ser todos únicos, ¿no? –

+0

Lo admito. Pregunta tonta. Solo me preguntaba si las dos columnas realmente describían lo mismo. nonnb respondió la pregunta hermosamente. –

Respuesta

13

Parece que usted tiene tanto una clave sustituta (int userId) y una clave natural (char o varchar username) Cualquiera de las columnas se puede usar como clave principal para la tabla, y de cualquier manera, aún podrá exigir la exclusividad de la otra clave.

Existen muchas discusiones sobre las ventajas y desventajas entre las claves naturales y sustitutas: deberá decidir qué es lo que le funciona y cuál es el "estándar" dentro de su organización.

Aquí hay algunas consideraciones a la hora de elegir un modo u otro:

Justificación de la utilización sustituto llaves (por ejemplo, identificación de usuario INT AUTO_INCREMENT)

Si utiliza un nombre de usuario (por ejemplo AUTO_INCREMENT INT) como Primario Clave, todas las tablas que hacen referencia a la tabla MyUsers usarían UserId como clave externa.

Todavía se puede sin embargo exigir la unicidad de la columna de varchar username través del uso de un adicional de unique index, por ejemplo:

CREATE TABLE `MyUsers` (
    `userId` int NOT NULL AUTO_INCREMENT, 
    `username` varchar(100) NOT NULL, 
    ... other columns 
    PRIMARY KEY(`userId`), 
    UNIQUE KEY UQ_UserName (`username`) 

Según @Dagon, utilizando una clave principal estrecho (como un int) tiene ventajas de rendimiento y de almacenamiento sobre el uso de un valor más ancho (y de longitud variable) como varchar. Este beneficio también afecta a otras tablas que hacen referencia a MyUsers, ya que la clave externa a userid se estrechará.

Además, si todas las tablas se acoplaron a MyUsers a través de username, es más incómodo cambiar un nombre de usuario (ya que de lo contrario se violaría la relación de clave externa). Si se requiere actualizar los nombres de usuario en tablas usando username como la clave externa, una técnica como ON UPDATE CASCADE necesitaría emplearse para conservar la integridad de los datos.

Sin embargo, con la clave entera sustituta, el nombre de usuario puede cambiarse sin afectar las tablas que hacen referencia a MyUsers (pero el cambio aún se puede rastrear).

El caso de la utilización de las teclas naturales (es decir, nombre de usuario)

En el lado negativo para el uso de sustitutos claves, tablas de referencia MyUsers a través de una clave sustituta siempre requerirán una combinación de vuelta a la mesa para recuperar el nombre de usuario. Uno de los posibles beneficios de las claves naturales es que si una consulta solo requiere la columna Username de una tabla que hace referencia a MyUsers, no necesita volver a unirse al MyUsers para recuperar el nombre de usuario. En cierto sentido, las teclas naturales ofrecen una forma leve de almacenamiento en caché en la columna clave.

Otras referencias here y here

+0

+1 para una respuesta pragmática, ambas soluciones tienen sus pro y sus contras. Personalmente, preferiría la solución de clave sustituta. –

+1

404 en el último enlace provisto. – johnsnails

1

int índice voluntad más rápido, puede o no ser un problema, difícil de decir en base a lo que usted ha proporcionado

1

Un int es de 4 bytes, una cadena pueden ser tantos bytes como desee. Por eso, un int siempre tendrá un mejor rendimiento. A menos, por supuesto, si usa nombres de usuario de menos de 4 caracteres :)

Además, nunca debe usar una columna como PK/FK si los datos dentro de la columna pueden cambiar. Los usuarios tienden a cambiar sus nombres de usuario, e incluso si esa funcionalidad no existe en su aplicación ahora mismo, lo hará en unos pocos años. Cuando llegue ese día, es posible que tenga 1000 tablas que hagan referencia a esa tabla de usuarios, y luego tendrá que actualizar todas las 1000 tablas dentro de una transacción, y eso es simplemente malo.

+0

no es la propiedad "en cascada de actualización" de la clave externa allí para encargarse de tales situaciones? ¿O me estoy perdiendo algo? Estoy de acuerdo con el punto de 4 bytes/4 caracteres. Pero no estoy de acuerdo con el segundo argumento. – shantanuo

+1

Claro, puedes hacer eso, pero sigue siendo malo. Esa actualización probablemente llevará más tiempo y creará más bloqueos de lo que es aceptable. Pero si eso no es un problema para la aplicación específica, adelante. Aún así no lo recomendaría. – TheQ

Cuestiones relacionadas