2008-09-26 14 views
7

Utilizo varias tablas referenciadas con claves primarias enteras. Ahora quiero cambiar las entradas a GUIDs dejando intactas todas las referencias. ¿Cuál es la forma más fácil de hacerlo?Pasar de ints a GUID como claves principales

¡Gracias!

adición

hago entender el proceso en general, así que necesito consejos más detallados, por ejemplo, cómo llenar nueva columna GUID. Usar el valor predeterminado newid() es correcto, pero ¿qué pasa con las filas ya existentes?

+0

Como ** advertencia ** para futuros lectores: solo aplique uniqueidentifiers (GUID) como claves principales después de _careful_ consideration: la mayoría de las veces es una mala idea. – DdW

Respuesta

11
  • crear una nueva columna para el valor GUID en la tabla maestra. Utilice el tipo de datos uniqueidentifier , haga que no sea nulo con un newid() predeterminado para todas las filas existentes se completarán.
  • Crea nuevas columnas uniqueidentifier en las tablas secundarias.
  • Ejecute las declaraciones de actualización para crear las relaciones de la alianza utilizando las relaciones existentes exisitng para hacer referencia a las entidades.
  • Coloque las columnas int originales.

Además, deje algo de espacio en sus páginas de datos/índice (especifique fillfactor < 100) ya que las guías no son secuenciales, como las columnas int de identidad. Esto significa que las inserciones pueden estar en cualquier parte del rango de datos y causarán divisiones de página si sus páginas están 100% llenas.

4

En primer lugar: Querido Dios ¿por qué?!?!?

En segundo lugar, primero tendrá que agregar la columna GUID a todas sus tablas, luego rellenarlas según el valor int. Una vez hecho esto, puede establecer los GUID en claves principales/externas y luego soltar las columnas int.

para actualizar el valor que usted haría algo como

  1. Establecer los nuevos GUID en la tabla de clave principal
  2. Ejecutar este:

.

UPDATE foreignTable f 
SET f.guidCol = p.guidCol 
FROM primaryTable p 
WHERE p.intCol = f.intCol 
+0

Estoy de acuerdo con Glenn. Me quedaría con enteros para PKs. Usa bigints si necesitas más registros. Si necesita un identificador global, use algo como un URI para una clave secundaria y apéguese a las entradas para PK. –

+0

¿Pero cómo establecer nuevos GUID en la tabla de claves principales? –

+0

2 Alexander Prokofyev: establece todas las columnas PK "guid" por defecto clausule a "newid()". 2 marxidad: Usar Guid en lugar de (big) int es muy útil, si necesita crear un registro en cascada en otro entorno que DB (aplicación de winforms, por ejemplo). – TcKs

2

Sí, estoy con Glenn ... En realidad estaba dudando sobre el desplazamiento de la misma cosa antes de que él lo publicó ....

¿Por qué no quiere un incremento automático int primaria llave separada de tu GUID? es mucho más flexible, y se puede simplemente tener la columna GUID indexados por lo que tiene un buen rendimiento en sus consultas ...


En cuanto a la flexibilidad, me gusta mantener mis identificadores como enteros autoincrement porque entonces el otro elemento digno, aparentemente único y principal, puede cambiar.

Un gran caso de flexibilidad es si usa nombres de usuario como clave principal. Incluso si son únicos, es bueno poder cambiarlos. ¿Qué pasa si los usuarios usan una dirección de correo electrónico como su nombre de usuario? Ser capaz de cambiar el nombre de usuario y no afectar todas sus consultas es una gran ventaja, y sospecho que lo mismo podría ser cierto con sus GUID ...

+0

Tengo una mejor experiencia con el uso de valor especial para PK. Porque entonces no hay problema con el cambio de cualquier valor en el registro (por ejemplo: porque el usuario hizo un error tipográfico). – TcKs

0

Creo que debe hacerlo a mano. O puede escribir alguna utilidad para eso. El escenario debería ser:

  • Duplique las columnas "int" PK/FK con las nuevas columnas "guid".
  • Genera nuevos valores para columnas PK "guid".
  • Actualice los valores en las columnas "guid" FK con valores especificados (los registros se encuentran a través de PK "int").
  • Eliminar referencias (relaciones) con columnas "int" PK/FK.
  • Cree referencias similares (relaciones) con columnas PK/FK "guid".
  • Elimina las columnas "int" PK/FK.
3

Esto es relevante en un sistema que implementa el modelo de computación distribuida . Si se requiere que el sistema conozca la clave primaria en el momento en que persiste la información en el sistema, el uso de una clave principal de autoincremento mantenida por el controlador ONE ralentizará el sistema. En su lugar, necesita un mecanismo como un generador de GUID para crear la clave principal (tenga en cuenta que la verdadera característica de una clave principal es su singularidad). Entonces, puedo escalar con múltiples servicios, cada uno creando su clave principal, independientemente el uno del otro.

Tuve el dudoso privilegio de hacer esto antes y, básicamente, lo que tenía que hacer era exportar toda la maldita base de datos en XML. Luego, tuve una aplicación Java que usa la función nextLong() de java.util.Random para reemplazar la clave principal con sus nuevas claves guid. Después de eso importé todo de nuevo en la base de datos.

Por supuesto, la primera vez que traté de importar los archivos XML, olvidé desactivar la función de número automático del campo de la clave principal, así que aprenda de mis errores. Estoy seguro de que hay mejores formas de hacerlo, pero esta fue una manera rápida y sucia de hacerlo ... y funcionó. En caso de que se lo pregunte, el proyecto era hacer que la aplicación escalara.

0

Es una muy buena elección. Cambié de longs a UUID para una de mis aplicaciones y no me arrepiento. Si usa MS SQL Server, está incluido en el estándar (yo uso postgresql y solo está incluido en el estándar de 8.3 en adelante).

Como se menciona por Glenn Slaven, puede volver a crear UUID de las claves que tiene en sus registros actuales. Tenga en cuenta que no serán únicos, pero de esa manera es fácil mantener intactas las relaciones. Los nuevos registros que cree después de la mudanza serán únicos.

0

¡NO LO HAGA! Empezamos a usar GUID, y ahora casi hemos terminado de mover a INTs como PKs; estamos reteniendo el GUID para fines de registro (y para algunas tablas de, er, "integridad relacional negociable";)), pero el aumento de la velocidad de uso de las entradas ha sido fenomenal.

Esto solo se hizo aparente cuando los recuentos de los números de la tabla se convirtieron en millones, fíjate.

Nuestra mayor insensatez fue el uso de un NEWID() como el PK de nuestra tabla de registro (secuencial). Hubo muchos contratiempos cuando nos dimos cuenta de nuestro error.

+2

¿Quizás indecisos incorect? ¿No tenía un índice agrupado en PK guid en lugar de un FK mejor? Es a menudo un error. – TcKs

Cuestiones relacionadas