PHP/MySQL – Beste Möglichkeit, eindeutige zufällige Zeichenfolgen zu erstellen?

Lesezeit: 5 Minuten

Benutzer-Avatar
John

Wie erstelle ich eine zufällige eindeutige Zeichenfolge in MySQL?

Wenn ich eine zufällige Zeichenfolge in PHP erstellen muss, verwende ich diese Funktion:

public function generateString($length)
{   
    $charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    for($i=0; $i<$length; $i++) 
        $key .= $charset[(mt_rand(0,(strlen($charset)-1)))]; 

    return $key;
}

Dann würde ich den generierten String nehmen und in einer MySQL-Datenbank speichern.

Was ist der beste Weg, um sicherzustellen, dass die generierte zufällige Zeichenfolge für alle anderen zufälligen Zeichenfolgen, die für andere Einträge in der Datenbank erstellt wurden, eindeutig ist?

Vielleicht so etwas?

while(++$i < 100)
{
  //query db with random key to see if there is a match

  //if no match found break out of loop
  break;

}

Dies scheint chaotisch und lang zu sein, und ich könnte möglicherweise mehrmals auf die Datenbank zugreifen. Wie kann ich schnell sicher sein, dass meine neue zufällige Zeichenfolge eindeutig ist?

  • mögliches Duplikat von Short unique id in php

    – Markus Biek

    25. Oktober 2011 um 17:36 Uhr

Warum nicht einfach die integrierten Funktionen zum Generieren eindeutiger Kennungen verwenden? Auf diese Weise müssten Sie sich keine Gedanken über Duplikate machen.

Sowohl PHP als auch MySQL haben ihre eigenen.

PHP: uniqid()

MySQL: UUID()

  • Standardmäßig gibt uniquid 13 Zeichen aus, ich brauche 10. Wenn ich also die letzten 3 abschneide, besteht dann nicht die Möglichkeit von Duplikaten?

    – John

    25. Oktober 2011 um 17:33 Uhr

  • Warum müssen es 10 Zeichen sein?

    – Markus Biek

    25. Oktober 2011 um 17:36 Uhr

  • Auf eine andere Anmerkung hat diese Frage einige gute Antworten. stackoverflow.com/questions/307486/short-unique-id-in-php

    – Markus Biek

    25. Oktober 2011 um 17:36 Uhr

  • Es ist eine Anforderung in der Web-App, die ich baue.

    – John

    25. Oktober 2011 um 17:39 Uhr

  • Dann denke ich, dass Sie Ihre eigene Lösung rollen und manuell nach Duplikaten suchen.

    – Markus Biek

    25. Oktober 2011 um 17:55 Uhr

Benutzer-Avatar
Salmann A

Angenommen 10 Zeichen aus dem Zeichensatz a-z, A-Z, 0-9 bedeutet, es gibt (26 + 26 + 10)10 = 8,39299366 × 1017 mögliche Kombinationen. Um die Wahrscheinlichkeit einer Kollision zu berechnen … nur 1/x der oben genannten Zahl. Ich würde mir also keine Sorgen machen, zweimal die gleiche Saite zu bekommen. Selbst wenn ich dieselbe Zeichenfolge erneut erhalte, führe ich die Funktion einfach erneut in einer Schleife aus, wobei die einzige Beendigungsbedingung darin besteht, dass eine eindeutige Zeichenfolge gefunden wird.

  • Ihre Kollisionswahrscheinlichkeit ist nicht ganz korrekt – Sie berechnen eine 1: 1-Kollision, nicht für eine Sammlung. Bei kleinen Sammlungen ist die Wahrscheinlichkeit einer Kollision ungefähr n(n-1)/N wo n ist die Größe der Sammlung, und N ist dein 8.329×10^17. Die Schlussfolgerung daraus ist, dass Ihre Kollisionswahrscheinlichkeit bei ungefähr nicht zu vernachlässigen ist sqrt(N) – das ist 10 ^ 8. Wenn Sie also viele (aber nicht völlig unangemessen große Datenmengen) an Daten haben, kann es zu einer Kollision kommen. Die beste Lösung in diesem Fall ist, die Schlüssellänge einfach etwas zu erhöhen oder eine Überprüfung durchzuführen, bevor Sie den Wert verwenden.

    – Michael Anderson

    4. April 2012 um 12:58 Uhr

  • @Michael: Ich denke, da ich bereits eine Million eindeutige Zeichenfolgen habe, ist die Wahrscheinlichkeit einer Kollision immer noch eins zu einer Billion (1000000/62 ^ 10).

    – Salmann A

    5. April 2012 um 8:57 Uhr

  • Ich stimme zu, dass die Wahrscheinlichkeit einer Kollision beim Hinzufügen einer Zeichenfolge 1M/(10^17) beträgt, da Sie bereits 1M eindeutige Zeichenfolgen haben. Aber Sie mussten dies 1 Million Mal tun. Das bedeutet, dass Ihre Gesamtwahrscheinlichkeit einer Kollision (ungefähr) 1M x (1M/(10^17)).

    – Michael Anderson

    5. April 2012 um 9:08 Uhr

  • @SalmanA Würden Sie einen maximalen Wiederholungsparameter setzen? ZB höchstens ausprobieren 1000 mal die nummer generieren? Oder würden Sie Ihren Code in eine Endlosschleife versetzen?

    – Tonix

    4. Mai 2020 um 14:24 Uhr

  • Ich würde es in eine Endlosschleife stecken und eine Ausnahme auslösen, wenn die Schleife 1000 Mal ausgeführt wird … oder sogar 3 Mal.

    – Salmann A

    19. Mai 2020 um 17:47 Uhr

