2009-02-03 15 views
12

Tuvimos una reunión esta mañana acerca de cómo debería almacenar nuestra identificación para algunos activos que tenemos en nuestra base de datos que estamos haciendo, la lluvia de ideas generó un poco de calor, así que decidí consultar a los expertos de SO.¿Usar prefijos específicos de elemento y autonumber para claves primarias?

La estructura de la tabla que creer que deberíamos tener (versión corta) es como la siguiente:

Ejemplo 1)

  • assetId - int (32) - Primary Key
  • tipo - cadena

por lo que algunos datos de ejemplo es la siguiente:

==AssetId======Type=== 
    12345  "Manhole" 
    155415  "Pit" 

etc.

Otro miembro del equipo sugirió algo como esto:

Ejemplo 2)

  • assetId - cadena - de clave principal
  • Tipo - cadena

por lo que algunos datos de ejemplo es la siguiente:

==AssetId======Type=== 
    "MH12345" "Manhole" 
    "P155415" "Pit" 

donde hacemos una versión corta del tipo y lo añaden a la parte delantera 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 ha gustado la idea de usar cadenas como ID para ordenar las 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ía? ¿Y por qué? ¿Hay algún beneficio al usar el enfoque 1 sobre 2?

EDIT: Sí Me va a utilizar para la aproximación AUTO_INCREMENT 1.

+0

Parece que varias respuestas, incluida la aceptada actualmente, malinterpretan el ejemplo 2 como claves primarias naturales, es decir, claves que contienen datos comerciales reales. Tal vez podría aclarar esto un poco, ya que las claves en el ejemplo 2 parecen ser solo claves indirectas, que no tienen conexión con los datos comerciales de la fila, pero con un prefijo específico de la tabla adicional. –

Respuesta

25

Por lo general, la regla de oro es que nunca utilice información significativa en las teclas principales (como el número de la Seguridad Social o el código de barras). Simplemente entero autoincrementado. Sin embargo, los datos parecen constantes; puede cambiar en un punto (llega una nueva legislación y se recalculan todos los SSN).

+2

¡Sí! En las últimas 3 compañías en las que trabajé se causó mucho dolor porque un idiota eligió una clave "natural". UPCs se reciclan; no todos tienen un SSN; la gente se arruina creando SKUs. Usted almacena eso, puede ÚNICO, pero el PK es SU número secreto para las relaciones. Usted no lo expone. –

+0

Creo que esta respuesta ni siquiera responde la pregunta. No estaba proponiendo claves naturales, sino una clave sustituta con un prefijo que indica a qué tabla pertenece la clave. ;-) –

4

me gustaría ir para 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 existen otros beneficios de rendimiento en 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.

2

Personalmente creo que el primer enfoque es mucho, mucho mejor. Permite que el software de la base de datos realice comparaciones enteras simples para buscar y ordenar por la clave, lo que mejorará el rendimiento de la operación de la tabla (SELECT, JOINs complejos, búsquedas INDEX por teclado, etc.)

Por supuesto, estoy suponiendo que de cualquier manera, usted está utilizando algún tipo de método de incremento automático 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?

+0

Sí, usaré AUTO_INCREMENT para el acercamiento 1. (agregado a la publicación) –

7

Esta es una decisión entre surrogate and natural keys, ser natural el primer ser subrogado (o "técnica") y el segundo.

He llegado a la conclusión de que casi siempre debe usar claves sustitutivas. Si usa claves naturales, esas pueden cambiar y actualizar las claves principales/externas no es una buena idea en general.

+0

Este es un punto interesante, pero no responde la pregunta, ya que tanto el ejemplo 1 como el 2 son claves sustitutivas. ;-) –

0

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, utilice la más corta que pueda 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 encuentra que necesita usar una clave basada en cadenas más tarde, es un trabajo de sustitución simple:

  • agregar la clave primaria picada a la tabla de activos.
  • agregue la clave externa de cadena a las tablas de referencia.
  • actualiza las relaciones de cadenas con el simple comando UPDATE utilizando relaciones enteras.
  • agregue restricciones de clave externa para las columnas sting.
  • elimina las restricciones de clave externa para las 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.

3

Bueno, quiero hacer algunas observaciones y sugerencias,

  • considerar tener una tabla separada para el Tipo, por ejemplo con la columna Id y la descripción, a continuación, hacer una TypeId clave externa 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 Cadena tiene sentido, si luego tu gente piensa en cambiar hacia UUID. No es necesario cambiar el tipo de datos a continuación

[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.

1

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 desde 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" 
0

La única ventaja del ejemplo 2, es que se puede deducir fácilmente sólo de la clave principal, que solo fila de la tabla que esta clave se aplica a. 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.

(Puede tener esta ventaja también mediante el uso de una secuencia global para generar claves numéricas, o mediante el uso de diferentes rangos numéricos, últimos dígitos o lo que sea. Entonces no tiene desventajas de rendimiento, pero tal vez no encontrará el tabla tan fácilmente.)

3

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.

Cuestiones relacionadas