Was sind die Optionen für die Erzeugung benutzerfreundliche alphanumerische IDs (wie Business ID, SKU)

StackOverflow https://stackoverflow.com/questions/217253

  •  03-07-2019
  •  | 
  •  

Frage

Hier sind die Anforderungen:

Muss alphanumerische, 8-10 Zeichen, so dass es benutzerfreundlich ist. Diese wird als eindeutige Schlüssel in der Datenbank gespeichert werden. Ich bin Guids als Primärschlüssel so eine Option GUIDs zu verwenden, um diese einzigartige Ids zu erzeugen vorzuziehen wäre.

ich auf den Linien eines Basis-n-Wandler denke, die eine Guid und wandelt in ein 8 Zeichen eindeutige Zeichenfolge nimmt.

Kurz, leichtgewichtige Algorithmus wie es bevorzugt, wäre ziemlich oft genannt werden.

War es hilfreich?

Lösung

Sie sollten erwägen Basis 36 , dass sie Buchstaben und Zahlen zu tun. Man betrachte ich das Entfernen (Auge) und O (Oh) von Ihrem Satz, so dass sie nicht mit 1 (eins) Sie vermischen sich und 0 (null). Einige Leute könnten bemängeln 2 und Z als auch.

Andere Tipps

8 characters - perfectly random - 36^8 = 2,821,109,907,456 combinations
10 characters - perfectly random - 36^10 = 3,656,158,440,062,976 combinations
GUID's - statistically unique* - 2^128 = 340,000,000,000,000,000,000,000,000,000,000,000,000 combinations

* ist ein GUID einzigartiges 100% der Zeit? [Stackoverflow]

Das Problem mit dem GUID -> Zeichenkonvertierung; während der GUID statistisch eindeutig zuzuordnen sind, mit einer Teilmenge Einnahme verringern Sie die Zufälligkeit und die Wahrscheinlichkeit von Kollisionen erhöhen. Sie wollen sicher nicht, nicht-unqiue SKUs erstellen.


Lösung 1:

Erstellen SKU relevante Daten zum Objekt und Geschäftsregeln.

d. Es dürfte eine kleine Kombination von Attributen sein, die ein Objekt einzigartig (ein natürlicher Schlüssel) . Kombinieren Sie die Elemente des natürlichen Schlüssel, kodieren und komprimieren sie eine SKU zu erstellen. Oft alles, was Sie brauchen, ist ein Datum-Uhrzeit-Feld (dh ErstellDatum) und einige andere Eigenschaften, dies zu erreichen. Du bist wahrscheinlich eine Menge Löcher in sku Schöpfung haben, aber SKUs sind relevant für Ihre Benutzer.

hypothetisch:

Wholesaler, product name, product version, sku
Amazon,     IPod Nano,    2.2,             AMIPDNN22
BestBuy,    Vaio,         3.2,             BEVAIO32

Lösung 2:

Ein Verfahren, das eine Reihe von Zahlen behält, und dann geht sie nacheinander zu lösen und gibt nie die gleiche Zahl zweimal. Sie können weiterhin mit Löchern im Bereich enden. Wahrscheinlich wenn Sie nicht erzeugen müssen genug SKUs an der Materie, sondern sicherzustellen, dass Ihre Anforderungen für dies zulassen.

Eine Implementierung ist eine key Tabelle in einer Datenbank zu haben, die einen Zähler hat. Der Zähler wird in einer Transaktion inkrementiert. Ein wichtiger Punkt ist, dass, statt um 1 zu inkrementieren, wobei das Verfahren in der Software einen Block greift. pseudo-c # -Code ist wie folgt.

-- what the key table may look like
CREATE TABLE Keys(Name VARCHAR(10) primary key, NextID INT)
INSERT INTO Keys Values('sku',1)

