2011-01-12 9 views
8

Ho diversi tavoli come Buyers, Shops, Brands, Money_Collectors, e.t.c.Qual è il metodo migliore per memorizzare valori predefiniti nel database?

Ciascuno di questi ha un valore predefinito, ad es. il valore predefinito Buyer è David, il valore predefinito Shop è Ebay e così via.

Desidero salvare quei valori predefiniti in un database (in modo che l'utente possa modificarli).

Ho pensato di aggiungere la colonna is_default a ciascuna delle tabelle, ma sembra essere inefficace perché solo una riga in ogni tabella potrebbe essere l'impostazione predefinita.

Quindi ho pensato che il migliore sarebbe avere la tabella Defaults che conterrà tutti i valori predefiniti. Questa tabella avrà 1 riga e N colonne, dove N è il numero dei valori di default:

Defaults table: 

buyer  shop  brand  money_collector 
-----  ----  -----  --------------- 
David  Ebay  Dell  NULL (no default value) 

Ma questo sembra non essere l'approccio migliore poiché la struttura della tabella cambia quando viene aggiunto un nuovo valore predefinito.

Quale sarebbe l'approccio migliore per memorizzare i valori predefiniti?

+3

Prima di tutto, cosa fa il valore predefinito? Secondo è un valore predefinito per tabella o uno per tabella per utente? Quando dici (in modo che l'utente possa cambiarli) sembra che CIASCUNO abbia un set di valori predefiniti. O vuoi dire che un utente ADMIN può cambiare il valore predefinito? Ultimo perché sei contrario a una colonna is_default? Quale sarebbe il problema con quello? –

+0

Nel mio caso, ogni tabella memorizza tutti i valori possibili di una casella di selezione. C'è un valore predefinito in ogni casella di selezione (o zero se non esiste un valore predefinito). Non mi dispiace per gli utenti. Supponiamo che ci sia un solo utente (come admin) che può modificare il valore predefinito. Per quanto riguarda la colonna 'is_default': supponiamo che ci siano 50 negozi (selezionare la casella con 50 possibili valori). In questo caso, per memorizzare il negozio predefinito sono necessari 50 campi booleani, anziché 1. In altre parole, non voglio occupare spazio. Non dovrei preoccuparmi dello spazio durante il salvataggio dei dati in un database? –

+0

Come vuoi che funzioni di default? È per l'interfaccia utente, in modo che la casella di selezione Negozi selezioni su Ebay? O è per il back-end del database, in modo da memorizzare Ebay per il negozio se l'utente non ha selezionato un negozio? –

risposta

18

Giusto per essere chiari.

Il modo migliore è con una colonna su ogni tabella da cui provengono i dropdown.

ed ecco perché ...

"Non dovrei preoccupare di spazio quando il salvataggio dei dati in un database?"

La risposta breve è no. La risposta più lunga è ciò di cui dovresti preoccuparti è la performance. Concentrarti sullo spazio ti porterà a fare cose molto brutte.

Cattive cose che farete se lo spazio è un problema.

  • Seppellirai il significato in Chiavi primarie. Ad esempio Smart Keys.
  • Proverai a memorizzare più valori in una colonna.
  • Avrete indice troppo poco
  • (Non c'è dubbio che siamo riusciti a creare un elenco di 50 cattive pratiche che fanno risparmiare spazio)

Supponiamo che ci sono 50 negozi (selezionare la casella di con 50 valori possibili) . In questo caso , per memorizzare il difetto del negozio si bisogno 50 campi booleani,

Beh è ONE colonna booleana. Esiste su ogni riga.

Lascia che ti chieda questo. Se hai creato una tabella con 1 colonna di data e inserita 1 riga, quanto spazio utilizzeresti sul disco?

Se hai detto un 7 o 8 byte, sei fuori da circa 1000 volte.

L'unità più piccola di spazio su disco è un blocco. I blocchi sono 8kb tipici (la può essere piccolo come 2kb grande come 32kb, in generale (senza fare i difficili qui, gli attuali limiti non sono importanti))

Diciamo che avete 8Kb blocchi allora la vostra colonna 1, 1 fila il tavolo richiede 8Kb. Se inserisci altre 999 righe, occuperà ancora 8 KB. (Anche in questo caso non fare i difficili v'è in testa per blocco e per riga - è un esempio)

Quindi nel tuo sguardo da tavola con 50 nomi dei negozi, la probabilità che l'aggiunta di 50 byte per la dimensione delle forze di tabella di espandere da 1 blocco a 2 è sottile a nessuno e completamente irrilevante.

D'altra parte, la tabella predefinita occuperà almeno un blocco aggiuntivo. Ma il colpo peggiore a PERFORMANCE è che la chiamata per riempire un menu a discesa avrà bisogno di due viaggi di andata e ritorno al database, uno per ottenere l'elenco, uno per ottenere il valore predefinito. (sì, si può essere in grado di farlo in uno, ma con esso)

Quindi hai salvato esattamente zero spazio e raddoppiato il traffico di rete.

Vedi quello che sto dicendo.


Un'altra cruciale motivo per smettere di preoccuparsi per lo spazio è che stai rinunciando chiarezza. pensa allo sviluppatore che assumerai per eseguire questa app. Quando si unisce al team e guarda il database, immagina i due scenari.

  1. C'è una colonna booleana denominata DEFAULT_VALUE
  2. C'è una tabella senza relazioni con tutto ciò che è denominate Default_Values ​​

gli si chiede di costruire una nuova per con un menu a discesa per il 'negozio'.

Nello scenario 1 trova la tabella del negozio, collega il menu a discesa a una query semplice della tabella e utilizza il campo default_value per selezionare il valore iniziale.

Nello scenario 2, senza un po 'di allenamento, come farebbe a cercare una tabella separata? Forse vedrebbe il tavolo ma al momento dell'assunzione, la tua datamodel ora ha centinaia di tavoli.

Ancora, un po 'forzato ma il punto è saliente. La chiarezza nel database è buona, vale la pena un byte per riga.


roba tecnico

io non sono un ragazzo di MySQL, ma in Oracle, una colonna null alla fine di una fila prendo nessun spazio aggiuntivo. In Oracle vorrei usare un Varchar2 (1) e lasciare 'T' = Default e lasciare gli altri nulli. Ciò avrebbe l'effetto solo utilizzando 1 byte di addizione totale e non per riga. YMMV con MySQL, puoi porre questa domanda separatamente se non puoi rispondere a Google.

Ma il tempo di preoccuparsi è su milioni di file, non centinaia. Qualsiasi tabella che alimenta un menu a discesa non sarà mai abbastanza grande da iniziare a preoccuparsi dei byte extra.

+0

In MySQL NULL VARCHAR (n <= 255) richiede un byte. TINYINT (che è un sinonimo di BOOLEAN in MySQL) farà altrettanto bene. – Mchl

+0

Stai rispondendo a un commento, non alla domanda. –

+0

È ancora un buon consiglio per quanto riguarda la domanda reale. – Mchl

0

Si dovrebbe piuttosto creare aa tabella con due colonne e n righe

Defaults table: 
buyer, David 
shop, Ebay, 
brand, Dell 

In questo modo è possibile aggiungere nuovi valori senza dover modificare la struttura della tabella

+0

Quali tipi dovrebbero essere le colonne? –

+0

'VARCHAR' funzionerebbe meglio suppongo – Mchl

+1

Ma, che succede se alcune tabelle di tabelle contengono numeri o booleani? –

1

Che cosa succede se si crea un XML e quindi negozio che XML nella tabella in una colonna XML. La colonna XML conterrebbe l'XML e l'XML potrebbe contenere tag di tabelle e un sub nodo di valori predefiniti.

0

È possibile creare una tabella catalogo (una sorta di tabella dei metadati) contenente i valori predefiniti come stringhe per le colonne della tabella desiderati. Quindi è possibile utilizzare la funzione convert per ottenere il valore appropriato. Qui di seguito è una definizione di tabella di esempio (Transact-SQL è stato utilizzato):

create table dbo.cat_default_values 
(
    id_column  varchar(30) not null, 
    id_table  varchar(30) not null,  
    datatype  varchar(30) not null,  
    value   varchar(100) not null,  
    f_creation  datetime  not null, 
    usr_creation char(8)  null,  
    primary key clustered (id_column, id_table) 
)  

declare @defaultValueInt int, 
     @defaultValueVarchar varchar(30) 

select @defaultValueInt = convert(int, value) 
    from cat_default_values where id_column = "defColumInteger" and id_table = "table1" 

select defaultValueVarchar = value 
    from cat_default_values where id_column = "defColumVarchar" and id_table = "table1" 
0

cosa si sta cercando di negozio non è meta informazioni dei dati. Prima di tutto, quindi non invento un archivio dati esterno per archiviare questi dati. (Accoppiato con codice aggiuntivo)

Presumo che tu abbia una logica di generazione di sequenza PK (sotto il tuo controllo). Assegnerò un numero magico x e inserirò un record in ogni tabella con _id = x come valore predefinito. Pertanto, se si desidera mostrare all'utente il valore predefinito, è possibile gestire la query in modo uniforme o gestirla nella logica dell'applicazione durante l'inserimento. La cosa buona è che si ha accesso al valore predefinito sempre e senza scrivere alcuna logica aggiuntiva e la logica per mantenere il valore predefinito di una tabella può essere mantenuta usando lo stesso codice (template) (Dalle lezioni apprese W3c dalle informazioni sullo schema di modellazione XML usando DTD.)

Unica cattura è una logica che dovrebbe essere esplicitata utilizzando una documentazione estesa o potrebbe essere imposta con un trigger.

Problemi correlati