Jaka jest normalna forma JSON?

Sep 13 2020

To zabrzmi jak trywialne pytanie, ale lubię myśleć, że jest naprawdę głębokie. Proste pytanie brzmi: „Jaka jest normalna postać typowego obiektu JSON?” Dla porównania przytoczę przykład poniżej, ale rozważ każdy typowy obiekt JSON, z którym miałeś do czynienia, to samo pytanie.

Zadaję to teoretyczne pytanie z praktycznego powodu. W praktyce często musimy przekonwertować obiekty JSON na jakiś zestaw tabel. Kiedy są tabelami, mają mierzalne formy normalne oparte na wszystkich zwykłych regułach form normalnych.

Ale dotarcie do tych stołów w ich normalnej formie wymaga pracy. Co jeszcze „wymaga pracy”. Odpowiedź: przejście z niższych form normalnych do wyższych form normalnych. To, co nie „wymaga pracy”, przechodzi do normalnych form. A przynajmniej niewielka ilość pracy. Oznacza to, że jeśli mam 6NF, mogę dość szybko zmanipulować drogę do dowolnej niższej normalnej formy. Jeśli mam, powiedzmy 2NF, i muszę dojść do co najmniej 5NF z jakiegoś praktycznego powodu, mam dużo do zrobienia.

Cóż ... ponieważ dość trudno jest uzyskać JSON w jakiejkolwiek przyzwoitej normalnej formie, to intuicyjnie wydaje się, że musi być w bardzo niskiej normalnej formie. Mam nadzieję, że ktoś tutaj może określić ilościowo tę normalną postać JSON . Bardzo wdzięczny.

Ale nadal nie podałem najbardziej krytycznego uzasadnienia. Nierzadko zdarza się, że przywódcy nietechniczni proszą o cuda. Nie krytykuję, wszyscy wiemy, że to się dzieje. Cudem jest forma, „po prostu napisz kod, aby automatycznie przekształcić JSON w tabele”.

Ale poczekaj! Jeśli moja teoria jest poprawna, a JSON jest w zasadzie 0NF lub coś podobnego, nie możesz zautomatyzować swojego wyjścia z tego. Nie możesz przejść od bardzo niskiego NF JSON do niczego przyzwoitego, takiego jak 3NF +, w automatycznym modzie, ponieważ to „wymaga pracy”. Oznacza to, że zrozumienie domeny wymaga inteligentnych ludzi.

Teraz wiem, że niektóre trywialne JSON mogą stać się trywialnymi tabelami. Wiem, że istnieje kilka narzędzi do obsługi prostych przypadków. Ale uważam, że konwerter JSON-to-Table ogólnego przeznaczenia jest teoretycznie niemożliwy, ponieważ JSON ma tak mało informacji o normalizacji (w rygorystycznym sensie Claude Shannon), że nie można go zautomatyzować.

Więc, co jest normalną formą typowego obiektu JSON ? Czy jest jakaś teoria, której nie znalazłem, a która już dowodzi, że nie można zautomatyzować wyjścia z tego.

Dzięki!

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

Odpowiedzi

6 Christophe Sep 13 2020 at 02:47

W skrócie

JSON to reprezentacja danych zgodnie ze składnią bez schematu bez predefiniowanej semantyki. Z drugiej strony, formy normalne są definiowane dla abstrakcyjnego modelu danych z relacyjną semantyczną zgodnie z ustalonym schematem. Dlatego nie ma sensu stosować zwykłych formularzy do formatu JSON.

Możesz jednak dodać schemat lub jakąś semantykę do formatu JSON, który pozwoliłby na normalną analizę formularza. Jednak pomimo wykonalności jest to generalnie mało korzystne, ponieważ bogaty model obiektowy z zagnieżdżonymi i powiązanymi obiektami ma na celu wyrażanie niezależnych danych w inny sposób i bardziej elastycznie niż poprzez ustalone, predefiniowane relacje tabelaryczne.

Więcej szczegółów

Czy jest sens?

Forma normalna została wymyślona w kontekście modeli relacyjnych przez pioniera Edgara F. Codda . Teoria algebry relacyjnej nie dotyczy tabel i kolumn, ale abstrakcyjnych relacji, atrybutów i zbiorów (które można łatwo przedstawić za pomocą tabel). Forma normalna dotyczy danych (krotek) w relacjach, postaci ich atrybutów i ich współzależności.

JSON nie jest modelem, ale reprezentacją danych z precyzyjną składnią, ale bez zdefiniowanej semantyki. Nie ma reguły dotyczącej powiązania dwóch różnych obiektów: każdy JSON reprezentuje inny obiekt i może reprezentować unikalną relację, utworzoną z pojedynczej krotki i niepowiązaną z żadnymi innymi, lub reprezentować zestaw powiązanych wystąpień relacji.

Wniosek: Pojęcie formy normalnej nie dotyczy obiektów JSON, ponieważ jest zdefiniowane dla modelu relacyjnego, a JSON jest używany w radykalnie różnych modelach (zwykle w modelu dokumentu).

Czy to ma sens?

Nic nie stoi na przeszkodzie, aby dodać semantykę do składni JSON. Nierzadko zestaw dokumentów JSON jest powiązany i reprezentuje krotki tej samej relacji, a elementy o tej samej nazwie odpowiadają temu samemu atrybutowi i mają swoje potencjalne wartości w tej samej domenie (zgodnie z niejawnym lub jawnym schematem ) . W rzeczywistości twój przykład używa JSON dokładnie w ten sposób.

Na jakim poziomie należy wziąć pod uwagę normalną formę?

  • Czy traktujesz sam obiekt JSON jako pojedynczy atrybut w relacji? Ponieważ nie jest elementarny / atomowy, ale składa się z agregacji kilku pierwiastków, rzeczywiście byłby to UNF.
  • Czy uważasz, że JSON jest krotką? W końcu Codd zanotował krotki, (a,b,c)używając kolejności nazw atrybutów (p1,p2, p3)i nigdy nie udawał, że krotka to UNF. {p1:a, p2:b, p3:c}Można więc łatwo uznać 1NF, jeśli każdy z jego elementarnych / atomowych.

W drugim przypadku jest jednak więcej pytań. Co jeśli:

  • niektóre elementy są obiektami zagnieżdżonymi: te nie są atomowe. Czy zatem uważamy je za osobną relację i rekurencyjnie stosujemy regułę dotyczącą postaci normalnej, patrząc w osadzony JSON? A może dochodzimy do wniosku, że jakikolwiek JSON zawierający osadzony JSON nie jest już w 1NF?
  • niektóre elementy to tablice: one też nie są atomowe. Czy uważasz, że to po prostu nie jest normalna forma, czy też uważasz tablicę za relację zdefiniowaną przez zamknięte krotki, a następnie przeglądasz rekurencyjnie każdy element tablicy?

Wniosek: przyjęcie pewnej semantyki do składni JSON pozwala na zastosowanie normalnej analizy postaci.

Jak rozszerzyć zwykły formularz do JSON?

W praktyce, mając semantykę zdefiniowaną w poprzedniej sekcji i wybierając analizę rekurencyjną dla pytań otwartych, definiujesz mapowanie między JSONami a formą relacyjną . W rzeczywistości zespół naukowców z Yale opublikował nawet artykuł opisujący taki algorytm .

Przy takim mapowaniu możesz po prostu zastosować kryteria krytyczne postaci normalnej do mapowanego modelu relacyjnego, aby sklasyfikować swoją reprezentację JSON.

Na przykład ten 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 }} ]
}

może mieć następujące mapowanie relacyjne:

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

Więc możesz twierdzić, że JSON to BCNF , ponieważ mapowanie relacyjne ma tabele tylko z atrybutami atomowymi, że atrybuty każdej tabeli zależą wyłącznie od klucza podstawowego, a nie części klucza podstawowego, że oczywiście nie ma zależności przechodnich, .. .

Ale jaka jest korzyść?

Twierdzę, że normalna forma JSON w większości przypadków nie daje żadnej korzyści :

  • Jeśli wybrałeś kodowanie JSON i bazę danych dokumentów NOSQL, to dlatego, że chcesz uwolnić się od modelu relacyjnego. Nie dlatego, że model relacyjny byłby zły (w rzeczywistości jest doskonały i osiągnął wybitne wyniki w dziedzinach, w których pasuje do potrzeb), ale dlatego, że model relacyjny prawdopodobnie nie pasuje do twoich konkretnych potrzeb. Nie ma więc sensu wprowadzanie sztucznych ograniczeń.

  • Jeśli cały Twój projekt jest oparty na bogatych obiektach biznesowych i nie chcesz ich spłaszczać i ponownie nawadniać za pomocą warstwy ORM , normalna forma Ci nie pomoże: Twoje obiekty są samowystarczalne, a nadmiarowość może nie mieć takiego samego znaczenia w tabelach. Właśnie dlatego zazwyczaj analizuje się każdy przypadek na gorąco, jeśli chodzi o implementację skojarzeń typu jeden do wielu w bazie danych dokumentów, tj. Osadzone dokumenty vs. odniesienia do innych dokumentów .

Wniosek: normalna forma generalnie nie dodaje korzyści do JSON, chyba że musisz zrobić ORM. Jednak przemyślenia na temat nadmiarowości i zależności funkcjonalnych, które są podstawowymi składnikami form normalnych, mogą pomóc w ocenie granic między obiektami.

3 JörgWMittag Sep 13 2020 at 03:45

Zeroth.

First Normal Form mówi, że dane powinny być atomowe. Tak jak w przypadku jednej wartości logicznej, jednej liczby. Nawet pojedynczy ciąg jest już wątpliwy. Zależy to od tego, jak jest używany, łańcuch może być użyty do reprezentowania czegoś, w którym to przypadku nie jest to już tak naprawdę dane atomowe. W rzeczywistości w ten sposób można użyć nawet liczby.

Tak więc, ogólnie rzecz biorąc , dokument JSON jest w Zerowa postać normalna, ponieważ jest dobrze, to dokument, a nie pojedyncza wartość atomowa.

Możliwe jest posiadanie dokumentu JSON w First Normal Form, na przykład ten dokument:

true

Jednak nawet ten dokument nie jest już w pierwszej normalnej formie:

{ "property": true }

Nie jest to niepodzielna wartość danych, jest to obiekt zawierający parę klucz-wartość, gdzie klucz jest łańcuchem, a wartość jest wartością logiczną.

Oczywiście, w rzeczywistości definicja pierwszej postaci normalnej mówi wprost o relacjach (lub tabelach), więc prawdziwa odpowiedź brzmi: JSON nie ma relacji ani tabel, więc samo pytanie jest pozbawione sensu.

JacquesB Sep 13 2020 at 19:48

W rzeczywistości jest to trudne pytanie, ponieważ normalizacja i formy normalne są definiowane za pomocą relacji i krotek (tj. Tabel z kolumnami o typie). Więc tak naprawdę nie można mówić o normalnej postaci danych struktury drzewiastej, takiej jak przykład Json.

Dane muszą być w formie tabelarycznej, zanim będzie można sensownie mówić o normalnych formularzach. Nie można powiedzieć, że sam JSON ma jakąkolwiek normalną postać.

Jeśli umieścisz JSON w formie tabeli, otrzymasz:

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

Kolumna „ulubione” przerywa pierwszą postać normalną przez posiadanie wielu wartości. Więc stół nie jest nawet w pierwszej normalnej formie. Jest to czasami nazywane formą normalną zerową lub 0NF.

Pytanie brzmi, czy tłumaczenie z formatu JSON na tabelę 0NF może być wykonane automatycznie lub wymaga znajomości domeny. Powiem, że można to zrobić automatycznie na wiele sposobów. Dowolna struktura JSON może być reprezentowana jako tabele. Po prostu wynikowe tabele będą miały wartość 0NF, a zatem będą podlegały wszystkim problemom związanym z danymi zdenormalizowanymi. Nie jest to więc coś, co bym polecał.

Przykładem może być tabela o postaci:

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

I tak dalej. Byłoby to w stanie reprezentować dowolny ładunek JSON, ale byłoby również niezwykle żmudne w przypadku zapytań.