Creazione di una chiave primaria secondaria in un database per alcune tabelle

22

Ad alcune delle mie tabelle voglio aggiungere "second_primary_key" che sarà uuid o una chiave lunga casuale. Ne ho bisogno perché per alcune tabelle non voglio esporre numeri interi alla mia applicazione web. Cioè, in una pagina "/ fatture" ho una lista di fatture e un link a "/ fatture /: id" dove: id è un numero intero. Non voglio che un utente sappia quante fatture ci sono nel mio sistema, quindi invece di "/ fatture / 123" voglio usare il suo "second_primary_key" in modo che l'url sia "/ fatture / N_8Zk241vNa"

Lo stesso vale per le altre tabelle in cui voglio nascondere l'ID reale.

Mi chiedo, è una pratica comune? Qual è il modo migliore per implementarlo?

E cos'è questa tecnica chiamata dopotutto, quindi faccio una ricerca su di essa?

    
posta Dari 22.08.2017 - 09:51
fonte

11 risposte

0

Potresti aggiungere una colonna UUID ma non hai davvero bisogno (e non dovresti). Questa è una preoccupazione del livello di presentazione. Non sognerebbe di dire, memorizzando un valore in valuta a $ 1,999 e nel 1999.

Vuoi solo un modo per oscurare il valore al volo per l'applicazione. Potresti farlo nell'applicazione stessa o come vista del database.

Dato che stiamo parlando solo di un singolo valore, forse guardiamo alla crittografia a 2 vie come AES o simili - più è leggero e meglio è.

L'hashing potrebbe essere un'altra possibilità: dipende dal fatto che si desideri recuperare il numero della fattura, poiché l'hashing è a senso unico.

    
risposta data 14.09.2017 - 22:43
fonte
48

Avere una "chiave primaria alternativa" è un concetto ben noto nella modellazione del database relazionale, si chiama "chiave alternativa" o talvolta anche "chiave secondaria". L'insieme di "potenziali chiavi primarie" è chiamato "chiavi candidate". Vedi link

Il modo in cui lo implementate dipende completamente da te, soprattutto se vuoi nascondere il numero totale di record. Non esiste un "metodo migliore", dovresti verificare i tuoi requisiti come set di caratteri consentiti o utili, lunghezza massima, se vuoi che gli ID siano maiuscole o minuscole, se vuoi che siano leggibili su una fattura stampata, se qualcuno deve essere in grado di ribellarli al telefono senza errori e così via.

    
risposta data 22.08.2017 - 11:23
fonte
9

La maggior parte delle fatture ha un numero di fattura, che secondo la maggior parte delle regole contabili deve essere sequenziale o un contabile potrebbe non firmare sui risultati dell'anno o l'IRS (o simili nel tuo paese) potrebbe voler eseguire una verifica completa nelle tue schede .

Un utente può dedurre dal numero di fattura quanti clienti hai servito, o da quanto tempo è trascorso prima di aver cambiato la strategia di numerazione sulle fatture.

Quante fatture sono memorizzate nel database non è una misura del totale complessivo delle fatture. Ci sono altri modi per scoprirlo, inclusa la richiesta dei rapporti annuali della Camera di commercio.

Vorrei tuttavia bloccare la fattura dietro una schermata di accesso utente, quindi non tutti possono richiederla. Quindi, nel login dell'utente, possono utilizzare una metodologia Ajax per richiedere fatture in sospeso, ecc. Questo protegge i tuoi dati, nasconde l'URL di ajax (nessuno può essere di solito preso la briga di guardare i dettagli di come è stata costruita la richiesta ajax) e tu controlli come vengono visualizzati e offerti i dati.

    
risposta data 22.08.2017 - 13:48
fonte
7

Potresti riuscire a utilizzare hashids per questo scopo, è stato progettato per risolvere esattamente questo scenario.

Codificherà l'ID del tuo database in un breve cancelletto (simile all'URL di un video di YouTube) e non ti richiederà di aggiungere alcuna chiave secondaria al tuo tavolo.

    
risposta data 22.08.2017 - 16:50
fonte
3

Puoi creare un'altra chiave univoca, ma non dovresti. Non per il motivo indicato. Esistono modi più semplici per nascondere le dimensioni della tabella.

La memorizzazione di N_8Zk241vNa costa 12 byte per riga nella tabella e ancor più nell'indice. È abbastanza dispendioso per quello di cui hai bisogno.

Crittografare il valore intero id non richiede spazio e quasi nulla nel tempo di esecuzione. Il modo in cui lo fai dipende dal tuo linguaggio di programmazione e / o dal tuo database.

Si noti che con AES si ottiene un numero intero a 128 bit, che significa 22 caratteri in base64, probabilmente più di quanto si desideri. Un cifrario con una dimensione di blocco di 64 come DES o 3DES ti dà 11 caratteri, proprio come vuoi.

Utilizza chiavi diverse per tabelle diverse.

Se tutto ciò di cui hai bisogno è nascondere le dimensioni delle tabelle, puoi usare una sequenza comune per tutte le tabelle. Nota che potrebbe trattarsi di un collo di bottiglia se ci sono frequenti inserimenti in molte delle tue tabelle. Con qualcosa come Hibernate e un algoritmo Hi-Lo, questo problema scompare.

    
risposta data 22.08.2017 - 13:35
fonte
0

IMHO che crea due chiavi primarie diverse non è possibile. Ovviamente puoi mettere uuid in un DB per averlo come "alias" per la chiave primaria corrente. Puoi mettere un indice sopra quella colonna con un vincolo univoco, ma la chiave primaria è (dalla sua essenza) quella singola all'interno di una singola tabella. Ci può essere una chiave primaria composta, ma non è quello che stai cercando.

Quindi suggerisco di metterlo lì, ma averlo solo con l'indice. È possibile creare un componente di gestione per l'interrogazione dei dati tramite PK e un'altra colonna univoca. Quando si gestisce la richiesta di "/ fatture / ..." basta controllare il parametro - se è intero, cercare l'ID, altrimenti cercare uuid. Oppure puoi avere la ricerca uuid come fallback quando la ricerca ID non ha trovato nulla.

E riguardo alla generazione di alcuni uuids "casuali": perché non qualcosa come "prendere ID, aggiungere CONSTANT, convertire in esadecimale". L'iniquità dell'ID fornirà l'unicità di uuid, il numero esadecimale è più difficile da leggere per i normali mortali + l'aggiunta costante eviterà di avere uuid come 00000001.

    
risposta data 22.08.2017 - 10:34
fonte
0

Se entrambe le chiavi puntano allo stesso fatto, non si scontreranno mai. Perché non derivare l'altra chiave da quella originale utilizzando una funzione scalare che creerebbe un codice hash personalizzato della tua chiave originale.

in alternativa, puoi creare una tabella di mappatura degli allegati, che memorizzerebbe entrambe le versioni della chiave. questa tabella fungerà da dizionario per cercare la chiave secondaria.

Secondo la mia comprensione, le chiavi sono indici impliciti e più si aggiungono gli indici, più gli inserimenti più lenti saranno.

    
risposta data 22.08.2017 - 16:16
fonte
0

Un altro approccio per il tuo caso d'uso particolare è che invece di modificare il database e l'applicazione, puoi semplicemente creare un percorso personalizzato per le fatture in modo che le / fatture /: f (id) dove f (id) sia una funzione di l'id.

Il percorso personalizzato è responsabile per associare una richiesta all'azione corretta lato server.

    
risposta data 22.08.2017 - 18:54
fonte
0

È una pratica totalmente accettabile, chiamata anche "Alternate Key" (AK). Fondamentalmente l'AK è un altro indice univoco o un vincolo univoco.

Puoi persino creare vincoli di chiave esterna in base al tuo AK.

Un possibile caso d'uso è come quello che hai spiegato: hai un PK in cluster su un numero di identità sempre crescente, ma non vuoi che questo numero venga visualizzato o usato come criterio di ricerca, perché può semplicemente essere indovinato. Quindi, in aggiunta, hai un identificatore univoco casuale o un numero di riferimento come AK, e questo è l'ID che hai presente all'utente

    
risposta data 22.08.2017 - 20:11
fonte
0

Esistono diversi tipi di chiavi / indici. Una chiave primaria è uno speciale indice univoco e, poiché le risposte dicono che puoi sicuramente creare un'altra chiave univoca. E sono d'accordo che è meglio non esporre le parti interne del database a meno che non ci sia un buon motivo.

Poiché la domanda è nel contesto di fatture e numeri, potrebbe essere utile analizzare come il settore contabile si aspetta che i numeri di fattura siano visualizzati: link

Potrebbe sembrare complicato avere un ID interno che è una chiave primaria e un altro campo univoco con il numero di fattura visibile dell'applicazione / cliente. Ma non è così impuro quando, ad esempio un anno lungo la strada, il cliente desidera adottare un nuovo schema di numerazione delle fatture. In tal caso non disturbare l'id interno e le sue relazioni in altri tavoli per rinumerare l'intera sfera di cera. Manterresti il tuo ID interno così com'è e riscrivi il numero di fattura non interno.

Idealmente, ti sforzi di non legare le tabelle alle chiavi / chiavi esterne che probabilmente cambieranno e mantieni trasparenti le tabelle e le relazioni interne sul livello dell'app.

    
risposta data 22.08.2017 - 20:28
fonte
0

Vai per questo.

Questo non è dissimile da un campo di "slug" che gli articoli del blog e simili hanno spesso - un modo unico di riferirsi al record del database separato dalla chiave primaria, adatto per l'uso in un URL. Non ho mai sentito nessuno discutere contro quelli.

    
risposta data 23.08.2017 - 14:25
fonte

Leggi altre domande sui tag