Ein guter Algorithmus zum Erzeugen einer Bestellnummer

8

So wie ich es mag, GUIDs als eindeutige Kennungen in meinem System zu verwenden, ist es nicht sehr benutzerfreundlich für Felder wie eine Bestellnummer, wo ein Kunde diese möglicherweise zu einem Kundendienstmitarbeiter wiederholen muss.

Was ist ein guter Algorithmus, der verwendet wird, um eine Bestellnummer zu erzeugen, so dass sie lautet:

  • Einzigartig
  • Nicht sequentiell (rein für Optik)
  • Nur numerische Werte (damit es einfach über das Telefon in eine CSR eingelesen oder eingegeben werden kann)
  • & lt; 10 Ziffern
  • Kann in der mittleren Ebene generiert werden, ohne einen Umlauf in die Datenbank durchzuführen.

UPDATE (12/05/2009) Nachdem wir jede der Antworten sorgfältig geprüft hatten, entschieden wir uns, eine 9-stellige Nummer in der mittleren Stufe zu randomisieren, um sie in der Datenbank zu speichern. Im Falle einer Kollision werden wir eine neue Nummer neu generieren.

    
Jason 01.12.2009, 03:46
quelle

10 Antworten

8

Wenn die mittlere Schicht nicht überprüfen kann, welche "Bestellnummern" bereits in der Datenbank vorhanden sind, ist das Beste, was sie tun kann, das Erzeugen einer Zufallszahl. Wenn Sie jedoch eine Zufallszahl generieren, die auf weniger als 1 Milliarde beschränkt ist, sollten Sie sich Sorgen um zufällige Kollisionen um sqrt(1 billion) machen, d. H. Nach einigen zehntausend auf diese Weise generierten Einträgen ist das Risiko von Kollisionen erheblich. Was wäre, wenn die Bestellnummer sequentiell ist, aber in einer verschleierten Art und Weise, d. H. Das nächste Vielfache einer großen Primzahl Modulo 1 Milliarde - würde das Ihren Anforderungen entsprechen?

    
Alex Martelli 01.12.2009, 03:53
quelle
5

& lt; Moan & gt; OK klingt wie ein klassischer Fall einer vorzeitigen Optimierung. Du stellst dir ein Performance - Problem vor (Oh mein Gott, ich muss auf die Horror - Datenbank zugreifen, um eine Bestellnummer zu erhalten! Das mag langsam sein) und lande mit einem Haufen pseudo - zufälliger Generatoren und einer Tonne doppeltem Code ; / stöhnen & gt;

Eine einfache praktische Antwort besteht darin, eine Sequenz pro Kunde auszuführen. Die tatsächliche Bestellnummer ist eine Kombination aus Kundennummer und Bestellnummer. Sie können einfach die letzte Sequenz abrufen, wenn Sie andere Dinge über Ihren Kunden abrufen.

    
James Anderson 01.12.2009 06:00
quelle
2

Eine einfache Option ist die Verwendung von Datum und Uhrzeit, z. 0912012359, und wenn zwei Aufträge in der gleichen Minute empfangen werden, erhöhen Sie einfach die zweite Reihenfolge um eine Minute (es spielt keine Rolle, wenn die Zeit abgelaufen ist, es ist nur eine Bestellnummer).

Wenn das Datum nicht sichtbar sein soll, berechnen Sie es als die Anzahl der Minuten seit einem festen Zeitpunkt, z. wenn du angefangen hast, Befehle oder ein anderes beliebiges Datum anzunehmen. Wiederum mit der doppelten Prüfung / Inkrementierung.

Ihre Mitbewerber werden davon nichts erfahren, und es ist einfach zu implementieren.

    
Will 01.12.2009 06:20
quelle
1

Vielleicht könnten Sie versuchen, einen eindeutigen Text mit einer Markov-Kette zu erzeugen - siehe hier für eine Beispielimplementierung in Python. Vielleicht verwenden Sie sequentielle Zahlen (anstatt zufällige), um die Kette zu generieren, so dass (hoffentlich) jede Bestellnummer eindeutig ist.

Aber nur eine Warnung - siehe hier für das, was passieren kann, wenn Sie nicht t vorsichtig mit Ihren Einstellungen.

    
a_m0d 01.12.2009 03:53
quelle
1

Eine Lösung wäre, den Hash eines Felds der Bestellung zu übernehmen. Dies garantiert nicht, dass es aus den Bestellnummern aller anderen Bestellungen eindeutig ist, aber die Wahrscheinlichkeit einer Kollision ist sehr gering. Ich könnte mir vorstellen, dass es ohne "eine Rundreise in die Datenbank" schwierig wäre, sicherzustellen, dass die Bestellnummer eindeutig ist.

Falls Sie mit Hash-Funktionen nicht vertraut sind, ist die Wikipedia-Seite ziemlich gut.

    
momeara 01.12.2009 04:07
quelle
1

Sie könnten base64 eine Guid codieren. Dies erfüllt alle Ihre Kriterien mit Ausnahme der Anforderung "Nur numerische Werte".

Wirklich, aber die richtige Sache, die hier zu tun ist, lässt die Datenbank die Bestellnummer generieren. Das kann bedeuten, dass ein Template -Eintrag erstellt wird, der nicht wirklich eine Bestellnummer hat, bis der Benutzer ihn speichert, oder möglicherweise die Möglichkeit hinzufügt, leer zu erstellen (aber vielleicht nicht committed) Bestellungen.

    
Joel Coehoorn 01.12.2009 04:08
quelle
1

Verwenden Sie primitive Polynome als endlichen Feldgenerator.

    
Luka Rahne 01.12.2009 05:51
quelle
1

Ihre 10-stellige Anforderung ist eine große Einschränkung. Betrachten Sie einen zweistufigen Ansatz.

  1. Verwenden Sie eine GUID
  2. Präfix der GUID mit einem 10-stelligen (oder 5 oder 4-stelligen) Hash der GUID.

Sie haben mehrere Treffer auf den Hash-Wert. Aber nicht so viele. Die Kundendienstmitarbeiter werden sehr leicht in der Lage sein, basierend auf zusätzlichen Informationen des Kunden herauszufinden, welche Bestellung in Frage steht.

    
John 01.12.2009 19:02
quelle
0

Die einfache Antwort auf die meisten Ihrer Aufzählungspunkte:

Machen Sie die ersten sechs Ziffern zu einem sequentiell ansteigenden Feld und fügen Sie drei Ziffern des Hashs an das Ende an. Oder sieben und zwei oder acht und eins, abhängig davon, wie viele Befehle du dir vorstellen willst.

Sie müssen jedoch immer noch eine Funktion am Backend aufrufen, um eine neue Bestellnummer zu reservieren. andernfalls ist es unmöglich, eine Nicht-Kollision zu garantieren, da es so wenige Ziffern gibt.

    
gary 01.12.2009 05:00
quelle
0

Wir machen TTT-Europa-1-N1.

  • T = Schaltungsart (D1E = DS1 EEL, D1U = DS1 UNE usw.)
  • C = 6-stellige Kundennummer
  • 1 = Der erste Standort des Kunden
  • A = Die erste Schaltung (A = 1, B = 2 usw.) an dieser Stelle
  • N = Auftragsart (N = Neu, X = Trennen usw.)
  • 1 = Die erste Ordnung dieser Art für diese Schaltung
Josh 01.12.2009 06:09
quelle

Tags und Links