Code-Design für Geschäftssysteme — Produkt- und Kundencodes festlegen, und Prüfziffern

· · Code-Design, Prüfziffer, Geschäftssysteme, Datenbank, C#, .NET, Excel, Entscheidungstabelle, Design, Windows-Entwicklung

„Wir migrieren zu einem neuen System, bitte legen Sie das Produktcode-Schema fest.“ — Immer wenn Sie ein Geschäftssystem aufbauen oder eine Excel-Liste migrieren, kommt diese Hausaufgabe auf. Und ein aus dem Moment heraus entschiedener Code überlebt im Schnitt das System selbst. Das System mag nach zehn Jahren ersetzt werden, doch die an Geschäftspartner ausgegebenen Kundennummern und die auf alten Formularen gedruckten Produktcodes leben weiter.

Gleichzeitig existiert eine erstaunliche Menge an angesammeltem Wissen für das Code-Design. Groß angelegte, im Einsatz befindliche Nummerierungssysteme — JAN-Codes, Kreditkartennummern, Japans My Number — veröffentlichen alles von ihrer Methode zur Erkennung von Eingabefehlern bis zur Zuordnung der Ziffern, samt der Begründung hinter diesen Designentscheidungen. Auf dieser Grundlage legt dieser Artikel die Regeln für die Festlegung von Produktcodes, Kundencodes, Belegnummern und Ähnlichem in einem Geschäftssystem sowie den nutzbaren Mechanismus (Prüfziffern) dar.

1. Zunächst das Fazit

  • Der Code identifiziert; die Bedeutung wird als Attribut in der Datenbank gehalten. Ein „bedeutungstragender Code“, der Abteilung, Kategorie oder Geschäftsjahr in seine Ziffern einbettet, bricht bei Umorganisation oder Kategorieänderung unweigerlich zusammen. My Number ist als eine Nummer konzipiert, die keine Bedeutung trägt.1
  • Versehen Sie Codes, die Menschen eintippen, abschreiben oder vorlesen, mit einer Prüfziffer. Aus Messungen ist bekannt, dass die überwiegende Mehrheit der Eingabefehler „ein einzelnes falsch getipptes Zeichen“ und „ein Vertauschen zweier benachbarter Zeichen“ sind2, und eine Prüfziffer zielt genau auf diese beiden.
  • Legen Sie den Zeichensatz danach fest, wie der Code verwendet wird. Ist Telefon, Fax oder Handschrift im Spiel, verwenden Sie ausschließlich Ziffern. Müssen Sie Stellen sparen, verwenden Sie alphanumerische Zeichen mit entfernten verwechselbaren Zeichen (I, L, O und dergleichen), etwa Crockford Base323.
  • Bemessen Sie die Stellenzahl auf etwa das Zehnfache der künftigen Datensatzzahl, und behandeln Sie den Code bei Verwendung führender Nullen in jedem System als Zeichenkette. Sobald Excel ihn als Zahl interpretiert, entfernt es führende Nullen und rundet Ziffern ab der 16. Stelle auf 0.4
  • Verwenden Sie einen einmal vergebenen Code nie erneut, auch wenn er frei wird. In alten Formularen, Protokollen und Systemen von Geschäftspartnern verbliebene Nummern würden am Ende auf etwas anderes zeigen.
  • Wenn Sie Barcodes auf Produkten anbringen und in den Vertrieb geben, verwenden Sie JAN-Codes (den GS1-Standard) statt eigener Codes.5

2. Soll der Code eine Bedeutung tragen? — Die erste und größte Weggabelung

Das Erste, was beim Code-Design zu entscheiden ist, ist weder die Stellenzahl noch der Zeichensatz, sondern: „Soll der Code eine Bedeutung tragen?“

Ein verbreitetes Design sieht so aus: „Produktcodes sind 8-stellig. Die ersten 2 Stellen sind die Abteilung, die nächsten 3 die Kategorie, die restlichen 3 eine laufende Nummer.“ Im Moment der Festlegung wirkt das ordentlich, doch innerhalb weniger Jahre bekommt man Folgendes:

  • Eine Umorganisation fusioniert Abteilungen, und Produkte mit dem alten Abteilungscode hängen in der Luft. Nummerieren Sie neu, können Sie nicht mehr mit alten Formularen abgleichen; lassen Sie es, vermehren sich in den Stammdaten Ausnahmen, bei denen „die Abteilung des Codes von der tatsächlichen Abteilung abweicht“.
  • Kategorieübergreifende Produkte tauchen auf (etwas, das sowohl Lebensmittel als auch Haushaltsware ist), und Sie brauchen eine interne Regel, welcher Code zugewiesen wird.
  • Eine Kategorie wächst so stark, dass ihre 3-stellige laufende Nummer erschöpft ist, und es beginnt die improvisierte Praxis: „Für diese Kategorie ausnahmsweise eine freie Nummer aus einer anderen Abteilung leihen.“