// some elements of the class
public static SkuKeyGenerator 
{
    private static syncObject = new object();
    private static int nextID = 0;
    private static int maxID = 0;
    private const int amountToReserve = 100;

    public static int NextKey()
    {
        lock( syncObject )
        {
            if( nextID == maxID )
            {
                ReserveIds();
            }
            return nextID++;
        }
    }
    private static void ReserveIds()
    {
        // pseudocode - in reality I'd do this with a stored procedure inside a transaction,
        // We reserve some predefined number of keys from Keys where Name = 'sku'
        // need to run the select and update in the same transaction because this isn't the only
        // method that can use this table.
        using( Transaction trans = new Transaction() ) // pseudocode.
        {
             int currentTableValue = db.Execute(trans, "SELECT NextID FROM Keys WHERE Name = 'sku'");
             int newMaxID = currentTableValue + amountToReserve;
             db.Execute(trans, "UPDATE Keys SET NextID = @1 WHERE Name = 'sku'", newMaxID);

             trans.Commit();

             nextID = currentTableValue;
             maxID = newMaxID;
        }
    } 

hier Die Idee ist, dass Sie genug Schlüssel behalten, so dass Ihr Code nicht auf die Datenbank oft nicht gehen, da der Tonumfang immer eine teure Operation ist. Sie müssen eine gute Vorstellung von der Anzahl der Tasten Sie Schlüsselverlust (Neustart der Anwendung) im Vergleich Tasten anstrengend zu schnell und geht zurück in die Datenbank zu behalten, müssen sie balancieren. Diese einfache Implementierung hat keine Möglichkeit, verlorene Schlüssel wieder zu verwenden.

Da diese Implementierung setzt eine Datenbank und Transaktionen, die Sie haben können Anwendungen gleichzeitig ausgeführt werden und alle erzeugen eindeutige Schlüssel ohne oft in die Datenbank gehen zu müssen.

die oben Hinweis basiert lose auf key table, Seite 222 von Patterns of Enterprise Application Architecture (Fowler) . Das Verfahren wird in der Regel verwendet, um Primärschlüssel zu erzeugen, ohne die Notwendigkeit einer Datenbank Identitätsspalt, aber man kann sehen, wie es für Ihre Zwecke angepasst werden kann.

Wenn Sie sich für „benutzerfreundlich“ Suchen Sie könnten ganze Wörter mit eher versuchen wollen, als einfach machen es kurz / alphanumberic, so etwas wie:

words = [s.strip().lower() for s in open('/usr/share/dict/canadian-english') if "'" not in s]
mod = len(words)

def main(script, guid):
    guid = hash(guid)

    print "+".join(words[(guid ** e) % mod] for e in (53, 61, 71))

if __name__ == "__main__":
    import sys
    main(*sys.argv)

Welche erzeugt eine Ausgabe wie:

oranjestad+compressing+wellspring
padlock+discommoded+blazons
pt+olenek+renews

Welche ist amüsant. Ansonsten einfach die ersten 8-10 Zeichen des guid oder SHA1 / MD5-Hash des guid Einnahme ist wahrscheinlich die beste Wahl.

Die einfachste Sache, die möglicherweise funktionieren könnte, ist ein Zähler, der jedes Mal, wenn ein Wert ist erforderlich, erhöht wird. Acht (links mit Nullen aufgefüllt) Ziffern geben Sie 100 Millionen mögliche Werten 00.000.000-99.999.999 (obwohl Sie vielleicht einwerfen Leerzeichen oder Bindestriche für die menschliche Lesbarkeit, wie in 000-000-00).

Wenn Sie mehr als 100 Millionen Werte benötigen, können Sie entweder die Länge erhöhen oder Buchstaben in alternativen Positionen verwenden. Mit A0A0A0A0 durch Z9Z9Z9Z9 gibt Ihnen mehr als vier-und-ein-halbe Milliarden mögliche Werte (4569760000) zur Verfügung. Es ist ein triviales Stück Code eine lange ganze Zahl zu nehmen und erzeugt so eine Codierung (mod 10 für die rechte Stelle, div um 10 dann mod 26 für die am weitesten rechts stehenden Buchstaben, etc.) Wenn Sie den Speicher zu brennen, der schnellste Weg, wird den Zähler auf eine mod 260-Array zu konvertieren, und jeden mod 260-Wert als einen Index in ein Array von zwei-Zeichen-Strings ( „A0“, „A1“, „A2“, und so weiter bis „A9“ verwenden ", B0" , "B1" usw. bis "Z9").

Das Problem mit der Basis 36 (in einer anderen Antwort erwähnte) ist, dass Sie nicht nur über Leser Verwirrung von ähnlichen Zeichen kümmern (eine vs. I, Null vs. O, zwei vs. Z, fünf vs. S), aber auch über Kombinationen von benachbarten Buchstaben, die dem Leser durch die Schreibweise geschmacklos oder obszöne Wörter oder Abkürzungen wahrgenommen werden könnten.

Sie können einen CRC32 Hash-Algorithmus versuchen. Die CRC-32 erzeugt eine 8-Zeichenfolge.

http://en.wikipedia.org/wiki/Cyclic_redundancy_check

http://textop.us/Hashing/CRC

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