Dovrei aggiungere un "significato booleano" a un'altra colonna?

5

È una buona o cattiva pratica aggiungere un "significato booleano" ad altri campi?

Per esempio, diciamo che sto modellando eventi, che potrebbero essere ricorrenti o meno. Posso avere:

  • Una colonna booleana che viene conservata se l'evento è ricorrente
  • Una colonna intera che contiene l'intervallo di ripetizione

o

  • Solo la colonna intera per l'intervallo di ripetizione e usa zero o null per indicare che l'evento non è ricorrente.

Il vantaggio di quest'ultimo è che abbiamo bisogno di un campo in meno nella tabella. Lo svantaggio che mi viene in mente è che a livello di applicazione è più chiaro controllare if(event.isRecurring()) rispetto a if(event.getRepetitionInterval() != null) .

C'è una buona pratica in casi come questo?

    
posta garci560 18.04.2016 - 13:52
fonte

6 risposte

6

Tendo a "Solo la colonna intera per l'intervallo di ripetizione, e uso zero o null per indicare che l'evento non è ricorrente" opzione e usa NULL.

Semantica di NULL a parte, con 2 colonne che interrompono il 3 ° modulo normale perché "l'intervallo di ripetizione" dipende dalla colonna booleana.

E quindi quasi garantisci che qualcuno utilizzerà il valore dell'intervallo di ripetizione senza controllare il valore booleano.

Io userei NULL invece di un valore sentinella: NULL come in "nessun dato" piuttosto che "indefinito"

    
risposta data 18.04.2016 - 14:09
fonte
5

Entrambe le tecniche hanno i loro pro e contro.

L'utilizzo di un flag e un valore indica che si utilizzano due campi in cui si farebbe uno. Di solito questo è solo un problema se sei estremamente corto nello spazio, ad es. nei sistemi embedded. Significa anche che stai memorizzando un valore in cui non è ovvio che potrebbe non essere applicabile. Prima o poi qualcuno vorrà guardare solo nell'intervallo e assumere che qualcosa accada ogni 30 minuti, tuttavia non è vero.

Utilizzare un valore sentinella con un significato speciale significa una logica più complicata, come hai detto tu.

Entrambi sono fatti regolarmente. Non esiste una "best practice" su cui le persone siano d'accordo su ciò che fanno su altre cose (ad esempio "non abusare dei campi VARCHAR come elenchi"). Pertanto, cosa fare dipende dalle particolarità del tuo progetto. Quanto sei a corto di spazio? Quanto sono diligenti i programmatori di applicazioni che riutilizzeranno questa interfaccia? Sai meglio di noi.

    
risposta data 18.04.2016 - 14:00
fonte
1

Sono d'accordo con la risposta di @ Kilian e ho pensato di aggiungere qualcosa alla discussione:

Ciò che descrivi è come catturare quella che sarebbe naturalmente una situazione di sottoclasse in OOP e mapparla al modello relazionale.

In OOP, potresti avere un evento (non ricorrente) e un evento ricorrente sottoclasse. O un evento astratto con due sottoclassi di eventi unici e eventi ricorrenti.

Come altro esempio, prendi una nozione di record dei dipendenti. In OOP avremmo forse un dipendente astratto con due sottoclassi, una per il CEO che, per definizione, non ha un manager dei dipendenti identificato e tutti gli altri dipendenti che devono avere un altro dipendente come manager. (Oppure potremmo fare a meno della classe astratta).

Nei sistemi relazionali, questo tipo di semplice sottoclasse causa un sacco di mal di testa, e probabilmente la migliore mappatura consiste nell'utilizzare una singola tabella dei dipendenti con un campo manager (da fk a self), e consentire a NULL il campo del direttore del CEO.

Codd descrive due usi di NULL: "mancante e applicabile" e "mancante e non applicabile". Il primo significa che sarebbe valido se avessimo i dati (semplicemente non ce l'abbiamo), mentre il secondo indica che questa colonna non si applica a un record di questo tipo.

Purtroppo, i due usi di NULL non sono distinti nei database SQL.
(Inoltre, non esiste un'indicazione formale su quale sia il vero tipo di riga, devi solo dedurlo dai valori nulli nelle colonne facoltative. Se ci fosse, potremmo forse dire che la colonna deve essere NULL per le righe ) di tipo CEO e non deve essere NULL per le righe regolari dei dipendenti.)

Come dice @Kilian, qui non esiste una buona pratica concordata.

Tuttavia, se ponessi la tua domanda da una prospettiva OOP, penso che troverai risposte che consigliano di utilizzare la sottoclasse.

Quindi i problemi nella mia mente sono quelli della mappatura relazionale. Nei mapping relazionali di tali situazioni, NULL viene comunemente utilizzato per campi facoltativi che non si applicano a causa della (sotto) digitazione. In questo caso, NULL significherebbe Codd's Missing e Non applicabile perché per un evento una volta il campo di ricorrenza non è applicabile.

    
risposta data 18.04.2016 - 17:07
fonte
1

Se posso essere così audace da suggerire provvisoriamente una terza soluzione se volessi veramente limitare il numero di colonne usate:

Un valore positivo potrebbe essere usato per indicare che un evento è valido. Un valore negativo potrebbe significare che un evento non è attualmente valido. Il vantaggio di un valore negativo è che potresti vedere a che cosa era stato inizialmente impostato il periodo di ripetizione.

La commutazione del flag diventa anche semplice come moltiplicare per -1;

    
risposta data 18.04.2016 - 17:22
fonte
1

Rimanere con uno. Sebbene sia abbastanza semplice da restituire un po 'dal db quando si desidera solo sapere se l'attività viene ripetuta, è necessario gestire le regole nell'applicazione per mantenere sincronizzati questi valori. Hai davvero sprecato spazio e reso il database più complicato del necessario. Ciò fa sorgere la sua brutta testa in azienda quando l'integrazione, il reporting, il data warehousing mettono più richieste sul database al di fuori del mondo di una singola applicazione.

    
risposta data 18.04.2016 - 21:09
fonte
0

Penso che l'opzione 2 sia sufficiente poiché è chiaro dal nome della variabile che è il conteggio delle ripetizioni e se è superiore a 0, dovrebbe ripetersi. Userò 0 invece di NULL.

    
risposta data 18.04.2016 - 14:18
fonte

Leggi altre domande sui tag