2014-12-30 10 views
7

Czekam na użycie kolumny PostgreSQL o nazwie jsonb dla nowego projektu backendu, który będzie głównie służyć jako JEST API REST-ful. Wierzę, że PostgreSQL's jsonb będzie pasował do tego projektu, ponieważ da mi obiekty JSON bez potrzeby konwersji na zapleczu.jsonb i klucze podstawowe/obce: które działa lepiej w PostgreSQL?

Jednak czytałem, że typ danych jsonb zwalnia podczas dodawania klawiszy, a mój schemat będzie wymagał użycia kluczy podstawowych i odwołań do kluczy obcych.

Zastanawiam się, czy posiadanie kluczy podstawowych/kluczy obcych w ich własnych kolumnach (w standardowy sposób relacyjnej bazy danych) i posiadanie kolumny jsonb dla pozostałych danych byłoby korzystne, czy też mogłoby to powodować problemy (czy teraz lub w dół drogi)?

W skrócie, będzie:

table car(id int, manufacturer_id int, data jsonb) 

wykonać lepiej lub gorzej niż:

table car(data jsonb) 

Zwłaszcza, gdy patrzy się kluczy obcych często?
Czy pojawią się usterki w stosunku do pierwszego, z perspektywy wydajności lub schematu?

+0

Dlaczego w ogóle chcesz używać 'jsonb'? Wygląda na to, że masz mniej lub bardziej ustalony schemat, a konwertowanie wierszy na JSON powinno być wystarczająco szybkie, abyś nie musiał się tym martwić. –

+0

Dobre pytanie: mam dobre pojęcie o relacjach, których mój schemat będzie potrzebował, ale w tym momencie nie mam konkretnego zrozumienia informacji, których każda tabela będzie potrzebować, a jednocześnie mogłem za każdym razem wykonywać migracje bazy danych Rozumiem, że użycie jsonb pozwoliłoby mi na dobrą wydajność w połączeniu z łatwym sposobem dodawania rzeczy szybko. Może później, gdy będę miał bardziej konkretne zrozumienie potrzebnych danych, będę mógł wrócić do dobrej konfiguracji relacyjnej. Ale to nie jest kwestia pytania, które brzmi: czy jeden wykonuje lepiej/gorzej od drugiego? –

+1

Ale i tak będziesz musiał zrobić kilka migracji, aby przepisać swój JSON, kilka ALTER TABLEs tu i tam nie powinno być przerażające, a jeśli następnie przepisują wszystkie swoje dane i kod, aby śledzić stale zmieniający się schemat być bardziej przerażającym. Jeśli chodzi o odpowiedź na pytanie, najpierw musisz zadać właściwe pytanie. Myślę, że musisz dowiedzieć się, jak wyglądają twoje dane, zanim zaczniesz przesuwać dane. Jeśli myślisz, że zamierzasz go przekreślić, a następnie wrócić i przeprojektować bazę danych, prawie na pewno się mylisz, to się nie stanie. –

Odpowiedz

12

Wszystkie wartości zaangażowanych w PRIMARY KEY lub FOREIGN KEY przymusu musi być przechowywane w postaci dedykowanych kolumn (najlepsze w znormalizowanej formie). Ograniczenia i odwołania nie działają dla wartości zagnieżdżonych w kolumnie w kolumnie.

Co do reszty danych: to zależy od. Posiadanie ich wewnątrz wartości jsonb (korzystnie) niesie ze sobą dobrze znane zalety i wady związane z przechowywaniem nieuporządkowanych danych typu dokumentu.

Dla atrybutów, które są obecne dla wszystkich lub większości wierszy, najprawdopodobniej będzie lepiej (szybciej, czystszy, mniejszy obszar pamięci), aby przechowywać je jako osobne kolumny. Łatwiejsze indeksowanie i prostsze zapytania. Mimo że nowy jsonb ma amazing index capabilities, indeksowanie dedykowanych kolumn jest jeszcze prostsze/szybsze.

Dla rzadko używanych lub dynamicznie pojawiających się atrybutów lub jeśli chcesz przechowywać i pobierać wartości JSON bez zbytniej obsługi wewnątrz DB, spójrz na jsonb.

Dla podstawowego EAV structures z głównie danymi znakowymi, bez zagnieżdżania i bez połączenia z JSON, rozważałbym hstore. Istnieją również typy danych xml (bardziej złożone i pełne) oraz json (głównie zastąpione przez jsonb), które tracą masę.

+1

Yup ... "to zależy". Jednym z problemów, które nie zostały tutaj omówione, jest to, że jeśli zaktualizujesz * dowolne * subfield wartości jsonb, * cała krotka * musi zostać przepisana i wszelkie/wszystkie indeksy wskazujące na nią muszą zostać zaktualizowane.Jeśli rozłożyłeś swoje dane na jednostki o relacjach pk/fk, tak już nie jest, możesz wstawiać/aktualizować/usuwać tylko jego części bez wymuszania przepisania całego artykułu. –

+0

@CraigRinger Czy to nadal prawda w postgresie 9.5? Pytam po przeczytaniu tej sekcji w dokumentacji do wydania https://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.5#JSONB-modifying_operators_and_functions – t1m0

+3

@ t1m0 Tak. Jest to nieodłączne dla magazynu TOAST poza linią i dla MVCC. PostgreSQL może teraz modyfikować obiekt jsonb bez konieczności jego całkowitej dekonstrukcji i rekonstrukcji, ale jest to modyfikacja w pamięci. Musi nadal czytać całą treść z dysku i musi jeszcze napisać całą nową zmodyfikowaną wersję ponownie do nowej krotki. –

2

Które działają lepiej? Zależy od użycia. To samo pytanie, gdy porównujesz bazy danych SQL (relacyjne) i NoSQL (KeyValue lub Document). W niektórych przypadkach bazy danych NoSQL działają bardzo dobrze, a inne nie.

Koncepcja relacyjna (znormalizowany schemat) jest zoptymalizowana pod kątem typowego użycia OLTP - 70% odczytu/30% zapisu, wielu użytkowników, wiele aktualizacji, obliczenia raportu, niektóre zapytania ad hoc. Pojęcie relacyjne jest stosunkowo szerokie ogólne ..z bardzo szeroką użytecznością (dowody, księgowość, wsparcie przetwarzania, ...). Zazwyczaj wszędzie nie jest tak źle.

Jest jasne, więc specjalistyczne bazy danych (Dokument, KeyValue, Graph) mogą być znacznie lepsze (o jedno zamówienie szybciej) w przypadku zastosowań specjalistycznych. Ale ich użycie jest znacznie węższe. Gdy skończy Ci się zoptymalizowany przypadek użycia, wydajność może być zła.

Inne pytanie to rozmiar bazy danych - liczby rekordów. Różnica w wydajności baz danych produkcyjnych może być znacząca w setkach tysięcy wierszy. W przypadku niektórych mniejszych baz danych wpływ może nie być znaczący.

Postgres jest relacyjną bazą danych i preferuję używanie znormalizowanego schematu dla wszystkich ważnych danych w bazie danych. Kiedy używasz go dobrze, jest strasznie szybko. Typy bez relacji są idealne dla niektórych danych rozmytych (HStore, JSON, XML, Jsonb) - są znacznie lepsze niż schematy EAV (w przypadku większych danych są gorsze).

Jeśli potrzebujesz wykonać ważną decyzję, przygotuj prototyp, wypełnij go oczekiwanymi danymi (3 lata) i sprawdź szybkość niektórych ważnych zapytań dla swojego systemu. Uwaga: silny wpływ na te benchmarki wykorzystał hw, bieżące obciążenie, aktualne sw.

Powiązane problemy