Qual è la forma normale di JSON?
Sembrerà una domanda banale, ma mi piace pensare che in realtà sia profonda. La semplice domanda è: "Qual è la forma normale di un tipico oggetto JSON?" Per riferimento, metto un esempio di seguito, ma considera qualsiasi oggetto JSON tipico che hai trattato, si applica la stessa domanda.
Faccio questa domanda teorica per una ragione pratica. In pratica, spesso abbiamo bisogno di convertire oggetti JSON in un insieme di tabelle. Una volta che sono tabelle, le tabelle hanno forme normali misurabili basate su tutte le regole usuali delle forme normali.
Ma arrivare a quei tavoli con la loro forma normale richiede lavoro. Ora, cos'altro "richiede lavoro". Risposta: passare da forme normali inferiori a forme normali superiori. Ciò che non "richiede lavoro", sta scendendo le forme normali. O almeno solo una quantità insignificante di lavoro. Cioè, se ho 6NF, posso manipolare abbastanza rapidamente la mia strada verso qualsiasi forma normale inferiore. Se ho, diciamo 2NF, e ho bisogno di raggiungere almeno 5NF per qualche motivo pratico, ho molto lavoro da fare.
Bene ... poiché è piuttosto difficile portare JSON in una forma normale decente, intuitivamente sembra che debba essere in una forma normale molto bassa. Spero che qualcuno qui possa quantificare quella forma normale di JSON . Molto apprezzato.
Ma non ho ancora fornito la logica più critica. Non è raro che i leader non tecnici chiedano miracoli. Non sto criticando, sappiamo tutti che succede. E il miracolo è qualcosa della forma, "basta scrivere un po 'di codice per trasformare automaticamente JSON in tabelle".
Ma aspetta! Se la mia teoria è corretta e JSON è fondamentalmente 0NF o giù di lì, non puoi automatizzarti per uscirne. Non puoi passare dal NF molto basso di JSON a qualcosa di decente, come 3NF +, in un fashing automatico perché "richiede lavoro". Cioè, ci vogliono esseri umani intelligenti per comprendere il dominio.
Ora, so che alcuni JSON banali possono diventare delle tabelle banali. So che ci sono alcuni strumenti che gestiscono i casi semplici. Ma credo che un convertitore da JSON a tabella generico non sia teoricamente possibile perché JSON è così basso sulle informazioni di normalizzazione (nel rigoroso senso di Claude Shannon), che non è possibile automatizzarlo.
Allora, qual è la forma normale di un tipico oggetto JSON ? E c'è qualche teoria che non ho trovato che già dimostra che non puoi automatizzare la tua uscita da questo.
Grazie!
{
"data": {
"cust1": {
"name": "Jane",
"age": 33,
"address": "Main Street",
"favorites": {
"colors": ["blue", "green"]
}
},
"cust2": {
"name": "Joe",
"age": 44,
"address": "West Road",
"favorites": {
"colors": ["red", "yellow"]
}
}
}
}
Risposte
In breve
JSON è una rappresentazione dei dati secondo una sintassi senza schema senza semantica predefinita. Al contrario, le forme normali sono definite per modelli di dati astratti con una semantica relazionale secondo uno schema fisso. Pertanto, non ha senso applicare forme normali a JSON.
Puoi tuttavia aggiungere uno schema o alcune semantiche al tuo formato JSON che consentirebbe la normale analisi del modulo. Ma nonostante la fattibilità, in genere è di scarso vantaggio, perché un modello a oggetti ricco con oggetti annidati e correlati ha lo scopo di esprimere dati autonomi in modo diverso e più flessibile rispetto a relazioni tabulari predefinite fisse.
Più dettagli
Ha senso?
La forma normale è stata inventata nel contesto dei modelli relazionali dal pioniere Edgar F. Codd . La teoria dell'algebra relazionale non riguarda tabelle e colonne, ma relazioni, attributi e insiemi astratti (che possono essere facilmente rappresentati con tabelle). La forma normale riguarda i dati (tuple) nelle relazioni, la forma dei loro attributi e le loro interdipendenze.
JSON non è un modello ma una rappresentazione di dati con una sintassi precisa ma senza semantica definita. Non esiste una regola su come mettere in relazione due oggetti diversi: ogni JSON rappresenta un oggetto diverso e potrebbe rappresentare una relazione unica, composta da una singola tupla e non correlata ad altre, oppure rappresentare un insieme di istanze correlate di una relazione.
Conclusione: il concetto di forma normale non si applica agli oggetti JSON, perché è definito per un modello relazionale e JSON viene utilizzato in modelli radicalmente diversi (tipicamente il modello di documento).
Potrebbe avere senso?
Niente ti impedisce di aggiungere un po 'di semantica alla sintassi JSON. Non è raro che un insieme di documenti JSON siano correlati e rappresentino tuple della stessa relazione e che elementi che condividono lo stesso nome corrispondano allo stesso attributo e abbiano i loro potenziali valori nello stesso dominio (seguendo uno schema implicito o esplicito ) . In effetti il tuo esempio utilizza JSON esattamente in questo modo.
A che livello dovrebbe essere considerata la forma normale?
- Considera l'oggetto JSON stesso come un singolo attributo in una relazione? Poiché non è elementare / atomico ma costituito da un'aggregazione di più elementi, sarebbe effettivamente UNF.
- Considera JSON come una tupla? Dopo tutto, Codd ha notato che le tuple
(a,b,c)utilizzavano l'ordine dei nomi degli attributi(p1,p2, p3)e non ha mai preteso che una tupla fosse UNF. Quindi{p1:a, p2:b, p3:c}potrebbe essere facilmente considerato 1NF se ciascuno dei suoi elementari / atomici.
Nel secondo caso ci sono però altre domande. Cosa succede se:
- alcuni elementi sono oggetti annidati: questi non sono atomici. Quindi li consideriamo come una relazione separata e applichiamo la regola sulla forma normale in modo ricorsivo, guardando all'interno del JSON incorporato? O concludiamo che qualsiasi JSON contenente un JSON incorporato non è più in 1NF?
- alcuni elementi sono array: neanche questi sono atomici. Quindi consideri che non sia una forma normale o consideri l'array come una relazione definita da tuple racchiuse e quindi guardi ricorsivamente ogni elemento dell'array?
Conclusione: l' adozione di alcune semantiche alla sintassi JSON consente di applicare la normale analisi della forma.
Come estendere la forma normale a JSON?
In pratica, con la semantica definita nella sezione precedente, e scegliendo l'analisi ricorsiva per le domande aperte, definisci una mappatura tra i tuoi JSON e una forma relazionale . In effetti, un gruppo di ricercatori di Yale ha persino pubblicato un documento per descrivere un tale algoritmo .
Con una tale mappatura puoi semplicemente applicare i criteri in forma normale al modello relazionale mappato per classificare la tua rappresentazione JSON.
Ad esempio questo JSON:
{ customers: [ { id:1, name:"Smith", turnover:324233.22},
{ id:2, name:"Wesson", turnover:1600256.00} ],
products: [ { id:1234, label:"Screwdriver", lauched: { y:2019,m:9 }},
{ id:1235, label:"Hammer (row)", lauched: { y:2011,m:1 }} ]
}
potrebbe avere la seguente mappatura relazionale:
TABLE CUSTOMERS (id, name, turnover);
TABLE PRODUCTS (id, label);
TABLE PRODUCT-LAUNCH (product-id, year, month);
Quindi potresti affermare che il JSON è BCNF , perché la mappatura relazionale ha tabelle con solo attributi atomici, che gli attributi di ogni tabella dipendono esclusivamente dalla chiave primaria e non da una parte della chiave primaria, che ovviamente non c'è dipendenza transitiva, .. .
Ma qual è il vantaggio?
Affermo che la forma normale per JSON nella maggior parte dei casi non ha alcun vantaggio :
Se hai scelto una codifica JSON e un database di documenti NOSQL, è perché vuoi liberarti del modello relazionale. Non perché il modello relazionale sarebbe un male (infatti è eccellente e ha ottenuto prestazioni eccezionali nei domini in cui si adatta alle esigenze), ma perché il modello relazionale probabilmente non si adatta alle tue esigenze specifiche. Non ha quindi senso introdurre vincoli artificiali.
Se l'intero progetto è basato su ricchi oggetti di business e non desideri appiattirli e reidratarli tramite un livello ORM , la forma normale non ti aiuterà: i tuoi oggetti sono autonomi e la ridondanza potrebbe non avere importanza allo stesso modo nelle tabelle. Questo è esattamente il motivo per cui di solito viene analizzato caso per caso fino all'implementazione di associazioni uno-a-molti in un database di documenti, ad esempio documenti incorporati e riferimenti ad altri documenti .
Conclusione: il modulo normale in generale non aggiunge vantaggi a JSON, a meno che non sia necessario eseguire ORM. Tuttavia, le riflessioni sulle ridondanze e le dipendenze funzionali, che sono ingredienti fondamentali delle forme normali, possono aiutare a valutare i confini tra gli oggetti.
Zeroth.
First Normal Form dice che i dati dovrebbero essere atomici. Come in un singolo booleano, un singolo numero. Anche una singola stringa è già discutibile. Dipende da come viene utilizzata, una stringa potrebbe essere utilizzata per rappresentare qualcosa, nel qual caso non si tratta più di dati realmente atomici. In effetti, anche un numero potrebbe essere utilizzato in questo modo.
Quindi, in generale , un documento JSON è in Zeroth Normal Form perché è, beh, un documento, non un singolo valore atomico.
Si è possibile avere un documento JSON in prima forma normale, per esempio questo documento:
true
Tuttavia, anche questo documento non è già più in prima forma normale:
{ "property": true }
Non è un valore di dati atomico, è un oggetto contenente una coppia di valori chiave in cui la chiave è una stringa e il valore è un booleano.
Naturalmente, in realtà , la definizione di Prima forma normale parla esplicitamente di Relazioni (o Tabelle), e quindi la vera risposta è: JSON non ha relazioni o tabelle, quindi la domanda stessa non ha senso.
Questa è in realtà una domanda delicata, poiché la normalizzazione e le forme normali sono definite in termini di relazioni e tuple (cioè tabelle con colonne tipizzate). Quindi non puoi davvero parlare della forma normale dei dati delle strutture ad albero come l'esempio di Json.
I dati devono essere in forma tabellare prima di poter parlare in modo significativo di forme normali. Non si può dire che il JSON stesso abbia una forma normale.
Se inserisci il JSON in forma di tabella, ottieni:
id | name | age | address | favorite colors
--------------------------------------------------
cust1 | Jane | 33 | Main Street | blue, green
cust2 | Joe | 44 | West Road | red, yellow
La colonna "preferiti" interrompe la prima forma normale con più valori. Quindi la tabella non è nemmeno nella prima forma normale. Questa è talvolta chiamata forma normale zero o 0NF.
La tua domanda è se una traduzione da JSON a un modulo di tabella 0NF può essere eseguita automaticamente o richiede la conoscenza del dominio. Dirò che può essere fatto automaticamente in diversi modi. Qualsiasi struttura JSON arbitraria può essere rappresentata come tabelle. È solo che le tabelle risultanti saranno 0NF e quindi soggette a tutti i problemi dei dati denormalizzati. Quindi non è qualcosa che consiglierei.
Un esempio potrebbe essere una tabella del modulo:
node id | name | type | value | parent node id
------------------------------------------------
1 | data | object | | NULL
2 | cust1 | object | | 1
3 | name | string | Jane | 2
E così via. Questo sarebbe in grado di rappresentare qualsiasi payload JSON, ma sarebbe anche estremamente noioso da interrogare.