Benutzer-Avatar
rudyrockstar

SET rand_str = SUBSTRING(MD5(NOW()),1,$LENGTH); — Wobei LENGTH 1 bis 32 gemäß MD5 ist

Einige Beispiele sind unten:

SET rand_str = SUBSTRING(MD5(NOW()),1,5); — 5 Zeichenkette

SET rand_str = SUBSTRING(MD5(NOW()),1,15); — Zeichenfolge mit 15 Zeichen

Ich würde die Spalte dieser ID in Ihrer DB eindeutig machen. Dann können Sie so etwas tun, um sich vor Kollisionen zu schützen:

    $row_count = 0;
    while ($row_count == 0) {
        error_reporting(0);
        $id_string = substr(uniqid(), 0, 10);

        $sql = "UPDATE <table> SET unique_id = :unique_id WHERE <something true>";
        $query = $this->db->prepare($sql);
        $query->execute(array(':unique_id' => $unique_id));
        $row_count = $query->rowCount();
    }

Sicher, es kann sein, dass Sie die Abfrage mehr als einmal versuchen müssen, aber auf diese Weise wissen Sie, dass sie in Ihrer DB garantiert eindeutig ist. Die Zeile error_reporting(0) dient dazu, eventuell eingeschaltete Warnungen zu unterdrücken. uniqid() von PHP ist auch nicht das einzigartigste Generieren, das es gibt, aber Sie können es leicht gegen Ihr eigenes austauschen oder einfach hier und da potenzielle Kollisionen erleiden.

Werfen Sie einen Blick auf die Eindeutig Funktion und die pecl uuid-Erweiterung. Beide können als Grundlage für die Generierung von Guids verwendet werden, wenn Sie jedoch planen, einen Cluster zu haben, sollten Sie sicherstellen, dass Sie etwas Extras haben, das sicherstellt, dass zwei Server nicht dieselbe ID generieren. Um dieses Problem zu beheben, reicht es aus, eine Konfiguration pro Server zu haben, die der ID ein Präfix oder Suffix hinzufügt.

Benutzer-Avatar
Gemeinschaft

Glücklicherweise haben Datenbanken bereits die Möglichkeit, eindeutige IDs (numerisch) zu erstellen – ich schlage den von uns gewählten Ansatz vor, der darin besteht, eine bidirektionale Konvertierung zwischen einer sanft ansteigenden numerischen ID und einer alphanumerischen ID zu erstellen. Wenn es bidirektional ist, wird sichergestellt, dass die alphanumerischen “zufälligen” Versionen auch eindeutig sind, ohne dass sie explizit getestet werden müssen. Tatsächlich speichere ich immer nur die numerische Version in der Datenbank (da Sie sie kostenlos mit einer SERIAL-Spalte erhalten) und drucke immer nur die Alpha-Version.

Dieses Beispiel generiert 7-Byte-IDs, aber der Ansatz kann trivial angepasst werden, um fast allen Umständen gerecht zu werden.

Siehe: Wie generiere ich eine eindeutige ID in MySQL?

Ich verwende normalerweise:

SELECT LEFT(MD5(id), 8)

Varianten nach Bedarf:

SELECT LEFT(UUID(), 8)

SELECT LEFT(MD5(RAND()), 8)

1055660cookie-checkPHP/MySQL – Beste Möglichkeit, eindeutige zufällige Zeichenfolgen zu erstellen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy