2008-11-04 9 views
17

Actualmente estoy trabajando en la base de datos de otra persona donde las claves principales se generan a través de una tabla de búsqueda que contiene una lista de nombres de tabla y la última clave primaria utilizada. Un procedimiento almacenado incrementa este valor y verifica que sea único antes de devolverlo al SP de "inserción" de llamada.Razones para no usar un número de incremento automático para una clave principal

¿Cuáles son los beneficios de utilizar un método como este (o simplemente generar un GUID) en lugar de simplemente usar el número de identidad/automático?

No estoy hablando de claves primarias que en realidad "significan" algo así como ISBN o códigos de producto, solo los identificadores únicos.

Gracias.

Respuesta

27

Un ID generado automáticamente puede causar problemas en situaciones en las que está utilizando la replicación (¡ya que estoy seguro de que las técnicas que ha encontrado pueden hacerlo!). En estos casos, generalmente opto por un GUID.

Si no es probable que utilice la replicación, es probable que un PK de incremento automático funcione bien.

+0

¿Puedes dar un ejemplo de replicación? ¿No podemos usar la inserción de identidad para la identificación autogenerada mientras se replica? – ivorykoder

+0

@ivorykoder Si dos bases de datos generan una nueva fila (y por lo tanto una nueva ID) y luego intentan sincronizar, habrá un conflicto ya que dos filas diferentes en la tabla tendrán PK diferentes. Si usa GUID, prácticamente se garantiza que los PK serán únicos. – Matthew

6

El método de procedimiento de incremento debe ser seguro para subprocesos. De lo contrario, es posible que no obtenga números únicos. Además, debe ser rápido, de lo contrario será un cuello de botella de la aplicación. Las funciones integradas ya han tenido en cuenta estos dos factores.

2

Una de las ventajas es que puede permitir que la base de datos/SQL sea más multiplataforma. El SQL puede ser exactamente el mismo en SQL Server, Oracle, etc.

6

Es útil para los clientes poder preasignar un montón de ID para hacer una inserción masiva sin tener que actualizar sus objetos locales con los ID insertados. Luego está todo el problema de replicación, como lo menciona Galwegian.

3

El uso de identificadores únicos le permitiría combinar datos de dos bases de datos diferentes.

Quizás tenga una aplicación que recolecta datos en múltiples bases de datos y luego se "sincroniza" con una base de datos maestra varias veces durante el día. No tendría que preocuparse por las colisiones de teclas principales en este escenario.

O, posiblemente, es posible que desee saber cuál será la identificación de un registro antes de que realmente lo cree.

1

La única razón que se me ocurre es que el código fue escrito antes de sequences se inventaron y el código se olvidó de ponerse al día;)

+0

Derecha. La base de datos para una de nuestras aplicaciones más antiguas tenía el enfoque local usando una tabla de secuencia (básicamente lo que se describe) porque MySQL no las soportaba (o posiblemente tenía errores) en ese momento. Las tablas todavía existen, pero hemos estado usando lo real durante años. – MBCook

1

yo preferiría usar un GUID para la mayoría de los escenarios en los que del puesto el método actual tiene sentido para mí (la replicación es posible). Si la replicación era el problema, dicho procedimiento almacenado debería conocer el otro servidor, que debería estar vinculado para garantizar la singularidad de la clave, lo que lo haría muy frágil y probablemente una forma pobre de hacerlo.
Una situación en la que utilizo claves primarias enteras que NO son identidades autoincrementables es el caso de tablas de búsqueda rara vez modificadas que imponen restricciones de clave externa, que tendrán una enumeración correspondiente en la aplicación que consume los datos. En ese escenario, quiero asegurarme de que la asignación enum será correcta entre el desarrollo y la implementación, especialmente si habrá múltiples servidores de prueba.

0

La única razón real para hacer esto es ser independiente de la base de datos (si las diferentes versiones de db utilizan diferentes técnicas de numeración automática).

El otro problema mencionado aquí es la capacidad de crear registros en varios lugares (como en la oficina central y en las laptops de los usuarios que viajan). Sin embargo, en ese caso, probablemente necesitaría algo así como un "código de sitio" que fuera exclusivo de cada instalación que tenía el prefijo para cada ID.

1

Otra posible razón es que deliberadamente desea claves aleatorias. Esto puede ser deseable si, por ejemplo, no desea navegadores curiosos que hojeen todos los elementos que tiene en la base de datos, pero no es lo suficientemente crítico como para garantizar medidas reales de seguridad de autenticación.

17

No hay nada intrínsecamente incorrecto con el uso de Autonumérico, pero hay algunas razones para no hacerlo. Aún así, lanzar tu propia solución no es la mejor idea, como mencionó Dacracot. Dejame explicar.

La primera razón para no usar Autonumérico en cada tabla es que puede terminar fusionando registros de varias tablas. Supongamos que tiene una tabla de pedidos de venta y otro tipo de tabla de pedidos, y decide extraer algunos datos comunes y utilizar la herencia de tablas múltiples. Es bueno tener claves primarias que son globalmente únicas. Esto es similar a lo que dijo bobwienholt sobre la fusión de bases de datos, pero puede ocurrir dentro de una base de datos.

