Perché dovrei usare le tabelle di ricerca?

1

Questa domanda ha confermato, cosa di cui ero già a conoscenza - invece di memorizzare direttamente le stringhe nella tabella, dovrebbe piuttosto usare interi o enumerazioni e unirli a una tabella di ricerca, per ottenere, di conseguenza, una stringa, che effettivamente desidero.

Ma perché dovrei usare la ricerca? Se ottengo un numero intero dalla tabella base , ciò che mi impedisce (o cosa dovrebbe impedirmi) di caricare i valori ricerca dal file (ad esempio un array associativo memorizzato nel testo file o direttamente in .php file, in caso di PHP) e usandoli in questo modo? Non è più veloce?

Sto cercando di rendere generale questa domanda (è per questo che chiedo sui programmatori, non su SO), ma dato che sono un programmatore PHP, l'esempio basato su PHP è l'unico che mi viene in mente. Supponiamo che io abbia un file contenente:

<?php
    return array
    (
        '1'=>'male',
        '2'=>'female',
        '3'=>'unspecified',
        '4'=>'unknown'
    );
?>

Perché non dovrei usarlo come "soluzione di ricerca", invece di replicare lo stesso set di dati nella tabella di ricerca?

    
posta trejder 21.06.2015 - 10:30
fonte

3 risposte

9

Stai suggerendo un join sul lato client : recupera alcuni dati dal database tramite una query, quindi nel codice esegui ulteriori join tramite le tabelle di ricerca caricate dai file.

Questo sarà quasi certamente più lento, e sicuramente più complesso del semplice fare il join nel database. Pensaci: perché dovresti essere in grado di scrivere la tua logica di join per essere più veloce di ciò che accade in un database? A meno che tu non abbia requisiti molto specifici (ad esempio vuoi ridurre al minimo la quantità di dati restituiti dal database) non vedo alcun vantaggio per l'esecuzione del join sul lato client.

    
risposta data 21.06.2015 - 11:32
fonte
2

Penso che tu stia confondendo alcune cose diverse qui.

1: normalizzazione del database.

La risposta alla domanda a cui si fa riferimento consiste nel normalizzare i dati ripetuti in una seconda tabella con un FK. La chiave necessaria è una int e verrà ripetuta, quindi se i tuoi dati sono SOLO, la chiave è già normalizzata.

2: interi come chiavi (a causa dello spazio?)

Suggerisci che l'utilizzo di un int è migliore come chiave, ma è contessivo. I GUID sono un'altra opzione e le stringhe possono essere utilizzate.

3: valori enum persistenti

Quindi un enum verrà valutato come int, ma se si memorizza solo int - > rapporto di nome nel tuo codice e non nel db hai potenziali problemi se cambi mai l'enum.

Se replichi l'enum in una tabella di ricerca, raddoppi il problema e avrai bisogno di sincronizzare il codice con db.

Solitamente è meglio mantenere un enum come stringa, poiché questo ha il significato e un enum non è una "stringa di visualizzazione" che cambierà, sarà tradotta ecc.

Quindi prendendoli insieme, dove hai un poco oggetto con un campo enum. Raccomando di memorizzare il campo come una stringa in una tabella db con colonne che corrispondono alle proprietà degli oggetti. Vale a dire

persona

Id - > alcuni guid

Nome - > fred

Sesso (ENUM) - > maschio

Dove la proprietà è una classe con più di una proprietà, dovresti usare un FK su un'altra tabella. Vale a dire.

indirizzo (classe) - > (addressId col) some guid

Se tratti l'enum come una classe e la sposti in una tabella di ricerca, puoi ottenere risparmi di spazio se hai molte righe e pochi valori enum.

Sesso (enum) maschile - > (sexId [breve]) 0

sesso

id [breve]

Nome [varchar (50)]

Ma l'id e la relazione FK dovrebbero essere puramente al livello del DB. Dovresti ancora restituire il Nome dalle query e deserializzare quella stringa di nuovo al tuo enum piuttosto che mappare l'Id breve al tuo enum int.

Tuttavia, si tratta di un'ottimizzazione piuttosto che di una normalizzazione e si risparmia solo spazio, il che, come dice la domanda di riferimento, è economico. Personalmente tendo a lasciare questo tipo di cose agli amministratori di database

Consideriamo ad esempio che è necessario un insert sproc, che prende la stringa enum, controlla la tabella di ricerca per trovare l'id breve, aggiunge l'enum alla tabella di ricerca, se necessario, e quindi usa l'id breve per l'insert. Quindi c'è un lato negativo nell'ottimizzazione e un rialzo

    
risposta data 21.06.2015 - 11:32
fonte
2

Esistono diversi motivi per cui vuoi archiviare le tue ricerche in un database.

  1. integrità referenziale. Se si imposta correttamente il database NON è possibile inserire una riga a meno che non esista la ricerca (vincolo di chiave esterna). Al momento non c'è nulla che mi impedisca di inserire il numero intero 0 o 9999 e la ricerca della matrice fallirà.

  2. Elimina e cancella in cascata dipendenze orfane. Relativo al punto 1. Se cancello # 3 dalla tabella di ricerca, mi aspetto che causi un errore perché le righe parent ancora fanno riferimento a # 3, o le righe di riferimento da eliminare o il riferimento a chiave esterna da annullare. Se una di queste cose non accade, ora hai riferimenti ciondolanti nel tuo database!

  3. Più facile da cambiare. Se hai bisogno di cambiare 1 & 2 per essere 'uomo' & 'donna' avresti bisogno di ricostruire e ridistribuire il tuo codice. Se è nel database, aggiorna semplicemente le ricerche. Avrai un problema simile quando aggiungi nuovi sessi.

  4. Complessità extra: per trovare tutti i tuoi uomini, devi cercare che cosa "maschio" corrisponda all'array, quindi includere quel valore in una query che invii al database. Se tutto è archiviato nel database, può essere eseguito in una query e ottimizzato dal motore di query:

    SELEZIONA people.id, people.name, genders.name Dalla gente INNER JOIN sessi   ON peoples.gender_id = gender.id WHERE genders.name = 'male'

  5. Se i dati non sono nel database non puoi fare le cose con il database! Cosa succede se il tuo cliente ha bisogno dell'elenco di persone ordinate per nome di genere? Se si trova in una tabella di ricerca, è semplice come:

    SELEZIONA people.id, people.name, genders.name Dalla gente INNER JOIN sessi   ON peoples.gender_id = gender.id DOVE genders.name = 'male' ORDINA BY genders.name ASC

risposta data 05.02.2018 - 16:43
fonte

Leggi altre domande sui tag