J'ai besoin de créer un identifiant unique pour nos utilisateurs. Je ne veux pas utiliser un identifiant auto_incrimentation, car je ne veux pas que les utilisateurs puissent deviner combien d'utilisateurs nous avons, ou quel est le taux de croissance. P>
Un UUID n'est pas vraiment une option non plus, car les utilisateurs devront repasser l'ID sur un smartphone. P>
Donc, j'espère que je peux réduire la base de données de «brute-forcer» autant que possible de trouver des identifiants inutilisés. Quelle serait une façon intelligente d'y aller? P>
Merci! P>
4 Réponses :
Vous pouvez créer votre enregistrement et mettre à jour le champ après avec une uide aléatoire sur une fonction.
La fonction vérifiera la vérification de l'unicité: pour les éléments existants, vous pouvez exécuter ceci: p> et dans l'instruction insertion que vous avez peut taper ceci: p>
Réponse très complète. "Déterministe" est incorrect dans ce cas cependant :)
C'est aussi une approche de force brute .. Mise en œuvre dans SQL PAS PHP, cependant.
Mais il semble également que cette méthode fera réellement brute une solution jusqu'à ce qu'elle trouve un nombre. Cela ne serait pas très bien évolué; Je pense donc que je préférerais une table de semences comme suggérée par @mchl.
Si l'UID de la colonne a un index, la base de données ne fait pas une "force brute", mais une recherche binaire et une échelle beaucoup mieux. Si l'UID de la colonne a une «contrainte unique», vous n'avez qu'à récupérer l'erreur et essayez avec le numéro aléatoire suivant.
aussi la possibilité que l'extérieur tandis que la boucle fonctionne une seconde fois est très très faible
Créer une liste de numéros uniqe aléatoires (vous pouvez utiliser la plage PHP () CODE> et shuffle () code> fonctions) et l'avoir stocké dans la base de données ou même dans une TXT déposer. Assurez-vous que la liste est suffisamment longue de manière à durer quelque temps.
Ensuite, chaque fois que vous avez besoin d'une nouvelle carte d'identité, affichez simplement la première valeur de la liste. $list = range(0,999999); //list now contains numbers from 0 to 999999
// if you ever need to add more ID's to your list, start at 1000000.
shuffle($list); //now it's randomly ordered
Une extension à ce cas consisterait à mapper l'identifiant généré à l'aide du dictionnaire S / clé pour le rendre vraiment facile à taper (32 bits signifierait 3 mots courts) FAQS.ORG/RFCS/RFC1760.HTML a le dictionnaire.
Solution fraîche et simple, mais la table ne sera pas chevauchée. Qu'est-ce qui se passe sur deux ou plusieurs demandes d'insertion en même temps?
Si vous vous inquiétez de cela, les transactions sont là pour vous.
transactions en combinaison avec des contraintes.
Cela tourne difficile si vous avez près d'un milliard d'identifiants. Par exemple, le fichier pondérera GB.
Si je vous comprends correctement, vous essayez de laisser les utilisateurs choisir leur propre identifiant unique d'une table dans laquelle il n'y a pas déjà d'utilisateur enregistré. Si tel est le cas, je disposerais de ma table d'utilisateurs avec des colonnes ID utilisateurId et Nom d'utilisateur. Puis renvoyez les identifiants où l'utilisateur est toujours null.
$query = "SELECT userID, userName FROM User WHERE userName='' AND userID=$userID";
$result=mysql_query($query);
if ($result) {
echo "number is available";
$insert = "UPDATE User
SET userName=$userName
WHERE userID=$userID";
$inserted=mysql_query($insert);
if ($inserted) {
echo "you have been inserted as: ";
echo $userID;
echo $userName;;
}
}
OK, je vais le donner un autre essai. Vos objectifs sont:
Pour toujours avoir de bonnes performances dans votre base de données, vous devez conserver un entier standard auto_incrimentation pour votre PK. Notez que Innodb commande les lignes basées sur la PK (voir " InnoDB Index clustered "), donc si vous utilisez une sorte de hachage magique en tant que PK, vous vous retrouverez avec beaucoup de réorganisation de votre indice en cluster, donnant de mauvaises performances d'écriture. P>
Je suggère d'utiliser un algorithme de chiffrement (cryptage, pas de hachage) pour crypter et décrypter l'ID que vous voulez masquer. De plus, pour la meilleure obfuscation, vous souhaitez utiliser une longueur minimale pour la chaîne résultante. La chaîne résultante doit être toujours utilisable. Vous devez donc utiliser quelque chose comme base64 pour le présenter à l'utilisateur informatique lisible. P>
Essayez cet exemple de cryptage: P>
10000 -> 1RXK468NYes -> 10000 10001 -> QdEov5mjMPA -> 10001 10002 -> 2gsgzWJgD+8 -> 10002 10003 -> 2zwPwhqr9HI -> 10003 10004 -> Xq+kDh1UFuM -> 10004 10005 -> wfwv6TrW9xY -> 10005 10006 -> 1Lck1L0HJ/U -> 10006 10007 -> v+3YY2zfL1A -> 10007 10008 -> 5AmGlqD8byM -> 10008 10009 -> pZBIpPnKXHU -> 10009 10010 -> CAeWdKGkk8c -> 10010 10011 -> fYddnLOSK6U -> 10011 10012 -> na8Ry0erHv8 -> 10012 10013 -> zxNj+ZJVMBY -> 10013 10014 -> gWJWC9VulZc -> 10014 10015 -> 5pR9B79eM/E -> 10015 10016 -> MQtpBhpzHRA -> 10016 10017 -> dW+3nejBEIg -> 10017 10018 -> znB/feM6104 -> 10018 10019 -> RtdRwwRyEcs -> 10019 10020 -> 4cW/OWT140E -> 10020 10021 -> dIvK9VjOevg -> 10021 10022 -> QxLdfrucc/Y -> 10022 10023 -> M0KN3sX10Gs -> 10023 10024 -> 827yFJyDCG4 -> 10024 10025 -> JF/VRj92qL8 -> 10025 10026 -> IXTvn/SCzek -> 10026 10027 -> L4nFwvhgwX8 -> 10027 10028 -> z0lve9nhgDA -> 10028 10029 -> m/UBgZzfIXo -> 10029 10030 -> IfWcrLKTHXk -> 10030 10031 -> n/jPFwKR/9A -> 10031 10032 -> j1mm2kbeWl0 -> 10032 10033 -> cm7mOQMVa6k -> 10033 10034 -> jCUuweEyRME -> 10034 10035 -> LDaMcOWKxjg -> 10035 10036 -> Zcrd5XzhhIk -> 10036 10037 -> j0Yg/fCjyAA -> 10037 10038 -> /LmlvRHmmmg -> 10038 10039 -> t0juuzGSKs4 -> 10039 10040 -> 9CoRCVXaak4 -> 10040 10041 -> tFmImR4j0JM -> 10041 10042 -> nI3Thy51hLg -> 10042 10043 -> mTCJh0/h2mE -> 10043 10044 -> S196xdyb3Os -> 10044 10045 -> ItOyUp+J4Q4 -> 10045 10046 -> DL87SidiOLM -> 10046 10047 -> d+Nw3xBqV44 -> 10047 10048 -> 3YzVelaC4uI -> 10048 10049 -> fAUJVOl6PaU -> 10049
J'aime cette solution, mais la simplicité d'une table de semences m'appelle. Je n'ai pas vraiment besoin de décryptage, car je vais simplement stocker la valeur dans un champ.
@Evert, je voulais juste démontrer une approche évolutive. La simplicité de la table de semences m'appelle aussi. Mais je n'aime pas la nécessité de "re-graine" lorsque la limite supérieure est atteinte. La solution de cryptage est une obfuscation complète 100% et cache également la gamme d'identifiants.
Oui, mais pour ce que ça vaut la peine. Je vous ai fait upvote :) C'est une solution très intelligente.
+ pour une belle fonction de cryptage :)
FWIW: Peut-être qu'il serait préférable d'utiliser la base32 au lieu de la base64. Cela élimine les problèmes de manipulation des humains: pas de sensibilité de cas, aucun caractère ambigieux (0 vs o, 1 vs L), pas de caractères spéciaux, ... mais cela rendra la corde beaucoup plus longue.
Cet article pourrait vous aider à plus que je pense. Stackoverflow.com/questions/307486/short-unique-id-in-php
«La typabilité humaine» se développera si vous utilisez le motif ([Consontant] [vocal]) * et uniquement de petites lettres.
Pourquoi ne laissez-vous pas l'utilisateur choisir son propre nom d'utilisateur, qui est votre identifiant, ce que vous recherchez? Votre utilisateur peut avoir également d'autres applications sur smartphone, vous le dérangeriez de vous souvenir d'un autre identifiant / mot de passe. Un UUID pourrait être utilisé pour des demandes de repos, car vous ne voudriez pas utiliser l'ID principal de toute communication au client utilisateur ou aux partenaires.