Die Ursache ist eindeutig: Organisationen und Kategorien ändern sich, doch sie wurden unter der Annahme in den Code eingebrannt, dass sie sich nicht ändern würden. Das Prinzip ist also das Gegenteil. Machen Sie den Code zu einem Symbol, das nichts weiter tut, als eindeutig auf etwas zu zeigen, und halten Sie Attribute wie Abteilung und Kategorie in Datenbankspalten. Als Attribute können sie sich beliebig ändern — ein UPDATE, und der Code bleibt unberührt.

Auch die staatlichen Nummerierungssysteme sind nach diesem Prinzip aufgebaut. My Number ist eine 11-stellige, bedeutungslose Nummer, erzeugt durch Umwandlung des Einwohnerregister-Codes „nach einer Methode, bei der keine Absicht einwirkt“, plus eine Prüfziffer.1 Keine Bedeutung zu tragen verhindert, dass aus der Nummer auf individuelle Attribute geschlossen werden kann, bedeutet aber auch, dass sich die Nummer bei einer Attributänderung (Umzug, Namensänderung) nicht ändert.

Dennoch hält sich in der Praxis hartnäckig der Wunsch, dass „zumindest die erste Stelle erkennen lassen sollte, ob es sich um einen Kunden oder Lieferanten handelt“, daher hier als Entscheidungstabelle.

Ansatz Beispiel Stärken Wo es bricht Wann es passt
Vollständig bedeutungstragender Code 02-104-317 (Abteilung-Kategorie-laufende Nummer) Lesen zeigt sofort die Attribute Neunummerierung bei Umorganisation, Kategorieänderung oder partiellem Stellenüberlauf Nur wenn der Bestand weder wächst noch schrumpft und Kategorien gesetzlich fixiert sind
Bedeutungsloser laufender Code 10000317 Nichts bricht, egal was sich ändert. Nummerierung ist einfach Menschen können dem Code nichts entnehmen Betrieb, bei dem ein System stets Attribute parallel auf Bildschirmen und Formularen anzeigt
Hybrid C-0317-5 (1 Zeichen Typ + laufende Nummer + Prüfziffer) Verhindert zumindest die Verwechslung von Typen. Minimale Bruchfläche Neudefinition des Typs (selten) Im Zweifel diese Variante. Den Typ so grob wie „Kunde / Lieferant / Produkt“ halten

Die Empfehlung sind die unteren beiden Zeilen. Gehen Sie davon aus: Je mehr Bedeutung Sie einbetten, desto mehr Bruchkeime pflanzen Sie.

3. Zeichensatz und Länge — Informationseffizienz gegen Lesbarkeit

Als Nächstes kommen Zeichensatz und Stellenzahl. Das ist reine Arithmetik: Je mehr Zeichenarten pro Position zur Verfügung stehen, desto mehr lässt sich mit derselben Stellenzahl darstellen.

Zeichensatz Darstellbare Anzahl mit 6 Stellen Widerstandsfähigkeit gegen Vorlesen / Handschrift
Nur Ziffern (10 Arten) 1 Million ◎ Stark für Telefon, Fax und Handschrift
32 Arten: Großbuchstaben + Ziffern ohne verwechselbare Zeichen (Crockford Base323) Etwa 1,07 Milliarden ○ Fehllesen wird adressiert, Vorlesen aber schlechter als bei Ziffern
Großbuchstaben + Ziffern (36 Arten) Etwa 2,18 Milliarden △ Verwechslung von 0 mit O und 1 mit I ist unvermeidlich

Es gibt zwei Kriterien:

  • Wird dieser Code am Telefon vorgelesen, handschriftlich notiert oder gefaxt? Trifft auch nur eines davon zu, wird ausschließlich Ziffern empfohlen. Sobald Buchstaben hineingemischt werden, entstehen Kosten durch „war das ein I oder eine Eins?“-Nachfragen und das Risiko des Fehllesens.
  • Würden reine Ziffern den Code zu lang machen? Erst wenn Sie die Länge komprimieren müssen — etwa weil der Bestand zig Millionen übersteigt —, sollten Sie alphanumerische Zeichen erwägen. Verwenden Sie auch dann ein vorentworfenes Alphabet wie Crockford Base32, das I, L und O (sowie U, um zufällige Obszönitäten zu vermeiden) ausschließt, statt der rohen 36 Arten. Diese Spezifikation ist beim Fehllesen gründlich: Beim Dekodieren akzeptiert sie Kleinbuchstaben und interpretiert i und l als 1 sowie o als 0.3

