Какая обычная форма JSON?

Sep 13 2020

Это прозвучит тривиально, но мне нравится думать, что это действительно глубокий вопрос. Простой вопрос: «Какова нормальная форма типичного объекта JSON?» Для справки я привожу пример ниже, но рассмотрите любой типичный объект JSON, с которым вы имели дело, применим тот же вопрос.

Я задаю этот теоретический вопрос из практических соображений. На практике нам часто требуется преобразовать объекты JSON в некоторый набор таблиц. Как только они являются таблицами, они имеют измеримые нормальные формы, основанные на всех обычных правилах нормальных форм.

Но чтобы добраться до этих таблиц в их нормальной форме, нужно потрудиться. Теперь о том, что еще «требует работы». Ответ: переход от низших нормальных форм к высшим нормальным формам. Что не «требует работы», так это нормальные формы. Или хотя бы тривиальный объем работы. То есть, если у меня есть 6НФ, я могу довольно быстро перейти к любой более низкой нормальной форме. Если у меня есть, скажем, 2NF, и мне нужно работать, по крайней мере, до 5NF по какой-то практической причине, у меня много работы.

Что ж ... поскольку довольно сложно привести JSON в какую-либо приличную нормальную форму, интуитивно кажется, что он должен быть в очень низкой нормальной форме. Я надеюсь, что кто-то здесь сможет количественно оценить эту нормальную форму JSON . Многое оценено.

Но я до сих пор не дал самого критического обоснования. Нетехнические лидеры нередко просят о чудесах. Я не критикую, мы все знаем, что такое бывает. И чудо - это что-то вроде того, «просто напишите код, чтобы автоматически преобразовывать JSON в таблицы».

Но ждать! Если моя теория верна, и JSON в основном 0NF или около того, то вы не можете автоматизировать выход из него. Вы не можете перейти от очень низкого NF JSON к чему-либо приличному, например, 3NF +, в автоматическом прошивке, потому что это «требует работы». То есть нужны умные люди, разбирающиеся в предметной области.

Теперь я знаю, что некоторые тривиальные JSON могут превратиться в тривиальные таблицы. Я знаю, что есть несколько инструментов для простых случаев. Но я считаю, что преобразователь JSON-to-Table общего назначения теоретически невозможен, потому что JSON настолько мало информации о нормализации (в строгом смысле Клода Шеннона), что вы не можете автоматизировать его.

Итак, какова нормальная форма типичного объекта JSON ? И есть какая-то теория, которую я не нашел, которая уже доказывает, что вы не можете автоматизировать выход из этого.

Благодаря!

{
  "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"]
      }
    }
  }
}

Ответы

6 Christophe Sep 13 2020 at 02:47

Коротко

JSON - это представление данных в соответствии с синтаксисом без схемы без предопределенной семантики. Напротив, нормальные формы определены для абстрактной модели данных с реляционной семантикой в ​​соответствии с фиксированной схемой. Поэтому применять к JSON обычные формы не имеет смысла.

Однако вы можете добавить схему или некоторую семантику в свой формат JSON, которые позволят анализировать нормальную форму. Но, несмотря на осуществимость, это обычно не приносит большой пользы, потому что богатая объектная модель с вложенными и связанными объектами предназначена для выражения автономных данных по-другому и более гибко, чем через фиксированные предопределенные табличные отношения.

Подробнее

Имеет ли это смысл?

Нормальная форма была изобретена в контексте реляционных моделей пионером Эдгаром Ф. Коддом . Теория реляционной алгебры - это не таблицы и столбцы, а абстрактные отношения, атрибуты и множества (которые легко могут быть представлены в виде таблиц). Нормальная форма - это данные (кортежи) в отношениях, форма их атрибутов и их взаимозависимости.

JSON - это не модель, а представление данных с точным синтаксисом, но без определенной семантики. Не существует правила о том, как связать два разных объекта: каждый JSON представляет отдельный объект и может представлять уникальное отношение, состоящее из одного кортежа и не связанное ни с каким другим, или представлять набор связанных экземпляров отношения.

Вывод: концепция нормальной формы не применяется к объектам JSON, поскольку она определена для реляционной модели, а JSON используется в радикально разных моделях (обычно в модели документа).

Может ли это иметь смысл?

Ничто не мешает добавить семантику в синтаксис JSON. Нередко набор документов JSON связан и представляет собой кортежи одного и того же отношения, а элементы с одинаковым именем соответствуют одному и тому же атрибуту и ​​имеют свои потенциальные значения в одном домене (согласно неявной или явной схеме ) . Фактически, ваш пример использует JSON именно так.

На каком уровне следует рассматривать нормальную форму?

  • Считаете ли вы сам объект JSON как отдельный атрибут в отношении? Поскольку он не элементарный / атомарный, а состоит из совокупности нескольких элементов, это действительно будет UNF.
  • Считаете ли вы JSON кортежем? В конце концов, Кодд отмечал кортежи, (a,b,c)используя порядок имен атрибутов, (p1,p2, p3)и никогда не притворялся, что кортеж является UNF. Так {p1:a, p2:b, p3:c}что легко можно было бы считать 1НФ, если каждый его элементарный / атомарный.

