Motivo per non utilizzare il numero nullable in Oracle?


12

La nostra azienda si interfaccia con un'altra società di software per un progetto congiunto e ci è stato detto che, se un valore particolare non dovesse essere visualizzato, dovremmo passare un -5000 (il loro valore di sentinella arbitrario); il motivo è che nessuna colonna numerica nel loro database Oracle supporta valori null, su raccomandazione del loro (ora ex) sviluppatore Oracle. Questa azienda scrive anche la maggior parte del loro codice in VB6 (passando lentamente a VB.NET, che è un altro argomento per un altro giorno ...). Per pura curiosità, c'è qualche motivo valido per questa raccomandazione? Non riesco a pensare a nessuno dalla mia parte.

--- modificare

Grazie per il feedback a tutti. Ho posto la stessa domanda su CodeProject.com ( link ) e ho ricevuto feedback molto simili. Sembra che l'unica volta in cui si possa iniziare a giustificare questa pratica è correlata alle chiavi esterne e posso affermare che non usano chiavi esterne in nessuna parte del sistema. Lo sviluppatore che ha preso questa decisione (una volta lavoravo in quella società) ha molta più esperienza di me, quindi volevo assicurarmi che non ci fosse una ragione valida per questo prima che la derisione seguisse.


2
Intendi altro che "questo è ciò che specifica la loro API"?
Robert Harvey,

Sì, sono più curioso del perché la loro API lo specifica in primo luogo; c'è una ragione per questa pratica, o è solo un po 'di follia?

3
Lunazia di primissimo ordine!
Philᵀᴹ

Risposte:


17

Realisticamente, il requisito è pazzo. Come tutte le grandi idee folli, tuttavia, è probabilmente basato su una pepita di ragionevole ragionevolezza portata lontano dal contesto da persone che non hanno alcuna comprensione della logica sottostante.

Può essere ragionevole progettare uno schema di database in modo che non NULLsiano consentiti valori. Se lo fai, tuttavia, ti impegni a un livello di normalizzazione in cui ogni elemento non necessario viene suddiviso in una tabella separata con un riferimento di chiave esterna appropriato al padre. Spesso non viene fatto in pratica, ma nei casi in cui ha senso farlo, ci possono essere benefici.

Se hai intenzione di progettare uno schema di database in modo tale che non NULLsiano consentiti valori, non ha senso lasciare che richiedano valori magici per indicare che qualcosa è sconosciuto. Ciò introduce tutti i problemi che hanno i NULLvalori consentiti e aggiunge un codice aggiuntivo per verificare i valori magici che devono essere ripetuti ovunque. Non ha senso sviluppare un'API che richieda il passaggio di valori magici indipendentemente dal design del database: se hai intenzione di confondere il tuo codice con controlli per valori magici, non dovresti davvero lasciare che la follia si propaghi ad altri sistemi .


+1 e il codice aggiuntivo per verificare i valori magici non possono utilizzare funzioni ben note come COALESCE()- quindi diventa ancora più complicato.
ypercubeᵀᴹ

E i valori devono essere archiviati in qualsiasi indice su quella colonna. Gli indici non devono memorizzare valori nulli.
Tripp Kinetics,

15

Non esiste un motivo valido per utilizzare un valore magico anziché NULL. Questo potrebbe essere il processo mentale di qualcuno che crea questo casino. Scrivono qualcosa del genere:

 SELECT c1, c2 FROM t1 WHERE c3 < 30;

Quando questo non restituisce i risultati che si aspettano, si rendono conto che non include NULL e dovrebbero scrivere questo:

SELECT c1, c2 FROM t1 WHERE c3 < 30 OR c3 IS NULL;

Non vogliono scrivere o dimenticare in futuro di scrivere questo, quindi escogitano la soluzione di creare tutti i NULLS -5000. Magicamente la loro query originale gestisce i NULL senza alcuna modifica. Quello che non capiscono è che ora qualcuno che vuole escludere questi valori deve scrivere questo:

SELECT c1, c2 FROM t1 WHERE c3 < 30 AND c3 <> -5000;

O se volessero questi valori e stessero cercando un intervallo più alto:

SELECT c1, c2 FROM t1 WHERE c3 > 40 OR c3 = -5000;

Inoltre, potrebbero non rendersi conto che quanto segue non sarebbe più significativo:

SELECT c1, c2 FROM t1 WHERE c3 IS NULL;

Invece una persona deve ricordare il valore magico. Con ogni tipo di dati utilizzato devono ricordare più valori magici, ad es. 1/1 // 1900, "Z", -5000. Inoltre, quando il valore magico è nei dati, devono anche ricordare valori magici alternativi.

Quindi, per un caso specifico, semplifica il codice a spese di altri casi, per non parlare dello spazio su disco, della dimensione dell'indice, dell'analisi delle query, della coerenza, ecc.


8

È una follia assoluta e non c'è giustificazione per questo. NULLè stato creato per rappresentare l'assenza di un valore e per usare un valore reale come -5000 è in crisi.

Di solito non scriverei una risposta così breve, ma la domanda merita di essere una delle più visibili su dba.se e più risposte meglio è.


5

