2008-10-03 13 views
8

Hola, quiero tener dos tablas, cada una tiene una columna INT "id" que se autoincrementará, pero no quiero que las columnas "id" compartan el mismo número. ¿Cómo se llama esto y cuál es la mejor manera de hacerlo? ¿Secuencia? ¿Iterador? ¿Índice? Incrementor?Comparta clave primaria autoincrementada entre dos tablas

Motivación: estamos migrando de un esquema a otro y tenemos una página web que lee las dos tablas y muestra el ID (int), pero no puedo utilizar el mismo ID para ambas tablas.

Estoy usando SQL Server 9.0.3068.

Gracias!

+0

¿Puede agregar por qué sería necesario, por favor? Puede haber un diseño mejor que no requiera el uso de GUID. –

Respuesta

14

Simplemente configure el incremento de identidad para que sea> 1 p. Ej. la tabla uno usa IDENTIDAD (1, 10) [1,11,21 ...] y la tabla dos usa IDENTIDAD (2, 10) [2,12,22 ...]. Esto también le dará espacio para la expansión si es necesario más tarde.

+0

¿Cómo exactamente hago esto? ¿Hay alguna forma de hacerlo utilizando PHPMyadmin? – everconfusedGuy

+0

También considere usar un bigint al hacer esto. –

3

Creo que el uso de un GUID sería la forma más directa, si lo entiendo correctamente.

SELECT NEWID() 
+0

Lo siento, debería haber mencionado que debe ser una int. – user24881

2

Utilice una columna con el tipo GUID (Globally Unique Identifier). Tiene 16 bytes y será siempre único para cada fila.

Sólo tenga en cuenta que obtendrá un golpe de rendimiento significativo en comparación con las claves enteras normales.

1

Utilice otra tabla con una clave ID de tipo int valor por defecto en 1, llamada KeyID o lo que sea.

Haga que un procedimiento almacenado recupere el valor, agregue 1, luego actualice el KeyID, luego regrese esto al procedimiento almacenado que está actualizando sus dos tablas que necesitan la nueva clave única.

Esto asegurará que la ID sea una int, y que sea única entre el conjunto de tablas que usan el procedimiento almacenado para generar nuevas ID.

0

No sé cómo lo llamarías.

Si no desea utilizar un GUID o una tabla separada, también puede crear una función que analice los valores máximos de los identificadores de ambas tablas y agregue uno a ese valor (o algo así) .

Podría llamar a esa función en un desencadenador de inserción en ambas tablas.

0

Personalmente, soy un fanático de la solución GUID, pero esta es una opción viable.

Muchas soluciones a este problema han evitado el GUID y han usado un buen entero antiguo. Esto es común también con las situaciones de duplicación de fusión donde muchos sitios satelitales se fusionan con un maestro y los conflictos clave deben evitarse.

Si GUID no funciona para usted, y absolutamente debe tener int, bigint o similar, siempre puede usar una columna de IDENTIDAD y tener cada tabla con un valor diferente para SEED. Esos tipos de datos tienen un rango muy amplio, y no es demasiado difícil dividir el rango en segmentos usables, especialmente si todo lo que desea son dos divisiones. Como ejemplo, basic int tiene un rango de -2^31 (-2,147,483,648) a través de 2^31 - 1 (2,147,483,647). Esto es más que suficiente para una tabla de clientes, por ejemplo.

Transact-SQL (SQL Server 2000) int, bigint, smallint, and tinyint

Ejemplo:

--Create table with a seed of 1 billion and an increment of 1 
CREATE TABLE myTable 
(
primaryKey int IDENTITY (1000000000, 1), 
columnOne varchar(10) NOT NULL 
) 
1

Se puede definir una columna de identidad en una tercera tabla, utilice que para generar valores de ID, pero siempre retire cualquier inserción que haga en la mesa (para evitar que crezca). Revertir la transacción no revierte el hecho de que se generó la ID.

No soy un usuario habitual de Microsoft SQL Server, así que perdone cualquier error de sintaxis. Pero algo como lo siguiente es lo que tengo en mente:

CREATE TABLE AlwaysRollback (
    id IDENTITY(1,1) 
); 

BEGIN TRANSACTION; 
INSERT INTO AllwaysRollBack() VALUES(); 
ROLLBACK TRANSACTION; 

INSERT INTO RealTable1 (id, ...) VALUES (SCOPE_IDENTITY(), ...); 

BEGIN TRANSACTION; 
INSERT INTO AllwaysRollBack() VALUES(); 
ROLLBACK TRANSACTION; 

INSERT INTO RealTable2 (id, ...) VALUES (SCOPE_IDENTITY(), ...); 
0

Si realmente necesita hacer esto con un int y tiene un número incremental de automóviles, la forma en que he hecho esto antes es cambiar el campo id función de incremento automático a la secuencia de la otra tabla. No estoy muy seguro en SQL MS SQL o de mi pero en pgsql que significa que en el sql que tendría este campo

id integer NOT NULL DEFAULT nextval('table_two_seq'::regclass), 

donde table_two_sequence es la función de secuencia de la otra tabla. Luego pruébelo insertando algunos datos. Realmente lo siento si esto no funciona en ms sql, trato de evitarlo tbh. En su defecto, el GUID es la mejor manera que otros han mencionado. O al insertar el código que usas, podrías ponerle un algoritmo, pero podría desordenarse.

Como alternativa, piense en tener los datos en una tabla, ya que esto sería una forma de evitarlo. si lo necesita, podría tener una vista que simule dos tablas. Solo un pensamiento.

espero haber ayudado

0

partir de SQL Server 2012 se puede declarar un objeto de secuencia https://msdn.microsoft.com/en-us/library/ff878091.aspx que es exactamente lo que necesita.

Debería ser bastante trivial emular un objeto de secuencia con una tabla que contenga el siguiente valor de secuencia y un procedimiento almacenado atómicamente seleccione el valor e incremente. [Le gustaría utilizar la función, pero las funciones no pueden tener efectos secundarios.]

¿Qué tal este truco? Cree una tabla (MySequence) con dos columnas: Y la columna Identity (SequenceValue) y una columna ficticia (DummyValue) y utilice este procedimiento almacenado para obtener un nuevo valor de secuencia. La única fila en la tabla será el último valor de secuencia recuperado.

CREATE PROCEDURE GetNextValue 
AS 
BEGIN 
    DECLARE @value int = null; 

    -- Insert statements for procedure here 
    INSERT into MySequence (DummyValue) Values (null); 

    SET @value = SCOPE_IDENTITY(); 

    DELETE from MySequence where SequenceValue <> @value 

    SELECT @value as Sequence 

    return @value 
END 

Para utilizar la secuencia, tendría que administrar las inserciones en las tablas de destino; probablemente, un desencadenador funcionaría.

Cuestiones relacionadas