Zufallszahl als Primärschlussl

Hallo liebe Datenbankfreunde,

wieder mal die Maribel mit einem Problem, wird nicht das letzte sein :wink:

Für meine Plakettennummern, die ja Primärschlüssel sind, würde ich gern Zufallszahlen eines bestimmten Bereiches einsetzen. Und zwar aus folgenden Gründen:

  1. Um einen gewissen Fälschungsschutz zu erreichen (durch zufällige Nummerierung)
  2. Sind diese Plaketten ja nur ein Jahr gültig, so könnte man diese ja nach 2 Jahren z.B. aus der DB werfen und die Nummern würden wieder frei, mit der fortlaufenden Nummerierung würde der Bereich nicht wieder frei gegeben, oder?

Unter Access war das einfach, aber unter MySQL und PHP finde ich einfach die Methode nicht oder sie bleibt mir irgendwie verborgen :frowning:

Nach 12 Stunden quer durch Google habe ich viereckige Augen und bitte Euch um Hilfe. Weiß einer einen gangbaren Weg?

Gruß Maribel

Hi Maribel,
möchtest du die Zufallszahl mit der Insert-Anweisung übergeben, also eine mysql-Funktion

$selectStatement = „INSERT INTO tabelle(Feld1, Feld2…) VALUES (Zufallszahl, Wert2…)“;

oder schon vorher in php erzeugen und dann die php-Variable übergeben?

$varZufallszahl = 42;
$selectStatement = „INSERT INTO tabelle(Feld1, Feld2…) VALUES (“ . $varZufallszahl . „, Wert2…)“;

Für letzteres gibts in php die Funktion rand:

$varZufallszahl = rand(1,100);

erzeugt in dem Fall eine Ganzzahl zwischen 1 und 100 (http://www.schattenbaum.net/php/random.php)

Auch mysql hat eine Funktion RAND(): http://dev.mysql.com/doc/refman/5.1/de/mathematical-…

ob die mit einem Insert-Statement funktioniert, habe ich nicht ausprobiert.

War es das, was du gesucht hast?

MfG
Julia

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Julia,

wenn es so einfach wäre, leider ist es das nicht, wie man dies Zahl erzeugt hatte ich schon getestet, leider darf sie ja nie doppelt vorkommen als Primärschlüssel und da fangen ja die Probleme erst an.

  • also Zufallszahl erzeugen (3x hintereinander, da ich 8 stellige zahlen brauche, das verfahren dazu ist mir auch noch nicht genau klar) dann die DB abfragen ob die Zahl schon vorhanden ist, wenn nicht ist es der neue Primärschlüssel für den neuen Datensatz, wenn ja, das ganze von vorne.

Am Ende muss dann eine Zahl rauskommen die im Bereich 00000001 und 99999999 liegt. in Access war das so einfach *heul*.

Gruss Maribel

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Maribel,

Zufallszahlen in einer unique-Spalte zu verwenden ist schlichtweg zu Unperformant um es sinnvoll zu verwenden.
Worst Case: es ist von 8 Millionen moeglichen Eintraegen nur noch einer frei. Um den letzten freien Key zu finden muesste der Datenbankserver jetzt im unguenstigsten Fall 8000000 mal versuchen einen Random-Key zu testen (evtl auftretende doppelte Versuche mal nicht mitgezaehlt)

Mir sind 2 Moeglichkeiten eingefallen dies zu loesen:

1.) Du verwendest nicht 8 Stellen sondern benutzt eine fortlaufende ID und eine angehaengte Zufallszahl mit fester Laenge (die in der Datenbank zu der ID gespeichert ist und zusammen mit der ID validiert wird)
Beispiel: die ID ist 123, die Zufallszahl ist 9876, die ausgegebene Nummer lautet dann 1239876.

Bei der Validierung splittest du die Zahl (letzten 4 Stellen = Zufallszahl, alles davor ist die ID), selektierst die ID aus der Datenbank und vergleichst dann ob die zugehoerige Zufallszahl zu der ID gehoert.

Um das Problem mit den Jahreszahlen zu loesen koennte man auch noch die Jahreszahl mit benutzen.

2.) man hat eine Tabelle mit (anfangs) fortlaufenden Zahlen (also von 1 bis zur max. moeglichen Zahl). Bei jedem INSERT suchst du dir nun eine Zahl aus der Tabelle aus (SELECT zahl FROM verfuegbareids ORDER BY RAND() LIMIT 0,1) benutzt diese und loeschst diese anschliessend aus der Tabelle.
Hier muss man bei Multi-User-Umgebungen allerdings extra darauf achten das keine Dopplungen auftreten koennen. Ausserdem wirst du bei grossen Tabellen das oben genannte Select-Statement warscheinlich optimieren muessen bzw gegen ein anderes austauschen

Ich hoffe da war evtl ein Denkanstoss mit dabei

Gruesse
Stefan

Vielen Dank Stefan,

damit hast Du mir ein großes Problem von den Schultern genommen und die Perfomancefrage war eigentlich genau der Punkt, der mir auch Gedanken gemacht hat.

Deine vorgeschlagene Lösung umgeht alle Probleme.

Solche Löschaktionen kann man ja in Zeiten legen, wo die Datenbank recht wenig genutzt wird, das würde dann am wenigsten stören.

Vielen Dank nochmal
Maribel

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Ich meinte damit eigentlich nicht das das Loeschen optimiert werden muss sondern eher das Selektieren :wink: