it-swarm.com.de

Erstellen eines sekundären Primärschlüssels in einer Datenbank für einige Tabellen

Zu einigen meiner Tabellen möchte ich "second_primary_key" hinzufügen, der 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 verfügbar machen möchte. Das heißt, auf einer Seite "/ Rechnungen" habe ich eine Liste von Rechnungen und einen Link zu "/ Rechnungen /: ID", wobei: ID eine Ganzzahl ist. Ich möchte nicht, dass ein Benutzer weiß, wie viele Rechnungen sich in meinem System dort 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 echte ID verbergen möchte.

Ich frage mich, ist das eine gängige Praxis? Was ist der beste Weg, um dies umzusetzen?

nd wie heißt diese Technik eigentlich, damit ich danach suche?

22
Dari

Sie könnten eine UUID-Spalte hinzufügen, müssen dies aber nicht (und sollten es auch nicht). Dies ist ein Problem der Präsentationsschicht. Sie würden nicht davon träumen, einen Währungswert von 1.999 USD sowie 1999 zu speichern.

Sie möchten nur eine Möglichkeit, den Wert für die Anwendung im laufenden Betrieb 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 2-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.

0
Robbie Dee

Ein "alternativer Primärschlüssel" ist ein bekanntes Konzept in der relationalen Datenbankmodellierung. Er wird als "alternativer Schlüssel" oder manchmal auch als "sekundärer Schlüssel" bezeichnet. Der Satz "potenzieller Primärschlüssel" wird als "Kandidatenschlüssel" bezeichnet. 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 die IDs zwischen Groß- und Kleinschreibung unterscheiden sollen oder nicht, ob Sie möchten, dass sie auf einer gedruckten Rechnung lesbar sind, falls jemand muss in der Lage sein, sie auf dem Telefon fehlerfrei zu beantworten, und so weiter.

48
Doc Brown

Die meisten Rechnungen haben eine Rechnungsnummer, die nach den meisten Rechnungslegungsregeln fortlaufend sein muss, oder ein Buchhalter kann die Jahresergebnisse nicht abzeichnen, oder der IRS (oder ein ähnlicher in Ihrem Land) möchte möglicherweise eine vollständige Prüfung Ihrer Registerkarten durchführen.

Ein Benutzer kann 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. Es gibt andere Möglichkeiten, dies herauszufinden, einschließlich der Anforderung Ihrer Jahresberichte bei der Handelskammer.

Ich würde jedoch die Rechnung hinter einem Benutzeranmeldebildschirm sperren, damit nicht jeder sie anfordern kann. Bei der Benutzeranmeldung können sie dann eine Ajax-Methode verwenden, um ihre ausstehenden Rechnungen usw. anzufordern. Dies sichert Ihre Daten, verbirgt die URL durch Ajax (normalerweise kann sich niemand die Mühe machen, die Details des Aufbaus der Ajax-Anfrage zu überprüfen). und Sie steuern, wie die Daten angezeigt und angeboten werden.

9
Tschallacka

Möglicherweise können Sie Hashids verwenden, um genau dieses Szenario zu lösen.

Ihre Datenbank-ID wird in einen kurzen Hash (ähnlich der URL eines YouTube-Videos) codiert, und Sie müssen Ihrer Tabelle keine Sekundärschlüssel hinzufügen.

7
mitchdav

Sie können einen anderen eindeutigen Schlüssel erstellen, sollten dies jedoch nicht. Nicht aus dem angegebenen Grund. Es gibt einfachere Möglichkeiten, die Tischgrößen auszublenden.

Speichern von N_8Zk241vNa kostet 12 Bytes 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 Speicherplatz und in der Laufzeit fast nichts. 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 Chiffre mit einer Blockgröße von 64 wie DES oder 3DES gibt Ihnen 11 Zeichen, genau 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 Hibernate und einem Hi-Lo-Algorithmus verschwindet dieses Problem.

3
maaartinus

Ein anderer 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 die/Rechnungen /: f (id) wobei f(id) ist eine Funktion der ID.

Die benutzerdefinierte Route ist dafür verantwortlich, eine Anforderung der richtigen Aktionsserverseite zuzuordnen.

0
user260171

Dies ist eine völlig akzeptable Praxis, 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 ist wie der, den 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 sie einfach erraten werden kann. Zusätzlich haben Sie eine zufällige eindeutige Kennung oder Referenznummer als AK, und das ist die ID, die Sie dem Benutzer präsentieren

0
Alex Schievink

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 stimme zu, dass es am besten ist, Ihre Datenbank-Interna nur dann verfügbar zu machen, wenn es einen sehr guten Grund gibt.

Da sich die Frage im Zusammenhang mit Rechnungen und Zahlen befindet, kann es sinnvoll sein zu untersuchen, wie die Buchhaltungsbranche erwartet, dass Rechnungsnummern aussehen: http://smallbusiness.chron.com/assign-invoice-numbers-52422. html

Es mag unübersichtlich erscheinen, eine interne ID zu haben, die ein Primärschlüssel ist, und ein weiteres eindeutiges Feld mit der sichtbaren Rechnungsnummer der Anwendung/des Kunden. 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 unverändert lassen und die nicht interne Rechnungsnummer neu nummerieren.

Im Idealfall bemühen Sie sich, Tabellen nicht auf Schlüsseln/Fremdschlüsseln zusammenzubinden, die sich wahrscheinlich ändern, und halten Ihre internen Tabellen und Beziehungen für die App-Ebene transparent.

0
Thomas Carlisle

Tue es.

Dies unterscheidet sich nicht von einem "Slug" -Feld, das Blog-Artikel und dergleichen häufig haben - eine einzigartige Möglichkeit, auf den vom Primärschlüssel getrennten Datenbankdatensatz zu verweisen, der für die Verwendung in einer URL geeignet ist. Ich habe noch nie jemanden dagegen argumentieren hören.

0
RemcoGerlich

IMHO ist das Erstellen von zwei verschiedenen Primärschlüsseln nicht möglich. Natürlich können Sie diese UUID in eine Datenbank 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 diese Spalte setzen, aber der Primärschlüssel ist (im Wesentlichen) ein einzelner Index innerhalb 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 Verarbeitungskomponente zum Abfragen von Daten nach PK sowie eine andere eindeutige Spalte erstellen. Wenn Sie die Anfrage nach "/ rechnungs/..." bearbeiten, überprüfen Sie einfach den Parameter. Wenn es sich um eine Ganzzahl handelt, suchen Sie die ID, andernfalls suchen Sie nach uuid. Oder Sie können die UUID-Suche als Fallback verwenden, wenn die ID-Suche nichts gefunden hat.

Und zum Generieren einiger "zufälliger" Benutzeroberflächen: Warum nicht so etwas wie "ID nehmen, Konstante hinzufügen, in Hexadezimal konvertieren". Die Eindeutigkeit der ID führt zur Eindeutigkeit der UUID. Die Hexadezimalzahl ist für normale Sterbliche schwerer zu lesen. Durch Hinzufügen einer Konstanten wird vermieden, dass die UUID wie 00000001 ist.

0
Jarda

Wenn beide Schlüssel auf dieselbe Tatsache verweisen und niemals kollidieren würden. Warum leiten Sie den anderen Schlüssel nicht mithilfe einer Skalarfunktion vom Originalschlüssel ab, mit der ein benutzerdefinierter Hashcode für Ihren Originalschlüssel erstellt wird?.

alternativ können Sie eine Anhangszuordnungstabelle 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. Je mehr Sie Indizes hinzufügen, desto langsamer werden die Einfügungen.

0
A.Rashad