2010-11-02 21 views
11

Utilizo SQL Server y cuando creo una nueva tabla hago un campo específico que incrementa automáticamente la clave primaria . El problema es que algunas personas me dijeron que convertir el campo en un incremento automático para la clave primaria significa que al eliminar cualquier registro (no les importa el número de campo de incremento automático) el campo aumenta en algún momento, si el tipo de campo es entero, por ejemplo, el rango del número entero se consumirá por completo y tendré problemas. Entonces me dicen que no use esta función más.Función de incremento automático en la base de datos

La mejor solución es hacer esto a través del código obteniendo el máximo de mi clave principal, y si el valor no existe, el máximo será 1, de lo contrario max + 1.

¿Alguna pregunta sobre este problema? ¿Puedo usar la función de incremento automático?

Quiero también conocer los casos que no sean preferible usar incremento automático ..y las alternativas ...

nota :: esta pregunta no es general específica para cualquier DBMS, quiero saber es esto cierto también para DBMS como ORACLE, Mysql, INFORMIX, ....

Muchas gracias.

+4

Bueno, ¿cuál es el problema si hay "agujeros" en el orden de los números PK? ¿A quien le importa? – zerkms

+0

vaya para UniqueIdentifier :) –

+2

@Serkan: este es un problema fantasma; consulte los argumentos a continuación para ver por qué el problema no existe. 'UniqueIdentifier' ciertamente no debe usarse con esto como motivación. Es un valor de 16 bytes que consumirá 4 veces más espacio que un 'int', que es aceptable en la gran mayoría de los casos, y el doble que un' bigint' que casi siempre será aceptable, pero generalmente no es necesario –

Respuesta

11

Debe usar columnas de identidad (incremento automático). El tipo de datos bigint puede almacenar los valores hasta 2^63-1 (9,223,372,036,854,775,807). No creo que su sistema llegue pronto a este valor, incluso si está insertando y eliminando muchos registros.

Si implementa el método que propone correctamente, terminará con muchos problemas de bloqueo . De lo contrario, tendrá que lidiar con las excepciones lanzadas debido a violación de la restricción (o incluso peor - valores no exclusivos, si no hay una restricción de clave primaria).

+3

+1.Además, no olvides que aún tendrás todos esos "huecos" si tomas la ruta máxima + 1; eso solo marcaría la diferencia si solo eliminas el último registro puesto. – AviD

+1

También puedes tener condiciones de carrera si lo haces incorrectamente – HLGEM

+0

@HLGEM :: ¿qué quieres decir con las condiciones de carrera aquí? –

3

Continuar utilizando la función de identidad con PK en SQL Server. En mysql, también hay función de incremento automático. No se preocupe si se queda sin rango de enteros, se quedará sin espacio en el disco duro antes de que eso suceda.

3

La solución que sugieren puede, y probablemente creará, un problema de concurrencia y/o un problema de escalabilidad. Si dos sesiones usan la técnica de Max que describes al mismo tiempo, pueden obtener el mismo número y luego intentar agregarlo al mismo tiempo. Esto creará una violación de restricción.

Puede solucionar este problema bloqueando la tabla o detectando excepciones, y continúe reinsertando ... pero esa es una manera realmente mala de hacer las cosas. El bloqueo reducirá el rendimiento y provocará problemas de escalabilidad (y si está planificando tantos registros como para preocuparse por desbordar un int, necesitará escalabilidad).

Los campos de identidad son operaciones atómicas. Dos sesiones no pueden crear el mismo campo de identidad, por lo que este problema no existe al usarlo.

Si le preocupa que un campo de identidad pueda desbordarse, utilice un tipo de datos más grande, como bigint. Sería difícil generar suficientes registros para desbordar eso.

Ahora, hay razones válidas para NO usar un campo de identidad, pero este no es uno de ellos.

8

Un tipo de datos int en SQL Server puede contener valores desde -2,147,483,648 hasta 2,147,483,647.

Si inicializa su columna de identidad con -2,147,483,648, p. FooId identity(-2,147,483,648, 1), entonces tiene más de 4 mil millones de valores para jugar.

Si realmente piensa que esto todavía no es suficiente, se puede utilizar un bigint, que puede contener valores de -9.223.372.036.854.775.808 través 9.223.372.036.854.775.807, pero esto casi garantiza que sea una exageración. Incluso con grandes volúmenes de datos y/o una gran cantidad de transacciones, probablemente se quede sin espacio en el disco o agote la vida útil de la aplicación antes de agotar los valores de identidad cuando use un int, y casi con seguridad cuando use un bigint.

En resumen, debe usar una columna de identidad y no debe preocuparse por las lagunas en los valores ya que a) tiene suficientes valores candidatos yb) es un número abstracto sin significado lógico.

Si implementara la solución que sugiere, con el código que deriva la siguiente columna de identidad, debería considerar la simultaneidad, ya que deberá sincronizar el acceso al valor máximo de identidad actual entre dos transacciones competidoras. De hecho, puede terminar introduciendo una degradación significativa del rendimiento, ya que primero tendrá que leer el valor máximo, calcular e insertar (sin mencionar el trabajo adicional que implica sincronizar las transacciones concurrentes). Sin embargo, si usa una columna de identidad, el motor de la base de datos manejará la concurrencia.

+0

es este el caso en mysql y Informix DBMSs también ,, o no –

+0

segundo ¿qué quiere decir con número abstracto? –

+1

mysql/informix - ninguna idea! preguntaste sobre el servidor SQL ... –

1

Yo aconsejaría contra el uso de la Identidad/Auto-incremento, debido a que:

  • Es la aplicación se rompe en el servidor SQL 2005/2008. Read more

  • No funciona bien si va a utilizar un ORM para asignar su base de datos a los objetos. Read more

Yo aconsejaría a utilizar el generador de alta/baja si suele acceder a su base de datos a través de un programa y no dependen de envío de instrucciones de inserción manual para el PP. Puedes leer más sobre esto en el segundo enlace.

+1

¡Otra trampa de ORM! :-) –

+0

Esa es otra discusión :) Pero realmente no lo veo como un escollo. Las ventajas superan la desventaja marginal – Trygve

+0

sí mapeo todas mis tablas a clases en la capa de acceso a datos ,, está usando el incremento automático en este caso será un gran problema. –

Cuestiones relacionadas