Bemessen Sie die Stellenzahl nicht anhand der „aktuellen Datensatzzahl“, sondern anhand der Zahl, die „über die 20 bis 30 Jahre erreichbar ist, in denen System und Formulare weiterleben“, und fügen Sie dann eine Stelle Reserve hinzu. Die Angst vor Stellenüberlauf wird in Kapitel 8 behandelt, doch eine zusätzliche Stelle ist ein geringer Preis, um sich die Art von umfassender Überarbeitung zu ersparen, die Japans Postleitzahlen abverlangt wurde, als sie 1998 von 5 auf 7 Stellen wechselten.

Eine weitere, unauffällig hilfreiche Sache sind Trennzeichen. Genau wie Kreditkartennummern in Vierergruppen gedruckt werden, können Menschen lange Ziffernfolgen nur in Blöcken von drei bis vier Zeichen korrekt verarbeiten. Bringen Sie Codes ab 8 Stellen auf Formulare oder Bildschirme, zeigen Sie sie getrennt an, etwa 1234-5678. Das Prinzip lautet jedoch: Das Trennzeichen ist nicht Teil der Daten; es wird erst bei der Anzeige hinzugefügt (Kapitel 6).

4. Prüfziffern — den Code Eingabefehler selbst erkennen lassen

4.1 Eingabefehler kommen in zwei Arten vor

Eine Prüfziffer ist eine einzelne Ziffer, die an das Ende (oder den Anfang) eines Codes angehängt wird und aus den übrigen Ziffern berechenbar ist, sodass sich ein Fehler in einem eingegebenen Code sofort erkennen lässt. Auch die Prüfziffer von My Number hat ihren Zweck in der Kabinettsverordnung festgeschrieben: „zu dem Zweck, zu bestätigen, dass bei der Eingabe in einen Computer kein Fehler vorliegt“.1

Welche Formel gut ist, bestimmt sich danach, welche Fehler Menschen tatsächlich machen. Nach Verhoeffs klassischer Studie, die Fehlerdaten aus Systemen wie der niederländischen Postgiro analysierte, sind 60 bis 95 % der Fehler ein Vertippen einer einzelnen Ziffer (Single Error) — mit Abstand die größte Klasse. Danach folgen zweistellige Fehler mit 10 bis 20 %, von denen die meisten zwei benachbarte Ziffern betreffen, insbesondere ein Vertauschen abba (Transposition). Jede andere Klasse (der Typ aabb, Sprung-Transpositionen und so weiter) macht jeweils nur etwa 0,5 bis 1,5 % aus.2

Mit anderen Worten: Die Leistung eines Prüfziffernschemas lässt sich wirksam anhand zweier Punkte beurteilen: „Wie viele einstellige Fehler kann es erkennen“ und „Wie viele benachbarte Transpositionen kann es erkennen“.

4.2 In der Praxis verwendete Schemata und ihre Erkennungsleistung (Entscheidungstabelle)

Schema Wo es verwendet wird Einstellige Fehler Benachbarte Transpositionen Merkmale
Modulus 10 Gewicht 3-1 GS1-Standards wie JAN-Codes, ISBN-136 Alle erkannt Übersieht Paare mit Differenz 5 (0550, 1661 usw.) Für Barcode-Betrieb praktisch die einzige Wahl
Luhn (Modulus 10) Kreditkartennummern7 Alle erkannt Übersieht nur das einzelne Paar 0990 Am einfachsten zu implementieren. Der Standardkandidat für eigene Codes
Modulus 11 (gewichtet) My Number8, alte ISBN Nahezu alle erkannt Nahezu alle erkannt Hohe Erkennungsleistung, aber mit dem „Restwert-Ausgleich“-Problem (siehe unten)
Modulus 9 (gewichtet) Unternehmensnummer9 Übersieht 09 Übersieht das Paar 09 Kann wegen der Division durch 9 nicht zwischen 0 und 9 unterscheiden
Damm / Verhoeff Akademische Schemata Alle erkannt Alle erkannt Umgesetzt per Tabellennachschlag (Damm10) oder Gruppenoperationen (Verhoeff2)

