database-design - traductor - primary key y foreign key
¿Utiliza prefijos y autonumerarios específicos para las claves principales? (9)
Tuvimos una reunión esta mañana acerca de cómo debería almacenar nuestra identificación para algunos de los activos que tenemos en nuestra base de datos que estamos creando, la explosión generó un poco de calor, así que decidí consultar a los expertos de SO.
La estructura de la tabla que creo que deberíamos tener (versión corta) es como la siguiente:
Ejemplo 1)
- AssetId - int (32) - Clave principal
- Tipo - cadena
así que algunos datos de ejemplo son así:
==AssetId======Type===
12345 "Manhole"
155415 "Pit"
etc.
Otro miembro del equipo sugirió algo como esto:
Ejemplo 2)
- AssetId - cadena - Clave principal
- Tipo - cadena
así que algunos datos de ejemplo son así:
==AssetId======Type===
"MH12345" "Manhole"
"P155415" "Pit"
donde hacemos una versión corta del tipo y la anexamos al frente de la ID y la almacenamos en la base de datos. He visto algunas bases de datos de activos que hacen esto y nunca he tenido realmente este enfoque.
Nunca me gustó la idea de usar cadenas como ID para ordenar razones. También siento que está almacenando información inútil por el simple hecho de que ya tienes el tipo de almacén de activos.
¿Qué enfoque tomarías? ¿Y por qué? ¿Hay algún beneficio al usar el enfoque 1 sobre 2?
EDITAR: Sí, usaré AUTO_INCREMENT para el acercamiento 1.
Esta es una decisión entre claves sustitutos y naturales , la primera es sustituta (o "técnica") y la segunda es natural.
Llegué a la conclusión de que casi siempre deberías usar claves sustitutivas. Si usa claves naturales, esas pueden cambiar y actualizar las claves principales / externas no es una buena idea en general.
Personalmente, creo que el primer enfoque es mucho, mucho mejor. Permite que el software de la base de datos haga comparaciones enteras simples para buscar y ordenar por la clave, lo que mejorará el rendimiento de la operación de la tabla (SELECT, JOINs complejas, búsquedas INDEX por teclado, etc.)
Por supuesto, supongo que de cualquier manera, estás usando algún tipo de método de autoincremento para producir los ID, ya sea una secuencia, un AUTO_INCREMENT o algo similar. Hazme un favor y no los construyas en el código de tu programa, ¿de acuerdo?
Por lo general, la regla de oro es que nunca utilice información significativa en las claves principales (como el número de seguridad social o el código de barras). Simplemente entero autoincrementado. Por muy constante que parezca la información, puede cambiar en un punto (llega una nueva legislación y se recalculan todos los SSN).
Prefiero el Ejemplo 1 por las razones que mencionas y el único argumento que se me ocurre para usar el Ejemplo 2 es si estás tratando de acomodar identificadores de cadena de una base de datos existente (bastante común), sin embargo, incluso en ese escenario, prefiero usar el siguiente enfoque.
==AssetId(PK)==Type========DeprecatedId====
12345 "Manhole" "MH64247"
155415 "Pit" "P6487246"
Si sus activos ya tienen identificadores naturales únicos (como empleados con sus ID de empleado), úselos. No tiene sentido crear otro identificador único.
Por otro lado, si no hay una identificación única natural, use la más corta posible que garantice suficientes claves únicas para su tamaño de tabla esperado (como su número entero). Se requerirá menos espacio en disco y probablemente sea más rápido. Y, además, si luego necesita usar una clave basada en cadenas, es un trabajo de sustitución simple:
- agregue la clave primaria picada a la tabla de activos.
- agregue la clave externa de cadena a las tablas de referencia.
- actualizar las relaciones de cadenas con el simple comando UPDATE usando relaciones enteras.
- agregue restricciones de clave externa para las columnas sting.
- eliminar restricciones de clave foránea para columnas enteras.
- eliminar columnas enteras por completo.
Algunos de estos pasos pueden ser problemáticos en un DBMS específico, quizás requiriendo una descarga / recarga de tabla para eliminar las columnas de clave primaria entera, pero esa estrategia es básicamente lo que se requiere.
Yo iría por el primero. La creación de identificadores únicos debe dejarse en el servidor SQL, y no se pueden tener los que se crean de forma automática en una ejecución segura de subprocesos si son cadenas. Según tengo entendido, ¿tendrías que manejar eso de alguna manera?
La velocidad es otro factor. Tratar con los valores int siempre va a ser más rápido que las cadenas. Diría que hay otros beneficios de perfrentamiento alrededor de la indexación que una persona mucho más experta en SQL que yo podría explicar;)
En mi experiencia, tener identificadores de cadena ha sido un fracaso.
Elegiría una clave primaria numérica por motivos de rendimiento. Las comparaciones enteras son mucho más económicas que las comparaciones de cadenas, y ocuparán menos espacio en la base de datos.
La única ventaja del ejemplo 2 es que puede ver fácilmente, solo desde la clave principal, a qué fila de la tabla se aplica esta clave. La idea es buena, pero si es útil o no depende de tus estrategias de registro y error. Probablemente tenga una desventaja de rendimiento, por lo que no lo usaría a menos que pueda mencionar algunas razones específicas para usarlo.
(También puede tener esta ventaja usando una secuencia global para generar claves numéricas, o usando diferentes rangos numéricos, últimos dígitos o lo que sea. Entonces no tiene desventajas de rendimiento, pero tal vez no encuentre la tabla tan fácilmente. )
Bueno, quiero hacer algunos puntos y sugerencias,
Considere tener una tabla separada para Type, digamos con la columna Id y Desc, luego haga una clave foránea TypeId en esta tabla. Un paso más para normalizar la cosa. Pero puede que no sea deseable. Hazlo si crees que sirve para algún propósito
Hacerlo String tiene sentido, si más tarde tu gente piensa en cambiar hacia UUID. No necesita cambiar el tipo de datos, entonces
[Editado]
Estoy de acuerdo con Cletus aquí. Esa clave sustituta demostró ser beneficiosa en algunos proyectos de la vida real. Permiten el cambio, y usted sabe bien que, el cambio es la única constante.