2010-11-19 34 views
7

Me preguntaba si alguien conocía una buena manera de crear un ID entero aleatorio único para una clave principal para una tabla. Estoy usando MySQL. El valor debe ser entero.¿Cómo crear ID ID aleatorio único para la clave principal de la tabla?

+2

por qué no sólo 'AUTO_INCREMENT' ? – RobertPitt

+2

Porque quiero usar ese valor para codificar en Base62 y luego usarlo para una identificación en una url. Si aumente automáticamente, podría ser obvio para el usuario cómo se genera el ID de URL. – MindGame

+3

Para evitar su problema de seguridad, puede usar AUTO_INCREMENT e incluir un número creado al azar como un campo. Para obtener su ID de usuario, toma la ID AUTO + ese número aleatorio. Ejecutarlo a través de un hash (SHA128 funcionará bien). Incluso si el número aleatorio es el mismo (lo que en realidad no será), combinándolo con otro número, SHA'ing le dará su ID de usuario. – g19fanatic

Respuesta

5

Si está abierto a sugerencias y puede implementarlo, use UUID. La función UUID() de MySQL devolverá un valor de 36 caracteres que se puede usar para ID.

Si desea usar un número entero, aún así, creo que necesita crear una función getRandID() que usará en la declaración INSERT. Esta función necesita usar la verificación aleatoria de identificadores existentes para devolver uno que no se haya utilizado anteriormente.

Verificar RAND() función para MySQL.

+0

Cómo se asegura de que el valor aleatorio no esté siendo utilizado por otra persona al mismo tiempo. Por ejemplo, las personas A y B obtienen el mismo número aleatorio.Ambos comprueban al mismo tiempo si existe, no lo hace, así que ambos se insertan. Por supuesto, uno falla debido a la restricción de la clave primaria. ¿Qué haces para darle la vuelta a eso? ¿Bloquear mesas? Nunca lo usaste y es un poco incómodo de usarlo. – MindGame

+0

Esa es la belleza de UUID (identificador único universal). Citando Wikipedia: "La intención de los UUID es permitir que los sistemas distribuidos identifiquen información de manera única sin una coordinación central significativa. Por lo tanto, cualquiera puede crear un UUID y usarlo para identificar algo con la confianza razonable de que el identificador nunca será utilizado involuntariamente por nadie De lo contrario, la información etiquetada con UUID puede combinarse luego en una única base de datos sin necesidad de resolver conflictos de nombres. " –

+1

@Tesh Solo repetiría la función en el CATCH cuando surgiera una excepción debido a la restricción UNIQUE y continuaría hasta que pueda insertar una fila con ese Id aleatorio. –

0

Hay una característica AUTO_INCREMENT. Yo usaría eso.

Ver here más ejemplos.

0

AUTO_INCREMENT va a ser su mejor apuesta para esto.

Here son algunos ejemplos.

Si lo necesita, puede ajustar dónde comienza el valor de incremento (de manera predeterminada es 1).

12

En respuesta a:."Porque quiero utilizar ese valor para codificar a Base62 y luego utilizar eso para un id en una URL si i incremento automático, puede ser obvio para el usuario cómo el id url es generado."

Si su objetivo es la seguridad, usar Base62, incluso con un número generado "aleatoriamente" no ayudará.

Una mejor opción sería:

  • No reinventar la rueda - Utilización AUTO_INCREMENT
  • continuación, utilizar una función hash criptográfica + una cadena generada aleatoriamente (oculto en el PP para una URL concreta) para generar la final "id único para esa url"
+1

Gracias por responder. De acuerdo, uso incremento automático y luego uso una función hash criptográfica + una cadena generada aleatoriamente. Pero necesito que mi URL sea corta. Corto como lo hace tinyurl. Al usar criptografía, ¿no obtendré una "identificación única para esa url" que es larga? – MindGame

7

Cómo se generan los unique_ids es una pregunta útil - pero parecen estar haciendo una suposición acerca productiva contador cuando usted gen califícalos!

Mi punto es que no necesita generar estos id únicos al momento de crear sus filas, ya que son esencialmente independientes de los datos que se insertan.

Lo que hago es generar identificaciones únicas para uso futuro, de esa manera puedo tomar mi propio tiempo y garantizar que sean únicas, y no hay que hacer ningún procesamiento en el momento de la inserción.

Por ejemplo, tengo una tabla de pedidos con order_id en ella. Esta identificación se genera sobre la marcha cuando el usuario ingresa la orden, incrementalmente 1,2,3 etc. para siempre. El usuario no necesita ver esta identificación interna.

Luego tengo otra tabla - unique_ids with (order_id, unique_id).Tengo una rutina que se ejecuta todas las noches que precarga esta tabla con suficientes filas unique_id para más que cubrir los pedidos que podrían insertarse en las próximas 24 horas. (Si alguna vez recibo 10000 pedidos en un día, tendré un problema, pero sería un buen problema)

Este enfoque garantiza la exclusividad y elimina cualquier carga de procesamiento de la transacción de inserción y en el lote rutina, donde no afecta al usuario.

1

¿Qué hay de este enfoque (PHP y MySQL):


corto

  1. Generar al azar number para user_id (UNIQUE)
  2. Insertar fila con generada number como user_id
  3. Si inse rted número de filas igual a 0, ir al punto 1

¿Parece pesado? Continúa leyendo


largo:

Tabla:

users (user_id int UNIQUE) 

Código:

<?php 
// values stored in configuration 
$min = 1; 
$max = 1000000; 

$numberOfLoops = 0; 
do { 
    $randomNumber = rand($min, $max); 

    // the very insert 
    $insertedRows = insert_to_table(
     'INSERT INTO foo_table (user_id) VALUES (:number)', 
     array(
      ':number' => $randomNumber 
     )); 

    $numberOfLoops++; 

    // the magic 
    if (!isset($reported) && $numberOfLoops/10 > 0.5) { 
     /** 
     * We can assume that at least 50% of numbers 
     * are already in use, so increment values of 
     * $min and $max in configuration. 
     */ 
     report_this_fact(); 
     $reported = true; 
} while ($insertedRows < 1); 

  1. Al l valores ($min, $max, 0.5) son sólo para explicar y no tienen ningún significado estadístico.
  2. Las funciones insert_to_table y report_this_fact no están compiladas en PHP. Los números también son solo para aclarar propósitos de explicación.
0

my way, tanto para plataformas de 32 bits como de 64 bits. resultado es de 64 bits

function hexstr2decstr($hexstr){ 
    $bigint = gmp_init($hexstr, 16); 
    $bigint_string = gmp_strval($bigint); 
    return $bigint_string; 
} 

function generate_64bitid(){ 
    return substr(md5(uniqid(rand(), true)), 16, 16); 
} 

function dbGetUniqueXXXId(){ 
    for($i = 0; $i < 10; $i++){ 
     $decstr = hexstr2decstr(generate_64bitid()); 

     //check duplicate for mysql.tablexxx 
     if($dup == false){ 
      return $decstr; 
     } 
    } 
    return false; 
} 
0

Puede utilizar un AUTO_INCREMENT para su mesa, sino dar a los usuarios la versión encriptada:

ENCRYPTED_ID: SELECT HEX(AES_ENCRYPT(id, 'my-private-key'));

Identificación: SELECT AES_DECRYPT(UNHEX(encrypted_id), 'my-private-key');

Cuestiones relacionadas