Frage

Hallo ich brauche 9-stellige eindeutige Kontonummern zu generieren. Hier ist mein Pseudo-Code:

function generateAccNo()

    generate an account number between 100,000,000 and 999,999,999

    if the account number already exists in the DB 
        call generateAccNo()    /* recursive call */
    else
        return new accout number
    end if

end function

Die Funktion scheint gut zu funktionieren, aber ich über den rekursiven Aufruf ein wenig besorgt bin.

Wird diese Speicherverluste verursachen (PHP 5 unter Apache)?

Ist dies ein akzeptabler Weg, um dieses Problem zu lösen?

Vielen Dank für Ihre Eingabe.

War es hilfreich?

Lösung

Sie erkennen dies könnte sehr gut einen Stapelüberlauf verursachen, nicht wahr? Da die Zahl der customesr zunimmt, nimmt die Wahrscheinlichkeit kein eine akzeptablen Kontonummer erhöht zu finden.

Auch, warum kannst du nicht einfach tun sequenzielle Kontonummern und erhöhen nur um eins jedes Mal? Mit diesem Ansatz würden Sie nur den max id derzeit in der Datenbank gelesen haben und sie nur erhöhen.

Leider so stumpf sein, aber Ihre Lösung ist eine schreckliche Art und Weise, das Problem zu lösen. Es wird jede Menge Speicher verwenden (wie der Stapel möglicherweise unendlich wächst) und es wird macht Tonnen von teueren Anrufen auf die Datenbank.

Sie sollten wirklich einen anderen Ansatz berücksichtigen:
Ich empfehle nur die Kundennummer erhöht wird jedes Mal, wenn ein Kunden erstellen. In der Tat, wenn Sie Ihre db richtig eingerichtet (mit Autoinkrement auf der id-Spalte), werden Sie nicht einmal die ID zu setzen haben. Die ID wird für Sie eingestellt werden, wenn Sie einen neuen Kunden einzufügen.

Andere Tipps

Ich glaube wirklich nicht, es kommt auf Rekursion vs. Looping, beide Probleme anfällig sind als die Datenmenge wächst, und wenn die Erzeugung von Zufallszahlen nicht korrekt implementiert ist. Zwei Ideen in den Sinn kommen:

. GUID

Wenn eine wirklich einzigartige ID mit so wenig Aufwand wie möglich erforderlich ist, sollten Sie eine GUID, Ihre DB wird wahrscheinlich in der Lage sein, den Sie zuweisen auf auf dem Einsatz, wenn nicht einen in Code erstellen. Es wird garantiert, einzigartig sein, obwohl es nicht sehr benutzerfreundlich ist. in Kombination mit einem sequentiellen AccountRecordId durch die DB auf dem Einsatz erzeugte jedoch würden Sie eine feste Kombination

. Composite-Key: Random + Sequential

Ein Weg, um alle Bedürfnisse zu erfüllen, auch wenn an der Oberfläche es ein bisschen kludgy fühlt, ist ein Verbundkontonummer von einem sequentiellen db Schlüssel von 5 Ziffern zu erstellen (oder mehr) und dann weitere 5 Ziffern des Zufalls. Wenn die Zufallszahl dupliziert wurde wäre es keine Rolle, wie die sequentielle ID die Einzigartigkeit des gesamten Kontonummer garantieren würde

Es gibt keine Notwendigkeit, hier einen rekursiven Aufruf zu verwenden. Führen Sie eine einfache while-Schleife in der Funktionsprüfung gegen Nicht-Existenz als bedingt, z.

function generateAccNo()

    generate an account number between 100,000,000 and 999,999,999

    while ( the account number already exists in the DB ) {
         generate new account number;
    }
    return new account number

end function

Randomly Erzeugen-and-Test ist ein suboptimaler Ansatz, um einzigartige Kontonummern zu erzeugen, obwohl, wenn dieser Code für etwas anderes ist als ein Spielzeug.

Es scheint in Ordnung, aber ich glaube, Sie irgendeine Art von Chip Zustand benötigen, wie oft werden Sie diesen Lauf lassen, bevor Sie aufgeben?

Ich weiß, dass dies mit der großen Zahl Bereich unwahrscheinlich scheint, könnte aber etwas schief gehen, dass Sie nur Tropfen zurück zum vorherigen Aufruf, der sich wieder rufen, Ad-nauseum.

Die Erzeugung Kontonummern der Reihe nach ist ein Sicherheitsrisiko dar - Sie sollten einen anderen Algorithmus finden, es zu tun

.

Alternativ können Sie eine separate Tabelle einen Puffer erzeugt, bekannt halten enthält eindeutige Kontonummern sein. Diese Tabelle sollte eine automatisch inkrementierende Ganzzahl-ID hat. Wenn Sie eine Kontonummer möchten, ziehen Sie einfach den Datensatz mit dem niedrigsten Index in dem Puffer und entfernen Sie sie aus dieser Tabelle. Haben Sie etwas Prozess, der regelmäßig läuft, die den Puffer auffüllt und stellt sicher, dass es Kapazität >> normalen Gebrauch hat. Der Vorteil ist, dass die Menge der Zeit vom Endbenutzer erfahren wird eine Kontonummer ausgegeben zu schaffen im Wesentlichen konstant sein.

Auch soll ich beachten Sie, dass der Verarbeitungsaufwand oder Risiken von Rekursion oder Iteration, das eigentliche Problem Determinismus ist und der Aufwand für Datenbankabfragen zu wiederholen. Ich mag TheZenker-Lösung von Zufall + sequentiell. Garantiert eine eindeutige ID zu erzeugen, ohne unnötigen Aufwand hinzufügen.

Sie müssen keine Rekursion hier verwenden. Eine einfache Schleife würde genauso schnell sein und weniger Stapelspeicherplatz verbrauchen.

Sie können es in einer while-Schleife setzen:

function generateAccNo()

    while (true) {    

      generate an account number between 100,000,000 and 999,999,999

      if the account number already exists in the DB 
          /* do nothing */
      else
          return new accout number
      end if
    }

end function

Warum nicht:

lock_db
do
    account_num <= generate number
while account_num in db

put row with account_num in db

unlock_db

Warum haben nicht die Datenbank damit umgehen? IN SQL Server, können Sie einfach eine Identitätsspalte, die bei 100000000 beginnt Oder Sie könnten SQL in jeder db verwenden, die Sie haben. Nehmen Sie einfach die max-ID plus 1.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top