Однако во втором случае есть еще несколько вопросов. Что если:

  • некоторые элементы являются вложенными объектами: они не атомарны. Итак, рассматриваем ли мы их как отдельное отношение и рекурсивно применяем правило о нормальной форме, просматривая встроенный JSON? Или мы делаем вывод, что любого JSON, содержащего встроенный JSON, больше нет в 1NF?
  • некоторые элементы являются массивами: они тоже не атомарны. Итак, считаете ли вы, что это просто ненормальная форма, или вы рассматриваете массив как отношение, определяемое заключенными кортежами, а затем рекурсивно просматриваете каждый элемент массива?

Вывод: Принятие некоторой семантики к синтаксису JSON позволяет применять анализ нормальной формы.

Как расширить обычную форму до JSON?

На практике, используя семантику, определенную в предыдущем разделе, и выбирая рекурсивный анализ для открытых вопросов, вы определяете соответствие между вашими JSON и реляционной формой . Фактически, группа исследователей из Йельского университета даже опубликовала статью с описанием такого алгоритма .

С таким отображением вы можете просто применить критерии нормальной формы к сопоставленной реляционной модели, чтобы категоризировать ваше представление JSON.

Например, этот 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 }} ]
}

может иметь следующее реляционное отображение:

TABLE CUSTOMERS (id, name, turnover); 
TABLE PRODUCTS (id, label);
TABLE PRODUCT-LAUNCH (product-id, year, month);  

Таким образом, вы можете утверждать, что JSON - это BCNF , потому что реляционное сопоставление имеет таблицы только с атомарными атрибутами, что атрибуты каждой таблицы зависят исключительно от первичного ключа, а не от части первичного ключа, что, очевидно, нет транзитивной зависимости, .. .

Но в чем польза?

Я утверждаю, что обычная форма для JSON в большинстве случаев не имеет никакой пользы :

  • Если вы выбрали кодировку JSON и базу данных документов NOSQL, это потому, что вы хотите освободиться от реляционной модели. Не потому, что реляционная модель была бы плохой (на самом деле она превосходна и обеспечивала выдающуюся производительность в тех областях, где она соответствует потребностям), а потому, что реляционная модель, вероятно, не соответствует вашим конкретным потребностям. В таком случае нет смысла вводить искусственные ограничения.

  • Если весь ваш дизайн основан на богатых бизнес-объектах, и вы не хотите сглаживать и восстанавливать их через слой ORM , обычная форма вам не поможет: ваши объекты являются самодостаточными, а избыточность может не иметь такого же значения, как и в таблицах. Именно поэтому обычно анализируется от случая к случаю, особенно для реализации ассоциаций «один ко многим» в базе данных документов, то есть встроенных документов по сравнению со ссылками на другие документы .

Вывод: Обычная форма, как правило, не добавляет преимуществ JSON, если вам не нужно использовать ORM. Однако мысли об избыточности и функциональных зависимостях, которые являются ключевыми ингредиентами нормальных форм, могут помочь оценить границы между объектами.

3 JörgWMittag Sep 13 2020 at 03:45

Zeroth.

Первая нормальная форма говорит, что данные должны быть атомарными. Как и одно логическое значение, одно число. Даже одна строка уже вызывает сомнения. Это зависит от того, как она используется, строка может использоваться для представления чего-либо, и в этом случае это больше не атомарные данные. Фактически, таким образом можно было использовать даже число.

Итак, в общем , документ JSON находится в нулевой нормальной форме, потому что это, ну, документ, а не одно атомарное значение.

Это есть возможность иметь документ JSON в первой нормальной форме, например , в этом документе:

true

Однако даже этот документ уже не в Первой нормальной форме:

{ "property": true }

Это не атомарное значение данных, это объект, содержащий пару «ключ-значение», где ключ является строкой, а значение является логическим.

Конечно, на самом деле определение Первой нормальной формы явно говорит об отношениях (или таблицах), и поэтому реальный ответ таков: JSON не имеет отношений или таблиц, поэтому сам вопрос не имеет смысла.

JacquesB Sep 13 2020 at 19:48

На самом деле это сложный вопрос, поскольку нормализация и нормальные формы определяются в терминах отношений и кортежей (т. Е. Таблиц с типизированными столбцами). Таким образом, вы не можете говорить о нормальной форме данных древовидной структуры, такой как пример Json.

Прежде чем вы сможете осмысленно говорить о нормальных формах, данные должны быть в виде таблицы. Сам JSON нельзя сказать , чтобы иметь любую нормальную форму.

Если вы поместите JSON в виде таблицы, вы получите:

 id    | name | age | address     | favorite colors
 --------------------------------------------------
 cust1 | Jane | 33  | Main Street | blue, green
 cust2 | Joe  | 44  | West Road   | red, yellow

Столбец «избранное» нарушает первую нормальную форму, имея несколько значений. Так что таблица даже не в первой нормальной форме. Иногда это называют нулевой нормальной формой или 0NF.

Вы спрашиваете, может ли перевод из JSON в табличную форму 0NF выполняться автоматически или требует знания предметной области. Я скажу, что это можно сделать автоматически несколькими способами. Любая произвольная структура JSON может быть представлена ​​в виде таблиц. Просто результирующие таблицы будут 0NF и, следовательно, будут подвержены всем проблемам денормализованных данных. Так что это не то, что я бы рекомендовал.

Примером может служить таблица вида:

node id | name | type   | value | parent node id
------------------------------------------------
     1  | data  | object |      | NULL
     2  | cust1 | object |      | 1
     3  | name  | string | Jane | 2

И так далее. Это могло бы представлять любую полезную нагрузку JSON, но также было бы чрезвычайно утомительно для запроса.