2011-09-27 10 views
5

¿Existe alguna manera de crear una tabla en MySql que tenga un campo ID automático, pero la ID no es secuencial? Por ejemplo, una identificación aleatoria o pseudoaleatoria. He encontrado soluciones que sugieren generar una ID e intentar insertarla hasta que se encuentre una ID no utilizada (generating an sequential five digit alphanumerical ID). pero no se puede hacer nada directamente en la definición de la tabla, o un truco más simple.Tabla MySql con ID no secuencial

Respuesta

11

MySQL tiene una función nativa UUID() que generará un identificador único global:

mysql> SELECT UUID(); 
    -> '6ccd780c-baba-1026-9564-0040f4311e29' 

Puede almacenar su producción en una columna CHAR(36).

INSERT INTO table (`uuid`, `col1`, `col2`) VALUES (UUID(), 'someval', 'someval'); 

Según la documentación embargo,

Aunque los valores UUID() están destinados a ser único, que no son necesariamente imposible de adivinar o impredecible. Si se requiere imprevisibilidad, los valores de UUID se deben generar de otra manera.

Adición Otra opción es UUID_SHORT() de 64 bits unsigned INT en lugar de un campo de caracteres.

mysql> SELECT UUID_SHORT(); 
    -> 92395783831158784 
2

¿Funcionaría una clave compuesta? Un campo estándar auto_increment estándar. Inserta su nuevo registro, recupera su nueva ID, luego copia esa ID con un salt y actualiza el registro con ese valor hash.

Si hace esto dentro de una transacción, la versión en curso del registro sin el hash nunca será visible hasta que se genere el hash. Y suponiendo que haya realizado una salazón adecuada, el valor hash resultante será para todos los efectos "aleatorio".

Tenga en cuenta que no puede hacer esto en un solo paso, ya que el valor de last_insert_id() en mysql no se actualiza con la nueva identificación hasta que se escribe realmente el registro. El valor recuperado durante la etapa de análisis de inserción real sería cualquier ID que se haya insertado ANTES de este.

1

El único valor predeterminado generado automáticamente en la definición de tabla permitida sería autoincrement (MySQL Guide).

Usted debe poder write a trigger para automatizar este proceso, tal vez a través de la función UUID como sugirió Michael.

+0

desde el primer comentario de su enlace CREAR sdata_insert gatillo antes INSERTAR EN alguna_tabla PARA CADA FILA COMENZAR SET NEW.guid = UUID(); END –

3

Has solicitado que un truco, se puede usar un identificador de auto_incremented común y "falso" que multiplicando con un gran primer (y luego en módulo 2^32): los valores

CREATE TABLE AutoIncPrime 
(id int unsigned auto_increment primary key 
) ; 

Insertar, desde 1 a 10:

INSERT INTO AutoIncPrime 
VALUES(),(),(),(),(),(),(),(),(),() ; 

SELECT * FROM AutoIncPrime ; 

de salida:

id 
--- 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

falso el id, con una vista:

CREATE VIEW AutoIncPrime_v AS 
    SELECT 
     ((id*1798672429) & 0xFFFFFFFF) 
      AS FakeUUID 
    FROM AutoIncPrime ; 

Le permite ver nuestras "UUID":

SELECT * FROM AutoIncPrime_v ; 

Salida:

FakeUUID 
---------- 
1798672429 
3597344858 
1101049991 
2899722420 
403427553 
2202099982 
4000772411 
1504477544 
3303149973 
806855106 

Incluso se puede hacer que parezca más al azar con (más complicada mezcla bits) :

CREATE VIEW AutoIncPrime_v2 AS 
    SELECT 
     ( (((id*1798672429) & 0x55555555) << 1) 
      | (((id*1798672429) & 0xAAAAAAAA) >> 1) 
     ) 
     AS FakeUUID 
    FROM AutoIncPrime ; 

SELECT * FROM AutoIncPrime_v2 ; 

FakeUUID 
---------- 
2537185310 
3918991525 
2186309707 
1558806648 
604496082 
1132630541 
3719950903 
2791064212 
3369149034 
808145601 

El truco es que todavía tiene una identificación secuencial en la tabla, que puede usar para unirse a otras tablas. Simplemente no se lo muestra a los usuarios, sino que solo muestra el falso.

Si la tabla es grande y los cálculos lentos, puede agregar otra columna en la tabla y almacenar el valor de FakeUUID allí con un disparador INSERTAR.

+0

genial !!! He pensado en este método, pero con las peores funciones (más complejas y no mysql), así que me das un puntero. Pero a) No puedo ver el camino inverso al ID verdadero (sin insertarlo con un disparador como dijiste) ¿puedes publicar el reverso de estas funciones tan bonitas? yb) ¿qué hay de la singularidad de los ID generados (en un rango dado, por supuesto)? No puedo calcular cuál es este rango para estas funciones, relacionadas con la máscara seleccionada y el cebado. realmente gracias, y disculpen mi inglés –

+0

Intentaré escribir las funciones inversas esta noche. La unicidad está garantizada, si usa un primo, como '1798672429' :) –

Cuestiones relacionadas