Ein paar Anmerkungen:

  • Das JAN-Schema (Modulus 10 Gewicht 3-1) multipliziert die Ziffern beginnend von der rechtesten Ziffer abwechselnd mit 3 und 1, summiert sie und nimmt die Einerstelle von „10 − (die Summe modulo 10)“ als Prüfziffer.6 Eine Transposition lässt die Summe unverändert, wenn die Differenz zwischen den ×3- und ×1-Gewichten, multipliziert mit der Differenz der Ziffern, ein Vielfaches von 10 ist — also wenn sich die beiden Ziffern um genau 5 unterscheiden; nur dieses Muster bleibt unerkannt.
  • Luhn ist das Schema, für das H. P. Luhn von IBM 1954 ein Patent anmeldete7: Es verdoppelt jede zweite Ziffer und zieht 9 ab, falls das Ergebnis 9 überschreitet, bevor summiert wird. Die einzige übersehene benachbarte Transposition ist das einzelne Paar 0990. Es bietet ein gutes Gleichgewicht zwischen Implementierungseinfachheit und Erkennungsleistung, und wenn Sie für eigene Codes neu eines übernehmen, ist dies der richtige Ausgangspunkt.
  • Der Modulus 11 von My Number hat dank der Primzahl 11 eine hohe theoretische Erkennungsleistung, doch es gibt eine Faltungsregel, die die Prüfziffer einheitlich auf 0 setzt, wenn der Rest 0 oder 1 ist8, und Fehler, die nur zwischen diesen beiden Klassen wechseln, lassen sich nicht erkennen. Die alte ISBN (ISBN-10) löste dies mit demselben Modulus 11, indem sie „den Rest 10 als X schreibt“, nahm dafür aber die betriebliche Unannehmlichkeit in Kauf, dass „an einer eigentlich numerischen Stelle ein X auftaucht“. Übernehmen Sie ein Schema der Modulus-11-Familie, sollten Sie wissen, dass das Problem „wie quetscht man 11 mögliche Reste in 10 Ziffern“ stets mitkommt.
  • Der Modulus 9 der Unternehmensnummer ist ein ungewöhnliches Design, das die Prüfziffer an den Anfang stellt11, doch weil er den Rest modulo 9 verwendet, sind 0 und 9 kongruent, sodass ein Vertippen oder Vertauschen dieser beiden ungehindert durchgeht.
  • Die Schemata von Damm und Verhoeff erkennen alle einstelligen Fehler und alle benachbarten Transpositionen. Verhoeff war der Erste, der einen Dezimalcode konstruierte, der alle einstelligen Fehler und alle benachbarten Transpositionen erkennt2, und Damm gab eine einfachere Konstruktion an, die nur das Nachschlagen in einer einzigen Quasigruppen-Operationstabelle erfordert.10 Steht Erkennungsleistung an oberster Stelle, sind dies die Kandidaten; als Gegenmaßnahme gegen Eingabefehler in einem Geschäftssystem reicht Luhn oder das JAN-Schema jedoch praktisch aus.

4.3 Codes, die eine Prüfziffer brauchen, und solche, die keine brauchen

Das Kriterium lautet: „Geht er durch Menschenhand und -auge?“ Ein von einem Papier-Bestellformular eingetippter Produktcode, eine am Telefon durchgegebene Mitgliedsnummer, eine vor Ort handschriftlich notierte Belegnummer — bei all diesen lohnt sich eine Prüfziffer. Interne IDs hingegen, die nur durch die Integration zwischen Systemen fließen, und Codes, die sich nur per Auswahl auf einem Bildschirm eingeben lassen, brauchen keine. Gibt es keine Fehlerquelle (einen Menschen), gibt es auch nichts zu erkennen.

5. Implementierungsbeispiele in C#

Die wichtigsten Schemata lassen sich jeweils in wenigen bis einem guten Dutzend Zeilen implementieren. Das Einzige, worauf Sie achten müssen, ist, den Code stets als Zeichenkette entgegenzunehmen (der Grund folgt in Kapitel 6).

Zunächst das JAN-Schema (GTIN-13). Die Prüfziffer wird aus dem 12-stelligen Rumpf berechnet.6

public static int Gtin13CheckDigit(string body12)
{
    if (body12.Length != 12 || !body12.All(char.IsAsciiDigit))
        throw new ArgumentException("12 Ziffern angeben", nameof(body12));

    int sum = 0;
    for (int i = 0; i < 12; i++)
    {
        int digit = body12[11 - i] - '0';        // von rechts zählen
        sum += (i % 2 == 0) ? digit * 3 : digit; // ganz rechts ×3, danach abwechselnd
    }
    return (10 - sum % 10) % 10;
}

Als Nächstes Luhn. Wenn Sie ihn an eigenen Kundencodes oder Mitgliedsnummern anbringen, reichen diese beiden aus.

public static int LuhnCheckDigit(string body)
{
    int sum = 0;
    for (int i = 0; i < body.Length; i++)
    {
        int digit = body[body.Length - 1 - i] - '0';
        if (i % 2 == 0)              // jede zweite Ziffer verdoppeln, beginnend neben der Prüfziffer
        {
            digit *= 2;
            if (digit > 9) digit -= 9;
        }
        sum += digit;
    }
    return (10 - sum % 10) % 10;
}

public static bool IsValidLuhn(string code) =>
    code.Length >= 2 && code.All(char.IsAsciiDigit) &&
    LuhnCheckDigit(code[..^1]) == code[^1] - '0';

Hier auch die Validierung der Unternehmensnummer, nutzbar für die Eingabeprüfung gegen einen Kunden-/Lieferantenstamm. Sie ist eine direkte Umsetzung der Formel aus der ministeriellen Verordnung9 (die erste Ziffer ist die Prüfziffer, die folgenden 12 Ziffern sind die Basisnummer).

