2009-03-19 14 views
6

Estoy creando una base de datos SQL que almacena contactos. Quiero poder eliminar contactos, y la identificación correcta para cada contacto es crucial para que mi software se conecte a ella. Digamos que tengo contacto con James y él es el primero. Su ID es 0. Agrego a Mary y su ID es 1. Si elimino a James, ¿cómo se puede configurar Mary id en 0 en lugar de permanecer 1? Tiene que reiniciarse ya que ella es la primera ahora. En otras palabras, ¿cómo puedo restablecer todos los ID en la base de datos cuando alguien es eliminado? GraciasRestablecer columna Identity en SQL Server

+0

¿Por qué exactamente quieres hacer esto? Si necesita mantenerlos en orden de entrada, puede tener una marca de fecha y hora o agregar una columna para mantener el rango. – achinda99

+2

Votivando la pregunta. Si bien estoy de acuerdo en que lo que el OP intenta hacer es desacertado, la pregunta es una buena señal para los programadores neófitos sobre lo que NO se debe hacer y por qué. Las respuestas que reciben muchos upvotes parecen abordar ese problema bastante bien y son muy instructivas. – JohnFx

+0

Es un error típico para los principiantes. Teniendo la sensación de que se quedarán sin ID, quieren ralentizar la tasa de crecimiento. –

Respuesta

3

No tiene sentido hacer esto en una columna de clave principal de incremento automático, ya que incluso si fuera trivial, sin actualizaciones masivas en las tablas relacionadas, afecta la integridad de los datos. Para hacerlo, es probable que deba soltar la restricción del índice y la clave principal de la columna (en ese momento su aplicación se puede descamar), renumerar todos los registros posteriores, renumerar todas las tablas relacionadas y luego volver a aplicar la restricción y el índice de la clave principal.

Si realmente debe tener algún tipo de identificador lineal que siempre comienza en 0 (esto puede indicar un problema con el diseño del software) entonces puede tener una segunda columna de ID además de la clave principal, que luego actualiza para mezclar los valores más altos hacia abajo un peldaño con una sentencia como:

UPDATE table 
SET secondaryID = secondaryID - 1 
WHERE secondaryID > (SELECT secondaryID FROM table WHERE primaryID = [id to delete]); 

DELETE FROM table 
WHERE primaryID = [id to delete]; 

yo estoy totalmente en tal práctica - si sus identificaciones han 'desaparecido' valores por los registros eliminados, el software debe probar la existencia de estos valores en lugar que simplemente salir.

6

Eso va a ser realmente lento una vez que tenga más que una cantidad trivial de registros en la base de datos. La columna de identidad no funcionará para ti, necesitas hacer algunos tsql personalizados para seguir cambiando todos los números, pero una muy mala idea, imo.

¿Por qué no utilizar un sello de fecha y hora si necesita realizar un seguimiento de los pedidos que se agregaron?

Necesita volver a pensar su diseño.

2

Está utilizando los identificadores como algo más que un simple identificador. Si ese es el caso, no podrá usar un campo de incremento automático. Necesitarás manejar esto en tu código.

5

Así no es como funcionan las ID, y no cómo deben funcionar. La ID nunca debería cambiar, o toda la información vinculada apuntaría a la fila incorrecta.

En su lugar, ¿por qué no agregar una columna "External_ID" que controle? O numerarlos dinámicamente en su consulta (¿con una columna calculada?)

16

Esta es una mala idea en muchos aspectos. Estoy debatiendo si debería mostrarte cómo hacer esto. Nunca debería haber una razón para cambiar la identidad de una fila una vez que está configurada.

Si existe, probablemente esté utilizando el campo incorrecto como su identificador PK. Estoy suponiendo aquí que estás hablando de tu campo PK, que también es una columna de identidad.

Tenga en cuenta que si crea cualquier tabla que se vincule a su tabla de contactos y comienza a cambiar su Id, también debe actualizar todas esas tablas. Que se volverá costoso ...

3

Esto se resolvería mucho mejor usando otro método que renumerar la columna de identidad cada vez que se borre una fila.

