2010-12-10 34 views
5

Je dois avoir des ID de texte dans mon application. Par exemple, nous avons un jeu de caractères azAZ09 acceptable, et une plage autorisée d'identifiants [aaa] - [cZ9]. Le premier identifiant généré serait aaa, puis aab, aac, aad e.t.c.MySQL: incrémentation de l'ID de texte dans la base de données

Comment peut-on retourner l'ID & incrémenter la limite inférieure en mode transaction? (Pour autant qu'il y ait des centaines de requêtes simultanées et que toutes aient des résultats corrects)

Pour réduire la charge, je suppose qu'il est possible de définir, disons, 20 plages distinctes, et de renvoyer l'identifiant de la plage aléatoire - cela devrait réduire la contention, mais ce n'est pas clair comment faire une seule opération en premier lieu.

Veuillez également noter que le nombre d'ID dans la plage peut dépasser 2^32.

Une autre idée est d'avoir des plages d'entiers de 64 bits, et de convertir un id entier-> char dans le code logiciel, où cela pourrait être fait de manière non-cryptée.

Des idées?

+0

Vous ne pouvez pas simplement utiliser un type entier et le convertir en cas de besoin? – PeeHaa

+0

Oui, je peux. Cela ne résout pas encore la tâche - j'ai toujours besoin d'un support de gamme autorisé - ce qui signifie que l'auto-incrémentation habituelle ne fera pas l'affaire. – BarsMonster

Répondre

1

Je demanderais une autre question de faire le même problème plus facile à résoudre: comment puis-je utiliser les fonctionnalités de m y base de données pour mettre en œuvre mes besoins. Regardez ce que votre base de données offre en termes de gestion des séquences. Certains d'entre eux peuvent gérer quelque chose comme ça. Si votre base de données ne le fait pas, je regarderais "piggy backing" sur ses touches numériques normales, puisqu'elles résolvent déjà tous les problèmes que vous anticipez. Ce que je veux dire est ceci: Laissez la base de données distribuer les clés numériques comme elle le fait normalement, en commençant à 0. Ensuite, écrivez deux fonctions pour convertir entre ces nombres et vos touches de texte. Vous avez une certaine flexibilité ici: vous pouvez implémenter cette fonction dans la base de données (en utilisant une deuxième colonne, des triggers, ou une fonction de base de données cool), ou sur votre couche serveur, comme Java. Ce ne sera pas si compliqué. En fin de compte, ce sont tous des bits de toute façon ... votre clé de texte est juste une façon différente de découper les bits.

Bonne chance!

+0

Brillante idée de départ, et nécessite seulement 1 table, maintenant je vois la solution parfaite :-) – BarsMonster

2

Une solution basée sur long (bigint) numéros, avec caractères à nombre et conversions des nombres en caractères effectuées dans le logiciel, ayant - disons - 32 différents gammes,

  • création de 32 tables range0 .. range31 pour abaisser la charge (une table unique avec 32 champs de distance aurait sa rangée verrouillée chaque fois qu'un intervalle est écrite)

  • à partir des plages en réglant la auto_increment à une valeur très élevée sur 64 bits - peut-être 63 si vous voulez éviter le problème de signe dans votre application. Idéalement, la valeur de la plage sur 5 bits, de 0 à 31. 1 signe de bit + 5 bits de plage = 6 bits. Votre compteur sera de 1 à (2^58-1) ou 10^17 ... cela devrait suffire.

  • dans le logiciel le numéro de série est sélectionnée au hasard, et le nom de la table de requête est construit en conséquence range i où i va de 0 à 31.

Les créer des tables commandes seraient quelque chose comme, par exemple en Java

String table; 
    String query; 
    long increment; 

    for (long i=0 ; i<32 ; i++) { 
    table = "range"+i; 
    increment = (i<<58) + 1; 
    query = "CREATE TABLE "+table+" (v bigint auto_increment primary key) auto_increment="+increment; 

    do_query(query); 
    } 
+0

Hmm ... Intéressant, mais comment vais-je gérer les plages qui ont disons 100 numéros? – BarsMonster

+0

@BarsMonster Au lieu de 32, ce serait 128, 2^7 (0..127), '(i << 58)' serait '(i << 56)' (toujours environ 10^16 valeurs possibles). –

+0

Bien sûr, vous pourriez utiliser une seule table ... (remplacer 'i <32' par' i <1' :-) - l'idée derrière la complexité de l'auto_increment 2^x était de réduire les accès simultanés à la même auto table incrémentée, et donc la fréquence * locks *. De cette façon, vous avez des clés multiples, bien que uniques. –