En segundo lugar, otras bases de datos no usan este paradigma, y ​​otros paradigmas como las secuencias de Oracle son mucho mejores. Afortunadamente, es posible imitar secuencias de Oracle utilizando SQL Server. Una forma de hacerlo es crear una sola tabla Autonumérico para toda su base de datos, llamada MainSequence, o lo que sea. Ninguna otra tabla en la base de datos usará el autonumber, pero cualquiera que necesite una clave primaria generada automáticamente usará MainSequence para obtenerla. De esta forma, obtienes todo el rendimiento, bloqueo, seguridad de hilos, etc. de los que dacracot estaba hablando sin tener que construirlo tú mismo.

Otra opción es usar GUID para claves primarias, pero no lo recomiendo porque incluso si está seguro de que un ser humano (incluso un desarrollador) nunca va a leerlos, probablemente alguien lo haga, y es difícil. Y, lo que es más importante, las cosas se convierten implícitamente en ints muy fácilmente en T-SQL pero pueden tener un montón de problemas al convertir implícitamente a un GUID. Básicamente, son inconvenientes.

Al construir un nuevo sistema, recomendaría usar una tabla dedicada para la generación de claves primarias (al igual que las secuencias de Oracle). Para una base de datos existente, no me desviaría de mi camino para cambiarlo.

10

de CodingHorror:

GUID Pros

  • único a través de cada mesa, cada base de datos, todos los servidores
  • Permite de fácil fusión de registros de diferentes bases de datos
  • Permite una fácil distribución de bases de datos a través de múltiples servidores
  • Puede generar ID en cualquier lugar, en lugar de tener que hacer un recorrido de ida y vuelta a la base de datos
  • La mayoría de los escenarios de replicación requieren columnas GUID de todos modos

GUID Contras

  • Es la friolera de 4 veces mayor que el valor tradicional de índice de 4 bytes; esto puede tener graves implicaciones de rendimiento y de almacenamiento, si usted no tiene cuidado
  • engorroso de depuración (donde id de usuario = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Los GUID generados deben ser parcialmente secuencial para un mejor rendimiento (por ejemplo, newsequentialid() en SQL 2005) y para permitir el uso de índices agrupados

El artículo proporciona una gran cantidad de buenos enlaces externos al tomar la decisión sobre GUID frente a Incremento automático. Si puedo, voy con GUID.

0

Un beneficio lateral útil de utilizar una clave principal GUID en lugar de una autoincrementada es que puede asignar el valor PK para una nueva fila en el lado del cliente (de hecho, debe hacerlo en un escenario de replicación) , evitándole la molestia de recuperar el PK de la fila que acaba de agregar en el servidor.

Una de las desventajas de un GUID PK es que las uniones en un campo GUID son más lentas (a menos que esto haya cambiado recientemente). Otro aspecto positivo del uso de GUID es que es divertido intentar explicar a un administrador no técnico por qué es poco probable una colisión GUID.

0

Mi problema principal con las teclas de incremento automático es que carecen de significado.

Para las tablas en las que determinados campos proporcionan la exclusividad (ya sea solo o en combinación con otro), optaría por usar eso en su lugar.

+0

Creo que cada tabla debe tener una clave "significativa", pero a menos que sea un único valor integral de atributo (rara vez es el caso), es demasiado golpe de rendimiento para FK, y las uniones relacionales ... Entonces Siempre trato de poner dos claves únicas en cada tabla, una clave de AutoNum y una clave significativa. –

+2

No creo que siempre sea bueno que PK tenga significado. Si tienen algún significado, se basa en el hecho de que las reglas comerciales no cambiarán de tal forma que permita que haya valores duplicados. Con PKs "sin sentido", esto no es una preocupación. – recursive

+0

... de ahí la estipulación de "donde ciertos campos proporcionan singularidad". No creo que sea un tipo de cosa de uno o de otro. –

3

Mi problema principal con las teclas de incremento automático es que carecen de cualquier significado

Eso es un requisito de una clave principal, en mi mente - no tienen otra razón para existir aparte de identificar un registro. Si no tiene un significado en el mundo real, entonces no tiene un motivo real para cambiar. No quiere que las claves principales cambien, en general, porque tiene que buscar-reemplazar su base de datos completa o algo peor. Me he sorprendido del tipo de cosas que he asumido serían únicas e inmutables que no han resultado ser años después.

0

La respuesta de Galwegian no es necesariamente cierta.

Con MySQL puede establecer un desplazamiento de clave para cada instancia de base de datos.Si combina esto con un incremento lo suficientemente grande, lo hará por multa. Estoy seguro de que otros proveedores tendrían algún tipo de configuración similar.

Digamos que tenemos 2 bases de datos que queremos replicar. Podemos configurarlo de la siguiente manera.

increment = 2 
db1 - offset = 1 
db2 - offset = 2 

Esto significa que

db1 tendrá las teclas 1, 3, 5, 7 ....

db2 tendrá teclas 2, 4, 6, 8 ....

Por lo tanto, no tendremos choques de teclas en las inserciones.

2

Aquí está la cosa con auto incrementar enteros como claves:

usted tiene que tener publicado el registro antes de obtener acceso a ella. Eso significa que hasta que haya publicado el registro, no puede, por ejemplo, preparar registros relacionados que se almacenarán en otra tabla, o cualquiera de muchas otras razones posibles por las que podría ser útil tener acceso a los registros únicos del nuevo registro id, antes de publicarlo.

Lo anterior es mi factor decisivo, ya sea que vaya con un método, o el otro.

Cuestiones relacionadas