public static bool IsValidCorporateNumber(string code)
{
    if (code.Length != 13 || !code.All(char.IsAsciiDigit)) return false;

    int sum = 0;
    for (int n = 1; n <= 12; n++)
    {
        int p = code[13 - n] - '0';          // die niedrigstwertige Ziffer der Basisnummer ist n=1
        sum += p * (n % 2 == 0 ? 2 : 1);     // ungerade Positionen ×1, gerade Positionen ×2
    }
    return 9 - sum % 9 == code[0] - '0';
}

Zur Kontrolle anhand des Beispiels aus dem Material der nationalen Steuerbehörde (Firmenregisternummer 700110005901 → Unternehmensnummer 8700110005901): Summe der ungeraden Positionen 11 + Summe der geraden Positionen 13 × 2 = 37, 37 geteilt durch 9 ergibt Rest 1, und 9 − 1 = 8, was übereinstimmt.11

Es gibt auch eine weitere Verfeinerung, wie Sie dies auf der Eingabemaske nutzen. Statt bei nicht übereinstimmender Prüfziffer nur „ungültiger Code“ anzuzeigen, gehen Sie so weit, den Stamm nachzuschlagen und den Namen zurückzumelden („1000317: Musterfirma GmbH — ist das richtig?“). So kann eine Fehleingabe, die an der Prüfziffer vorbeirutscht (weil der Nutzer einen anderen, tatsächlich existierenden Code getippt hat), ebenfalls von einem menschlichen Auge erkannt werden.

6. Fallstricke, auf die Sie im Feld garantiert stoßen

Selbst bei einem guten Codesystem gibt es Standardmuster, bei denen Implementierung und Betrieb es zunichtemachen.

  • Excels Wegfall führender Nullen und 15-stellige Rundung. Wenn Excel den Inhalt einer Zelle als Zahl interpretiert, entfernt es führende Nullen, und weil die signifikante Genauigkeit einer Zahl 15 Stellen beträgt, ersetzt es Ziffern ab der 16. Stelle durch 0.4 Kundencode 00123 wird zu 123, und bei kreditkartenlangen Nummern wird das Ende zu 0. Bauen Sie bei Codes in einem System mit CSV-Integration die Behandlung als Zeichenkette auf jedem Pfad (Angabe des Texttyps in Power Query, Angabe des Spaltentyps auf der Importseite) von Anfang an in Ihre Betriebsverfahren ein.
  • Speicherung in einer numerischen Spalte der Datenbank. Führende Nullen verschwinden wie bei Excel, und ein BETWEEN, das „nach Codebereich filtern“ soll, zieht Codes unterschiedlicher Länge mit hinein. Ein Code ist nichts, womit man rechnet, daher gilt als Prinzip ein Zeichenkettentyp fester Länge. Entwerfen Sie auch die Sortierreihenfolge als Zeichenkette (fixieren Sie die Länge, dann entspricht die Zeichenkettensortierung der numerischen Sortierung).
  • Bindestriche in den Daten aufnehmen. Sobald 1234-5678 und 12345678 als getrennte Datensätze nebeneinander existieren, ist es vorbei. Speichern Sie den nackten Code, fügen Sie Trennzeichen erst bei der Anzeige hinzu. Entfernen Sie bei der Eingabe Bindestriche und Leerzeichen, bevor Sie validieren.
  • Uneinheitliche Groß-/Kleinschreibung. Verwenden Sie Buchstaben, normalisieren Sie vor dem Speichern auf Großschreibung und erzwingen Sie die Einheitlichkeit selbst, statt sich auf die Kollatierung (Collation) zu verlassen.
  • Wiederverwendung freigewordener Nummern. „Kundencode 1000317 ist gekündigt, also geben wir ihn einem neuen Kunden“ ist tabu. Alte Rechnungen, Protokolle und Systeme von Geschäftspartnern enthalten noch die alte Zuordnung, und ein Audit oder eine Störungsuntersuchung würde am Ende die falsche Partei treffen. Codes sollten grundsätzlich dauerhaft stillgelegt werden.

7. Codes, die Sie nicht selbst festlegen dürfen — auf einem bestehenden Standard aufsetzen

Codes, die im Unternehmen bleiben, können Sie frei gestalten, doch wenn Sie Barcodes auf Produkte drucken und diese nach außen (Einzelhandel, E-Commerce, Logistik) gehen, verwenden Sie JAN-Codes (GTIN) statt eigener. Ein JAN-Code wird unter einem an Sie lizenzierten GS1-Firmenpräfix vergeben; Sie können ihn nicht einfach selbst festlegen.5 Auch die Methode zur Berechnung der Prüfziffer ist durch den Standard definiert.6

