¿Cuál es la forma normal de JSON?
Esta va a sonar como una pregunta trivial, pero me gusta pensar que en realidad es una pregunta profunda. La pregunta simple es: "¿Cuál es la forma normal de un objeto JSON típico?" Como referencia, pongo un ejemplo a continuación, pero considere cualquier objeto JSON típico con el que haya tratado, se aplica la misma pregunta.
Hago esta pregunta teórica por una razón práctica. En la práctica, a menudo necesitamos convertir objetos JSON en algún conjunto de tablas. Una vez que son tablas, las tablas tienen formas normales medibles basadas en todas las reglas habituales de las formas normales.
Pero llegar a esas mesas con su forma normal requiere trabajo. Ahora, qué más "requiere trabajo". Respuesta: pasar de formas normales inferiores a formas normales superiores. Lo que no "requiere trabajo" es seguir las formas normales. O al menos una cantidad trivial de trabajo. Es decir, si tengo 6NF, puedo manipular rápidamente mi camino hacia cualquier forma normal más baja. Si lo tengo, digamos 2NF, y necesito trabajar para llegar al menos a 5NF por alguna razón práctica, tengo mucho trabajo por hacer.
Bueno ... dado que es bastante difícil llevar JSON a una forma normal decente, entonces intuitivamente parece que debe estar en una forma normal muy baja. Espero que alguien aquí pueda cuantificar esa forma normal de JSON . Muy apreciado.
Pero todavía no he dado la justificación más crítica. No es raro que los líderes no técnicos pidan milagros. No estoy criticando, todos sabemos que pasa. Y el milagro es algo de la forma, "simplemente escriba un código para convertir JSON en tablas automáticamente".
¡Pero espera! Si mi teoría es correcta, y JSON es básicamente 0NF más o menos, entonces no puede automatizar su salida. No se puede pasar del NF muy bajo de JSON a algo decente, como 3NF +, en un fashing automatizado porque eso "requiere trabajo". Es decir, se necesitan humanos inteligentes para comprender el dominio.
Ahora, sé que algunos JSON triviales pueden convertirse en tablas triviales. Sé que hay algunas herramientas que manejan los casos simples. Pero creo que un conversor JSON a tabla de propósito general no es teóricamente posible porque JSON es tan bajo en la información de normalización (en el sentido riguroso de Claude Shannon), que no se puede automatizar.
Entonces, ¿cuál es la forma normal de un objeto JSON típico ? ¿Y hay alguna teoría que no encontré que demuestre que no se puede automatizar la salida de esto?
¡Gracias!
{
"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"]
}
}
}
}
Respuestas
En breve
JSON es una representación de datos según una sintaxis sin esquema y sin semántica predefinida. Por el contrario, las formas normales se definen para el modelo de datos abstracto con una semántica relacional según un esquema fijo. Por lo tanto, no tiene sentido aplicar formas normales a JSON.
Sin embargo, puede agregar un esquema o algo de semántica a su formato JSON que permitiría un análisis de forma normal. Pero a pesar de la viabilidad, generalmente tiene poco beneficio, porque un modelo de objeto rico con objetos anidados y relacionados está destinado a expresar datos autónomos de manera diferente y más flexible que a través de relaciones tabulares predefinidas fijas.
Más detalles
¿Tiene sentido?
La forma normal fue inventada en el contexto de modelos relacionales por el pionero Edgar F. Codd . La teoría del álgebra relacional no se trata de tablas y columnas, sino de relaciones abstractas, atributos y conjuntos (que se pueden representar fácilmente con tablas). La forma normal trata de los datos (tuplas) en las relaciones, la forma de sus atributos y sus interdependencias.
JSON no es un modelo sino una representación de datos con una sintaxis precisa pero sin semántica definida. No existe una regla sobre cómo relacionar dos objetos diferentes: cada JSON representa un objeto diferente y podría representar una relación única, hecha de una sola tupla y no relacionada con ninguna otra, o representar un conjunto de instancias relacionadas de una relación.
Conclusión: El concepto de forma normal no se aplica a los objetos JSON, porque está definido para un modelo relacional y JSON se usa en modelos radicalmente diferentes (típicamente el modelo de documento).
¿Podría tener sentido?
Nada le impide agregar algo de semántica a la sintaxis JSON. No es raro que un conjunto de documentos JSON estén relacionados y representen tuplas de la misma relación, y que los elementos que comparten un mismo nombre correspondan al mismo atributo y tengan sus valores potenciales en el mismo dominio (siguiendo un esquema implícito o explícito ) . De hecho, su ejemplo usa JSON exactamente de esta manera.
¿A qué nivel se debe considerar la forma normal?
- ¿Considera el objeto JSON en sí mismo como un atributo único en una relación? Dado que no es elemental / atómico sino que está hecho de una agregación de varios elementos, sería de hecho UNF.
- ¿Consideras JSON como una tupla? Después de todo, Codd anotó tuplas
(a,b,c)usando el orden de los nombres de los atributos(p1,p2, p3)y nunca pretendió que una tupla fuera UNF. Por lo{p1:a, p2:b, p3:c}que fácilmente podría considerarse 1NF si cada uno de sus elementos elemental / atómico.
En el segundo caso, sin embargo, hay algunas preguntas más. Y si:
- algunos elementos son objetos anidados: estos no son atómicos. Entonces, ¿los consideramos como una relación separada y aplicamos la regla sobre la forma normal de forma recursiva, mirando dentro del JSON incrustado? ¿O llegamos a la conclusión de que cualquier JSON que contenga un JSON incrustado ya no está en 1NF?
- algunos elementos son matrices: estos tampoco son atómicos. Entonces, ¿considera que no es una forma normal, o considera la matriz como una relación definida por tuplas encerradas y luego mira recursivamente cada elemento de la matriz?
Conclusión: La adopción de alguna semántica a la sintaxis JSON permite aplicar análisis de forma normal.
¿Cómo extender la forma normal a JSON?
En la práctica, con la semántica definida en la sección anterior, y eligiendo el análisis recursivo para las preguntas abiertas, usted define un mapeo entre sus JSON y una forma relacional . De hecho, un equipo de investigadores de Yale incluso publicó un artículo para describir dicho algoritmo .
Con tal mapeo, puede simplemente aplicar los criterios de forma normal al modelo relacional mapeado para categorizar su representación JSON.
Por ejemplo, este 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 }} ]
}
podría tener el siguiente mapeo relacional:
TABLE CUSTOMERS (id, name, turnover);
TABLE PRODUCTS (id, label);
TABLE PRODUCT-LAUNCH (product-id, year, month);
Entonces, podría afirmar que JSON es BCNF , porque el mapeo relacional tiene tablas con solo atributos atómicos, que los atributos de cada tabla dependen únicamente de la clave principal y no de una parte de la clave principal, que obviamente no hay dependencia transitiva, .. .
¿Pero cuál es el beneficio?
Afirmo que la forma normal de JSON en la mayoría de los casos no tiene ningún beneficio :
Si eligió una codificación JSON y una base de datos de documentos NOSQL, es porque desea liberarse del modelo relacional. No porque el modelo relacional sea malo (de hecho, es excelente y logró un desempeño sobresaliente en los dominios donde se ajusta a las necesidades), sino porque el modelo relacional probablemente no se ajuste a sus necesidades específicas. Entonces no tiene sentido introducir restricciones artificiales.
Si todo su diseño se basa en objetos comerciales enriquecidos y no desea aplanarlos y rehidratarlos a través de una capa ORM , la forma normal no lo ayudará: sus objetos son independientes y la redundancia puede no importar de la misma manera que lo hace. en tablas. Esta es exactamente la razón por la que generalmente se analiza caso por caso para implementar asociaciones de uno a muchos en una base de datos de documentos, es decir, documentos incrustados frente a referencias a otros documentos .
Conclusión: la forma normal en general no agrega beneficios a JSON, a menos que necesite hacer ORM. Sin embargo, los pensamientos sobre redundancias y dependencias funcionales, que son ingredientes centrales de las formas normales, pueden ayudar a evaluar los límites entre objetos.
Zeroth.
La primera forma normal dice que los datos deben ser atómicos. Como en un solo booleano, un solo número. Incluso una sola cuerda ya es cuestionable. Depende de cómo se use, una cadena podría usarse para representar algo, en cuyo caso ya no son datos atómicos. De hecho, incluso un número podría usarse de esta manera.
Entonces, en general , un documento JSON está en forma normal cero porque es, bueno, un documento, no un solo valor atómico.
Que es posible tener un documento JSON en la Primera Forma Normal, por ejemplo este documento:
true
Sin embargo, incluso este documento ya no está en Primera forma normal:
{ "property": true }
No es un valor de datos atómicos, es un objeto que contiene un par clave-valor donde la clave es una cadena y el valor es un booleano.
Por supuesto, de hecho , la definición de Primera forma normal habla explícitamente de Relaciones (o Tablas), por lo que la respuesta real es: JSON no tiene Relaciones o Tablas, por lo que la pregunta misma no tiene sentido.
Esta es en realidad una pregunta complicada, ya que la normalización y las formas normales se definen en términos de relaciones y tuplas (es decir, tablas con columnas escritas). Entonces, realmente no se puede hablar sobre la forma normal de datos de estructuras de árbol como el ejemplo de Json.
Los datos deben estar en forma de tabla antes de poder hablar de manera significativa sobre las formas normales. No se puede decir que el JSON en sí tenga una forma normal.
Si pones el JSON en forma de tabla, obtienes:
id | name | age | address | favorite colors
--------------------------------------------------
cust1 | Jane | 33 | Main Street | blue, green
cust2 | Joe | 44 | West Road | red, yellow
La columna "favorito" rompe la primera forma normal al tener múltiples valores. Así que la tabla ni siquiera está en la primera forma normal. A esto a veces se le llama forma cero-normal o 0NF.
Su pregunta es si una traducción de JSON en forma de tabla 0NF se puede hacer automáticamente o requiere conocimientos de dominio. Diré que se puede hacer automáticamente de varias maneras. Cualquier estructura JSON arbitraria se puede representar como tablas. Es solo que las tablas resultantes serán 0NF y, por lo tanto, estarán sujetas a todos los problemas de los datos desnormalizados. Entonces no es algo que yo recomendaría.
Un ejemplo podría ser una tabla de la forma:
node id | name | type | value | parent node id
------------------------------------------------
1 | data | object | | NULL
2 | cust1 | object | | 1
3 | name | string | Jane | 2
Etcétera. Esto podría representar cualquier carga útil JSON, pero también sería extremadamente tedioso de consultar.