Zu einigen meiner Tabellen möchte ich "second_primary_key" hinzufügen, was uuid oder ein zufälliger langer Schlüssel sein wird. Ich brauche es, weil ich für einige Tabellen keine Ganzzahlen für meine Webanwendung bereitstellen möchte. Das heißt, auf einer Seite "/ invoices" habe ich eine Liste von Rechnungen und einen Link zu "/ invoices /: id", wobei: id eine Ganzzahl ist. Ich möchte nicht, dass ein Benutzer weiß, wie viele Rechnungen sich in meinem System befinden. Daher möchte ich anstelle von "/ invoices / 123" den "second_primary_key" verwenden, damit die URL "/ invoices / N_8Zk241vNa" lautet.
Das gleiche gilt für andere Tabellen, in denen ich die echte ID verstecken möchte.
Ich frage mich, ist das eine gängige Praxis? Wie lässt sich das am besten umsetzen?
Und wie heißt diese Technik überhaupt, damit ich danach suche?
Antworten:
Sie könnten eine UUID-Spalte hinzufügen, müssen dies jedoch nicht (und sollten dies auch nicht). Dies ist ein Anliegen der Präsentationsebene. Sie würden nicht davon träumen zu sagen, einen Währungswert von 1.999 US-Dollar sowie 1999 zu speichern.
Sie möchten nur eine Möglichkeit, den Wert für die Anwendung im Handumdrehen zu verschleiern. Sie können dies entweder in der Anwendung selbst oder als Datenbankansicht tun.
Da es sich nur um einen einzelnen Wert handelt, sollten Sie sich eine Zwei-Wege-Verschlüsselung wie AES oder ähnliches ansehen - je leichter, desto besser.
Hashing könnte eine andere Möglichkeit sein - es hängt davon ab, ob Sie die Rechnungsnummer zurückerhalten möchten, da Hashing eine Möglichkeit ist.
quelle
Ein "alternativer Primärschlüssel" ist ein bekanntes Konzept in der relationalen Datenbankmodellierung und wird als "alternativer Schlüssel" oder manchmal auch als "Sekundärschlüssel" bezeichnet. Der Satz von "potentiellen Primärschlüsseln" wird "Kandidatenschlüssel" genannt. Siehe https://beginnersbook.com/2015/04/alternate-key-in-dbms/
Wie Sie dies implementieren, liegt ganz bei Ihnen, insbesondere wenn Sie die Gesamtzahl der Datensätze ausblenden möchten. Es gibt keinen "besten Weg", Sie sollten Ihre Anforderungen wie zulässiger oder nützlicher Zeichensatz, maximale Länge überprüfen, ob bei den IDs die Groß- und Kleinschreibung beachtet werden soll oder nicht, wenn Sie möchten, dass sie auf einer gedruckten Rechnung lesbar sind, falls jemand Sie müssen in der Lage sein, sie am Telefon fehlerfrei zu beantworten, und so weiter.
quelle
Die meisten Rechnungen haben eine Rechnungsnummer, die nach den meisten Abrechnungsregeln fortlaufend sein muss, oder ein Buchhalter kann die Jahresergebnisse nicht abzeichnen, oder die IRS (oder eine ähnliche in Ihrem Land) möchte eine vollständige Prüfung Ihrer Registerkarten durchführen.
Ein Benutzer konnte aus der Rechnungsnummer ableiten, wie viele Kunden Sie bedient haben oder wie lange es gedauert hat, bis Sie die Nummerierungsstrategie für Rechnungen geändert haben.
Wie viele Rechnungen in der Datenbank gespeichert sind, ist kein Maß für die Gesamtsumme Ihrer Rechnungen. Sie können dies auch auf andere Weise herausfinden, indem Sie Ihre Jahresberichte bei der Handelskammer anfordern.
Ich würde jedoch die Rechnung hinter einem Benutzeranmeldebildschirm sperren, damit nicht jeder sie anfordern kann. Bei der Benutzeranmeldung können sie dann mithilfe einer Ajax-Methode ihre ausstehenden Rechnungen usw. anfordern. Dies sichert Ihre Daten, verbirgt die URL durch Ajax (normalerweise kann sich niemand die Mühe machen, die Details zum Aufbau der Ajax-Anforderung zu prüfen). und Sie steuern, wie die Daten angezeigt und angeboten werden.
quelle
Möglicherweise können Sie dafür Hash-IDs verwenden . Sie wurden entwickelt, um genau dieses Szenario zu lösen.
Ihre Datenbank-ID wird in einem kurzen Hash (ähnlich der URL eines YouTube-Videos) codiert, und Sie müssen Ihrer Tabelle keine sekundären Schlüssel hinzufügen.
quelle
Sie können einen anderen eindeutigen Schlüssel erstellen, dies sollte jedoch nicht der Fall sein. Nicht aus dem angegebenen Grund. Es gibt einfachere Möglichkeiten, die Tischgrößen auszublenden.
Das Speichern
N_8Zk241vNa
kostet 12 Byte pro Zeile in der Tabelle und noch mehr im Index. Das ist ziemlich verschwenderisch für das, was Sie brauchen.Das Verschlüsseln der Ganzzahl
id
kostet Sie keinen Platz und fast nichts in der Laufzeit. Wie Sie dies tun, hängt von Ihrer Programmiersprache und / oder Ihrer Datenbank ab.Beachten Sie, dass Sie mit AES eine 128-Bit-Ganzzahl erhalten, was 22 Zeichen in base64 bedeutet, wahrscheinlich mehr als Sie möchten. Eine Verschlüsselung mit einer Blockgröße von 64 wie DES oder 3DES gibt Ihnen 11 Zeichen, ganz wie Sie möchten.
Verwenden Sie unterschiedliche Schlüssel für unterschiedliche Tabellen.
Wenn Sie nur die Tabellengrößen ausblenden müssen, können Sie für alle Tabellen eine gemeinsame Reihenfolge verwenden. Beachten Sie, dass es zu Engpässen kommen kann, wenn viele Ihrer Tabellen häufig eingefügt werden. Mit etwas wie Ruhezustand und einem Hi-Lo-Algorithmus verschwindet dieses Problem.
quelle
byte[]
, Sie können Ihreid
in vier oder acht Bytes schreiben , eine eindeutige Tabellennummer hinzufügen und verschlüsseln (die Eingabe muss genau 16 Bytes sein). Wenn Sie zwischen verschiedenen Modi wählen können, ist die EZB richtig.IMHO Erstellen von zwei verschiedenen Primärschlüsseln ist nicht möglich. Natürlich können Sie diese UUID in eine DB einfügen, um sie als "Alias" für den aktuellen Primärschlüssel zu haben. Sie können einen Index mit einer eindeutigen Einschränkung über dieser Spalte platzieren, der Primärschlüssel ist jedoch (von Grund auf) ein einzelner Index in einer einzelnen Tabelle. Es kann einen zusammengesetzten Primärschlüssel geben, aber das ist nicht das, wonach Sie suchen.
Also schlage ich vor, es dort abzulegen, aber nur mit Index. Sie können eine Handling-Komponente für die Abfrage von Daten nach PK sowie für andere eindeutige Spalten erstellen. Wenn Sie eine Anfrage nach "/ invoices / ..." bearbeiten, überprüfen Sie einfach den Parameter. Wenn es sich um eine Ganzzahl handelt, suchen Sie die ID, andernfalls suchen Sie die UUID. Oder Sie können die UUID-Suche als Ersatz verwenden, wenn die ID-Suche nichts gefunden hat.
Und um ein paar "zufällige" UUIDs zu generieren: Warum nicht so etwas wie "ID nehmen, CONSTANT hinzufügen, in Hexadezimalzahl konvertieren". Die Eindeutigkeit der ID gibt die Eindeutigkeit der UUID an. Die hexadezimale Zahl ist für normale Sterbliche schwerer zu lesen. Durch das Hinzufügen einer Konstanten wird vermieden, dass die UUID 00000001 entspricht.
quelle
/invoices/123
,/invoices/124
, ...) Sie würden also nur nach UUID über die URL suchen.Wenn beide Tasten auf dieselbe Tatsache verweisen und niemals kollidieren würden. Warum nicht den anderen Schlüssel mit einer Skalarfunktion vom Original ableiten, die einen benutzerdefinierten Hash-Code Ihres Originalschlüssels erzeugt?
Alternativ können Sie eine Anhang-Zuordnungstabelle erstellen, in der beide Versionen des Schlüssels gespeichert werden. Diese Tabelle dient als Wörterbuch zum Nachschlagen des Sekundärschlüssels.
Nach meinem Verständnis sind Schlüssel implizite Indizes, und je mehr Sie Indizes hinzufügen, desto langsamer werden die Einfügungen.
quelle
Ein weiterer Ansatz für Ihren speziellen Anwendungsfall besteht darin, dass Sie anstelle einer Änderung der Datenbank und der Anwendung einfach eine benutzerdefinierte Route zu den Rechnungen erstellen können, sodass / invoices /: f (id) wobei f (id) eine Funktion der ID ist.
Die benutzerdefinierte Route ist dafür verantwortlich, eine Anforderung der richtigen Aktion serverseitig zuzuordnen.
quelle
Dies ist eine völlig akzeptable Vorgehensweise, die auch als "Alternate Key" (AK) bezeichnet wird. Grundsätzlich ist der AK ein weiterer eindeutiger Index oder eine eindeutige Einschränkung.
Sie können sogar Fremdschlüsseleinschränkungen basierend auf Ihrer AK erstellen.
Ein möglicher Anwendungsfall entspricht dem, was Sie erklärt haben: Sie haben eine gruppierte PK mit einer ständig wachsenden Identitätsnummer, möchten jedoch nicht, dass diese Nummer angezeigt oder als Suchkriterium verwendet wird, da dies einfach erraten werden kann. Sie haben also zusätzlich eine zufällige eindeutige Kennung oder Referenznummer als AK, und das ist die ID, die Sie dem Benutzer präsentieren
quelle
Es gibt verschiedene Arten von Schlüsseln / Indizes. Ein Primärschlüssel ist ein spezieller eindeutiger Index, und wie die Antworten besagen, können Sie mit Sicherheit einen weiteren eindeutigen Schlüssel erstellen. Und ich bin damit einverstanden, dass es am besten ist, Ihre Datenbankinterna nur dann offenzulegen, wenn es einen sehr guten Grund gibt.
Da die Frage im Zusammenhang mit Rechnungen und Zahlen steht, lohnt es sich möglicherweise zu untersuchen, wie die Buchhaltungsbranche das Aussehen von Rechnungsnummern erwartet: http://smallbusiness.chron.com/assign-invoice-numbers-52422.html
Es mag unsauber erscheinen, eine interne ID zu haben, die ein Primärschlüssel ist, und ein weiteres eindeutiges Feld mit der Rechnungsnummer, die für die Anwendung / den Kunden sichtbar ist. Aber es ist nicht so unrein, wenn der Kunde beispielsweise ein Jahr später ein neues Rechnungsnummerierungsschema einführen möchte. In diesem Fall würden Sie die interne ID und ihre Beziehungen in anderen Tabellen nicht stören, um die gesamte Wachskugel neu zu nummerieren. Sie würden Ihre interne ID beibehalten und die nicht interne Rechnungsnummer neu nummerieren.
Idealerweise bemühen Sie sich, Tabellen auf Schlüsseln / Fremdschlüsseln, die sich wahrscheinlich ändern, nicht miteinander zu verknüpfen, und halten Ihre internen Tabellen und Beziehungen für die App-Ebene transparent.
quelle
Tue es.
Dies unterscheidet sich nicht von einem "Slug" -Feld, über das Blog-Artikel und dergleichen häufig verfügen - eine einzigartige Möglichkeit, auf den Datenbankdatensatz zu verweisen, der vom Primärschlüssel getrennt ist und für die Verwendung in einer URL geeignet ist. Ich habe noch nie jemanden dagegen argumentieren hören.
quelle