Der Design-Punkt hierbei ist, den internen Code und den JAN-Code nicht gewaltsam zu vereinheitlichen. Da dasselbe Produkt je nach Verpackungsgröße unterschiedliche JANs haben kann und sich ein JAN bei einer Spezifikationsänderung ändern kann, ist es gängige Praxis, „internen Produktcode (faktisch der Primärschlüssel, von Ihnen vergeben)“ und „JAN-Code (ein Attribut, möglicherweise mehrfach)“ als getrennte Spalten im Produktstamm zu halten. Auch hier gilt unmittelbar das Prinzip „der Code identifiziert; die Bedeutung (die Zuordnung zu einem externen Standard) ist ein Attribut“.

8. Die Lebensdauer eines Codesystems und Migration

Wie sorgfältig Sie es auch gestalten — ein Codesystem erreicht irgendwann das Ende seiner Lebensdauer. Die typische Ursache ist Stellenüberlauf. Rückt die Obergrenze der laufenden Nummer in Sichtweite, bleibt nur die Option „Stellen hinzufügen“ — doch die Stellenzahl ist nicht nur in die Spaltendefinitionen des Stamms eingebrannt, sondern auch in Formularlayouts, Barcode-Druckbreiten, die Dateispezifikationen für die Integration mit Geschäftspartnern und sogar in die Systeme der Geschäftspartner selbst. Am Ende führen Sie eine Migration in der Größenordnung der japanischen Postleitzahlumstellung auf 7 Stellen (1998) durch — im eigenen Unternehmen und bei allen Geschäftspartnern.

Genau deshalb zahlt sich die „eine Stelle Reserve“ aus Kapitel 3 aus — doch wird eine Migration dennoch notwendig, gelten drei Prinzipien:

  • Bauen Sie einen Alt-Neu-Zuordnungsstamm auf und machen Sie während der Übergangszeit beide Codes durchsuchbar. Anfragen von Geschäftspartnern kommen mit dem alten Code.
  • Haben Sie den internen Schlüssel vom Code getrennt gehalten, bleibt die Migration auf die Anzeigeschicht und den Stamm beschränkt. Haben Sie den Geschäftscode selbst als Datenbank-Primärschlüssel verwendet, gehen die Fremdschlüssel jeder Tabelle mit unter. Für Neuentwürfe empfehlen wir, den internen Schlüssel (automatisch nummeriert) vom Anzeigecode zu trennen.
  • Liefern Sie Schemaänderungen als versionierte Migrationen aus. Wie sich eine Änderung der Spaltenlänge eines Codes zuverlässig an jeden Kunden und jede Umgebung weitergeben lässt, ist im Artikel über Datenbankschema-Migration behandelt.

9. Zusammenfassung

  • Das erste Prinzip des Code-Designs lautet „der Code identifiziert, die Bedeutung ist ein Attribut“. Brennen Sie Abteilungen oder Kategorien in den Code ein, werden Änderungen an Organisation und Klassifizierung zu Brüchen im Code. Dass My Number eine bedeutungslose Nummer ist, ist kein Zufall.1
  • Zeichensatz und Länge sind ein Kompromiss zwischen Informationseffizienz und Lesbarkeit. Wird vorgelesen oder handschriftlich notiert, ausschließlich Ziffern; wollen Sie die Länge komprimieren, verwenden Sie ein gegen Fehllesen konzipiertes Alphabet (Crockford Base323). Bemessen Sie es auf das Zehnfache der künftigen Datensatzzahl plus eine Stelle.
  • Die Realität von Eingabefehlern lautet: „einstellige Fehler 60 bis 90 %, benachbarte Transpositionen der Großteil des Rests.“2 Versehen Sie Codes, die durch Menschenhand gehen, mit einer Prüfziffer; im Zweifel über das Schema Luhn verwenden, und für Barcodes den GS1-Standard.6 Das „Restwert-Ausgleich“-Problem der Modulus-11-Familie und die Tatsache, dass der Modulus 9 der Unternehmensnummer nicht zwischen 0 und 9 unterscheiden kann, sind Eigenschaften, die man bei der Wahl des Schemas kennen sollte.
  • Die Implementierung sollte durchgehend auf Zeichenketten setzen. Excels Wegfall führender Nullen und 15-stellige Rundung4, Speicherung in numerischen Spalten, sich einschleichende Bindestriche und die Wiederverwendung freigewordener Nummern sind die vier großen Unfälle im Feld.
  • Nach außen fließende Produktcodes sollten auf JAN (GS1) aufsetzen und in einer separaten Spalte vom internen Code gehalten werden. Halten Sie zur Vorbereitung auf eine Migration bei Stellenüberlauf internen Schlüssel und Anzeigecode getrennt.