Difícil decir exactamente qué más haría sin saber por qué su aplicación tiene esta necesidad, pero el hecho de que su aplicación necesita esta funcionalidad probablemente sea indicativa de un problema de diseño en alguna parte.

4

El ID es el identificador único de la fila.

Se puede utilizar para vincular una fila a otra fila en otra tabla. La ausencia de ID también contiene información en sí misma, ya que indicaría claramente que fue eliminada. Empezar a reciclar los números de identificación derrota completamente el propósito de tener un identificador único, y realmente no tiene ningún sentido. Una vez que se asigna una identificación a una fila, no debe cambiarla arbitrariamente.

Imagine por un momento que cuando alguien muere, le entregan su número de seguro social (ID) a otra persona. Eso dará como resultado la transferencia de toda la información anterior que estaba vinculada al número de seguro social del muerto a esa nueva persona, lo cual no tiene ningún sentido. Lo mismo ocurre con las ID, si se reasigna una ID, heredará cualquier dato anterior que haya estado vinculado anteriormente.

0

Escribí una aplicación para manejar un programa de ventas de varios niveles. Por supuesto, la gente abandona. En el nuestro, las personas tenían que ser insertadas también.

Estás en el camino correcto con una modificación.

El número de identidad (ID) y el número de secuencia (seq) son dos cosas diferentes. No tienen ninguna relación entre ellos.

Nunca cambie una identificación. Una vez asignado, siempre asignado.

Cree una columna (cNEXT) en su tabla para la secuencia y rellene con ID. "¿Qué ID será el próximo en esta secuencia?"

Mezcle los ID en cNEXT, reasignando cNEXT, en cualquier momento que desee. Cualquier proceso almacenado puede hacer eso.

Luego también tiene la flexibilidad de crear cadenas de ID no secuenciales. Esto es útil cuando las personas se trasladan a diferentes regiones u obtienen promociones para diferentes grupos.

Espero que esto ayude! :)

1

A 1 minuto de búsqueda en google me dio una página que no puedo mostrar. Google esto y será su primer enlace a partir del 01/06/2009: tsql fix "columna de identidad"

Básicamente, sugiero agregar una restricción de clave externa entre todos sus campos relacionales al campo ID en cuestión antes de hacer cualquier renumeración (que también es una idea horrible si hay alguna relación, estrictamente porque si estás haciendo esta pregunta, vas a tener muchísimo tiempo).

Si su tabla de contactos es su ÚNICA tabla o tiene relaciones CERO basadas en este campo ID, puede establecer la propiedad Identidad en NO, renumerar los valores de 1 a COUNT (ID) y establecer la propiedad Identidad en SÍ, y sembrar de nuevo la identidad para la terminación usando:

DECLARE @MaxID INT

SELECT @MaxID = COUNT (ID) de TableID

DBCC CHECKIDENT ('TableID', rESEED, @MaxID)

En este escenario, podrías utilice la secuencia de comandos reseed anterior después de cada conjunto de eliminaciones (pero cambie COUNT (ID) a MAX (ID) una vez que todo esté configurado inicialmente correctamente, esto agrega un poco de velocidad a medida que la tabla aumenta), antes de cualquier inserción adicional o extranjera actualizaciones de restricciones clave. Asegúrese de utilizar TRANSACCIONES envueltas en los borrones y los bloques de resiembra, y asegúrese de que la tabla solo permita transacciones sincrónicas, esto evitará que se encharquen los datos en el medio de los reinicios.

Complejo eh? Por eso es mejor comenzar con el pie derecho. ;) (Lo aprendí de la experiencia) Envíenme un correo electrónico a mraarone et yahoo d0t com si tiene más preguntas.

0

Todas las respuestas presuponen que se trata de un entorno de producción. Si su prueba de un diseño de base de datos, a continuación, desea truncar rápidamente todas las tablas no debe ser una manera fácil de lograr esto:

DBCC CHECKIDENT ({nombre de la tabla}, sembrar de nuevo, 0)

* Eliminar todas las filas de todas las tablas que usan el ID primero

Cuestiones relacionadas