Ci ho pensato per un po 'cercando di essere positivo e giustificando la necessità di utilizzare un valore arbitrario anziché un valore nullo e sembra (almeno per me) non esserci una ragione valida per questo, tranne forse in un set di dati di data mining chiuso per migliorare e semplificare le prestazioni e le query, e quindi solo nei casi in cui i numeri non sono valori che potrebbero distorcere i dati. Anche questo dovrebbe essere considerato attentamente. In tutte le situazioni del mondo reale dare valore a null non è una buona pratica. Questo trasforma una definizione di colonna NOT NULL dal tuo amico al tuo nemico poiché non è proprio vera.

È una cosa molto diversa affermare che la nostra applicazione non dovrebbe accettare un valore NULL per alcune (o anche tutte) le colonne. Questa è una buona pratica sensata e ci sono benefici ben documentati nel non consentire valori nulli (chiavi e indici e calcoli statistici per esempio). Tuttavia, assegnare un valore a "sedere nel posto" di un null non è affatto lo stesso. È l'asta per la tua schiena, poiché devi prima selezionare un valore che non verrà mai usato, filtrare questo valore come faresti con il valore nullo e ricordati di non usarlo in calcoli e riepiloghi e rimuoverlo da feed di dati esterni . Questo è almeno altrettanto grave se si utilizza un null per rappresentare un valore reale, che è quello che ti dici di evitare, ma non lo sei.

La maggior parte dei problemi causati da null, una volta compresi, può essere risolta (migliore normalizzazione, indici basati su funzioni o bitmap o con un semplice WHERE x NOT NULL). Pensi che in qualche grande Telco o su Amazon nel meeting delle performance mensili alcuni DBA stiano delineando questo grande piano per accelerare un po 'le query sui loro enormi set di dati "sostituendo null con un valore arbitrario, qualcosa come -5000, o altro - Sono aperto sul valore ... ". O pensi che trascorrano il loro tempo divisi tra una migliore progettazione dell'applicazione per filtrare i null indesiderati e l'ottimizzazione delle query in base ai dati effettivi che ricevono ? Va bene, forse un incontro mensile è un po 'ottimistico, ma ogni volta che succede posso assicurarti che "Sostituire i valori null con -5000 (o qualsiasi altra cosa) per una migliore API" non è un punto dell'ordine del giorno.

Per me va bene dire che non accetterò i dati mancanti (devi avere un'età o un prezzo o un codice di regione o altro) e a volte anche bene dire per questa colonna c'è un valore predefinito che verrà inserito se non metti qualcos'altro. Non va bene mettere da parte un valore che significa null. Pensa ai campi di secondo nome come esempio. A volte questi non esistono poiché i genitori sono troppo pigri per riempire tutte le caselle. Aggiungiamo "nessuno" o "mancante" o "sconosciuto" ai nostri dati per migliorare le nostre ricerche? No perché potrebbero esserci persone strane che cambiano il loro nome in questi valori e quindi quando stampiamo i dati non sappiamo se dobbiamo includerli o meno. È un esempio semplice, ma di vasta portata. Conosciamo NULL e abbiamo prevedibili funzioni integrate per gestirlo. Non puoi codificarlo meglio.

Se nessuna risposta (o NULL) non è una risposta valida alla richiesta di input, non consentirla nell'applicazione o nel database, se è una buona risposta, è necessario consentirla sia nell'applicazione che nel database e gestire come una risposta valida. Se fa parte di una serie di risposte valide, è necessario progettare il database per memorizzarlo. Dopo tutto ciò che non dici, ehi, i campi numerici sono così noiosi che consente di memorizzare i numeri in BLOB e utilizzare le immagini di animali selvatici per rappresentare ogni numero, perché è matto (bello ma matto). Inoltre non decidiamo che non ci piace la lettera B, e come un incubo crudele di Sesame Street sostituirla con un # nei nostri dati. Se B non è una risposta che vogliamo, diciamo all'utente "Ehi, non puoi inserire una B qui". Quindi perché trattare null in modo diverso?

Quindi evita i null che non vuoi a livello di applicazione e gestiscili nel tuo database dove li accetti altrimenti sicuro come giraffe + giraffe = ippopotamo i tuoi inutili conflitti di dati ti metteranno nei guai.


2
I miei genitori non erano pigri e comunque non ho un secondo nome. Non tutte le persone vivono negli Stati Uniti.
ypercubeᵀᴹ

1
Doveva essere un esempio spensierato, senza offesa. Ci sono, naturalmente, molte persone senza secondo nome (il primo punto) per molte ragioni abbastanza valide (il punto principale). Nulla in questa colonna non dice nulla sul perché mancasse. Non sono sicuro del tuo punto di vista geo-politico: non vivo negli Stati Uniti, ma in realtà ho un secondo nome. Immagino sia difficile fare ipotesi basate sui dati mancanti.

Nessuna offesa. Ho effettivamente votato la tua risposta. Penso che tu abbia colto nel segno il tuo punto principale che c'è differenza tra non accettare / consentire Nulls nel database e sostituire Nulls con un valore magico.
ypercubeᵀᴹ

5
Mi piacerebbe se il mio secondo nome fosse "-5000"! : D
Philᵀᴹ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.