Ein Codesystem ist eine faktische externe Spezifikation: Ist es einmal ausgegeben, sind die Kosten einer späteren Korrektur um Größenordnungen höher. Kommt bei der Anforderungsdefinition eines neuen Systems das Thema Codes auf, gehen Sie die Checkliste dieses Artikels durch, bevor Sie zu Bildschirmen und Funktionen übergehen.

Verwandte Artikel

Verwandte Beratungsbereiche

Die KomuraSoft LLC übernimmt Code- und Stammdatendesign für neue und ersetzende Geschäftssysteme, die Untersuchung von Stellenüberlauf und Duplikaten in bestehenden Codesystemen samt Migrationsplanung sowie die Implementierung von Eingabevalidierung (Prüfziffern und Stammdatenabgleich). Wie beim Vergleich der Prüfziffernschemata in diesem Artikel übernehmen wir auch Beratung im Bereich der mathematischen Beratung, bei der bewertet wird, „welches Schema welche Fehler wie gut erkennt“, formelbasiert und in Designentscheidungen umgesetzt.

  1. Order for Enforcement of the Act on the Use of Numbers to Identify a Specific Individual in Administrative Procedures (Cabinet Order No. 155 of 2014), Artikel 6. Dazu, dass die als Individual Number zu verwendende Nummer aus einer 11-stelligen Nummer besteht, die durch Umwandlung des Einwohnerregister-Codes nach einer Methode gewonnen wird, bei der keine Absicht einwirkt, gefolgt von einer einzelnen Prüfziffer (eine Ganzzahl von 0 bis 9, berechnet zu dem Zweck, zu bestätigen, dass bei der Eingabe der Individual Number in einen Computer kein Fehler vorliegt).  2 3 4

  2. J. Verhoeff, Error Detecting Decimal Codes, Mathematical Centre Tracts 29, Mathematisch Centrum, Amsterdam. Zu den Häufigkeiten der Fehlerklassen auf Basis einer Analyse von Fehlerstichproben aus realen Systemen (einstellige Fehler die größte Klasse mit 60 bis 95 %, zweistellige Fehler mit 10 bis 20 %, wovon die meisten Transpositionen benachbarter Ziffern sind, sowie Minderheitenklassen wie Zwillingsfehler mit jeweils 0,5 bis 1,5 %), und zur Konstruktion eines Dezimalcodes durch den Autor, der alle einstelligen Fehler und alle benachbarten Transpositionen erkennt (Transposition bezeichnet in dieser Arbeit das Vertauschen benachbarter Ziffern).  2 3 4 5

  3. Douglas Crockford, Base 32. Zum 32-Zeichen-Alphabet, das I und L (verwechselbar mit 1) sowie O (verwechselbar mit 0) ausschließt, plus U zur Vermeidung zufälliger Obszönitäten; dazu, dass beim Dekodieren beide Schreibweisen akzeptiert werden und i sowie l als 1 und o als 0 behandelt werden; und zum Mechanismus des Prüfsymbols mittels mod 37.  2 3 4

  4. Microsoft Support, Keep leading zeros and large numbers. Dazu, dass die signifikante Genauigkeit von Zahlen in Excel höchstens 15 Stellen beträgt, sodass bei Zahlen ab 16 Stellen wie Kreditkartennummern der über 15 Stellen hinausgehende Teil auf 0 geändert wird, dazu, dass führende Nullen entfernt werden, und zur Umgehung, die Spalte als Text zu behandeln.  2 3

  5. GS1 Japan, GS1 company prefixes and GTIN (JAN codes). Dazu, dass die Verwendung von JAN-Codes ein Registrierungsverfahren zur Lizenzierung eines GS1-Firmenpräfixes erfordert.  2

  6. GS1 Japan, How to calculate the check digit. Dazu, dass die Prüfziffer von GTIN-13 (dem Standard-JAN-Codetyp) berechnet wird, indem die Summe der abwechselnd von der rechtesten Ziffer aus mit 3 und 1 multiplizierten Ziffern gebildet und anschließend „(die Summe modulo 10) von 10 subtrahiert“ wird.  2 3 4 5

  7. H. P. Luhn, US Patent 2,950,048 “Computer for Verifying Numbers” (angemeldet 1954, erteilt 1960). Zum Schema, eine Prüfziffer an das rechte Ende der ursprünglichen Nummer anzuhängen und die Nummer durch eine Kreuzaddition mittels Ersatzziffern (der Ziffernsumme der verdoppelten Ziffer) zu verifizieren.  2

  8. Order on the Individual Number, Individual Number Card, and Provision of Specific Personal Information under the Act on the Use of Numbers to Identify a Specific Individual in Administrative Procedures (Ministry of Internal Affairs and Communications Order No. 85 of 2014), Artikel 5. Zur Formel der Prüfziffer (die Ziffer Pn an Position n, gezählt von der niedrigstwertigen der 11 Ziffern außer der Prüfziffer, wird mit einem Gewicht Qn von n+1 für 1≦n≦6 und n−5 für 7≦n≦11 multipliziert, summiert, durch 11 geteilt, und der Rest wird von 11 subtrahiert; ist der Rest 1 oder kleiner, wird 0 verwendet).  2

  9. Ministerial Ordinance on the Designation of Corporate Numbers (Ministry of Finance Order No. 70 of 2014), Artikel 2. Zur Formel der Prüfziffer der Unternehmensnummer (die Ziffer Pn an Position n, gezählt von der niedrigstwertigen der Basisnummer, wird mit einem Gewicht Qn von 1 bei ungeradem n und 2 bei geradem n multipliziert, summiert, durch 9 geteilt, und der Rest wird von 9 subtrahiert).  2

  10. H. M. Damm, Totally anti-symmetric quasigroups for all orders n≠2,6, Discrete Mathematics, Vol. 307, 2007. Zur Existenz, für alle Ordnungen außer 2 und 6, der total antisymmetrischen Quasigruppen, die den Prüfziffernschemata zugrunde liegen, welche alle einstelligen Fehler und benachbarten Transpositionen erkennen.  2

  11. National Tax Agency, Calculating the check digit. Dazu, dass die Unternehmensnummer aus einer 12-stelligen Basisnummer besteht, der eine einzelne Prüfziffer vorangestellt ist, sowie zum durchgerechneten Beispiel, das Prüfziffer 8 aus der Firmenregisternummer 700110005901 berechnet.  2

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Welche Codes sollten eine Prüfziffer erhalten?
Codes, die Menschen eintippen, abschreiben oder vorlesen. Typische Beispiele sind ein von einem Papierformular eingegebener Produktcode, eine am Telefon durchgegebene Mitgliedsnummer oder eine handschriftlich notierte Belegnummer. Interne IDs hingegen, die nur zwischen Systemen fließen (etwa Datenbank-Primärschlüssel), benötigen keine. Codes, die nie durch Menschenhand gehen, erleiden keine Tippfehler, und der Zweck einer Prüfziffer ist die Erkennung von Eingabefehlern. Auch die japanische My-Number-Prüfziffer ist gesetzlich mit dem ausdrücklichen Zweck definiert, „zu bestätigen, dass bei der Eingabe in einen Computer kein Fehler vorliegt“.
Ist es zulässig, einem Produktcode eine Bedeutung wie eine Abteilung oder Kategorie zu geben?
Das Prinzip lautet: „Der Code identifiziert, die Bedeutung wird als Attribut in der Datenbank gehalten.“ Betten Sie Abteilungen, Kategorien oder Geschäftsjahre in die Ziffern eines Codes ein, erzwingt jede Umorganisation oder Kategorieänderung eine Neunummerierung, und der Abgleich mit alten Formularen und bereits an Geschäftspartner vergebenen Nummern bricht zusammen. Wenn Menschen wirklich auf einen Blick unterscheiden können müssen, beschränken Sie sich auf ein einzelnes Präfix-Zeichen für den Typ und machen Sie den Rest zu einer laufenden Nummer — das ist der praktische Kompromiss.
Können wir ein bestehendes Codesystem nachträglich mit einer Prüfziffer versehen?
Technisch ja, aber da dadurch eine Ziffer hinzukommt, betrifft es die Stammdaten, jedes Formular, den Datenaustausch mit Geschäftspartnern und gedrucktes Material. In der Praxis wird daraus ein Migrationsprojekt für das Codesystem, daher ist es realistisch, dies mit einem Zeitpunkt zu verbinden, an dem das System ohnehin überarbeitet wird, etwa im Zuge einer Behandlung von Stellenüberlauf. Als Übergangslösung bis dahin reduziert bereits eine einfache Existenzprüfung gegen die Stammdaten auf der Eingabemaske (Verifikation, dass der eingegebene Code tatsächlich existiert) samt Rückmeldung des Namens den praktischen Schaden durch Fehleingaben erheblich.
Dürfen wir eine UUID oder ULID als Geschäftscode verwenden?
Als interne Datenbankschlüssel sind sie unproblematisch, aber für einen „Anzeigecode“, den Menschen vorlesen oder abschreiben, sind sie ungeeignet. Eine UUID ist mit 36 Zeichen viel zu lang, um die Übermittlung per Telefon oder Fax zu überstehen. Verwenden Sie eine zweischichtige Struktur mit einem internen Schlüssel (eine UUID oder eine automatisch hochzählende Nummer) und einem separaten, den Menschen gezeigten Anzeigecode (eine kurze laufende Nummer plus Prüfziffer), können Sie beide Anforderungen erfüllen. Selbst wenn Sie später das Anzeigecode-Schema ändern müssen, hält ein stabiler interner Schlüssel den Wirkungsbereich auf die Anzeigeschicht begrenzt.

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog