Timeseries: SQL czy NoSQL?

33

Nie dbam o ogólne różnice między SQL a NoSQL (lub ich tradycyjne różnice).

Obecnie zastanawiam się nad zmianą sposobu przechowywania naszych wewnętrznych szeregów czasowych. Wszystkie zawierają dane finansowe z wielu różnych źródeł. Obecnie przechowujemy nasze dane w zastrzeżonej bazie danych. To bardzo NoSQL, który ma swój własny język zapytań.

Interesują mnie dane wejściowe od społeczności: Jak przechowujesz dane w bazie danych SQL? Jakie są zalety używania SQL nad NoSQL, szczególnie dla szeregów czasowych? Czy jestem szalony za rozważenie przechowywania tego w SQL?

Nasz zestaw danych składa się z milionów szeregów czasowych, z których około 10% zawiera miliony rekordów każdy. Szeregi czasowe są uporządkowane hierarchicznie: / Rynek / Instrument / Wartość / Częstotliwość, gdzie:

  • Rynek to giełda papierów wartościowych itp., Zasadniczo zbiór instrumentów, zwykle podobnych instrumentów.
  • Instrument jest instrumentem. Może to być wskaźnik (Brent Crude), kapitał własny (GOOG) itp
  • Wartość jest jednym z wielu rodzajów danych dla instrumentu. Może to być bliski, wysoki, niski itp
  • Częstotliwość to częstotliwość określonych wartości szeregów czasowych. Co tydzień, codziennie, co miesiąc, zaznacz, arbitralnie itp.

Jak dane byłyby przechowywane w bazie danych SQL? Jeden duży stół (być może podzielony na części), jeden stół na rynek lub instrument, jeden stół na szereg czasowy.

Z góry dziękuję.

Nicolas
źródło
1
Czy wszystkie szeregi czasowe zawierają te same metadane (tj. Kolumny)?
Jack Douglas,
1
Brzmi jak hurtownia danych ... Zobacz to na SO: stackoverflow.com/q/2684462/27535
gbn
@ jack-douglas: Czy prosisz o zasugerowanie magazynu danych zorientowanego na kolumny?
Nicolas
3
@Nicolas Nie oczekuję, że tradycyjny SQL RDBMS będzie dobrze pasował do twoich danych, ponieważ a) łatwiej byłoby zapytać, b) woluminy nie brzmią niepraktycznie duże (miliardy wierszy?) C) partycjonowanie daty brzmi naturalnie i / lub standardowe funkcje OLAP. Pytałem o metadane, aby określić, ile tabel potrzebujesz. Jeśli każda seria czasowa ma unikalne metadane, potrzebujesz milionów tabel, co nie brzmi jak dobry pomysł na zwykłym RDBMS, ale nie sądzę, że potrzebujesz tego, prawda?
Jack Douglas,
2
@Nicolas zajrzał do nowego łącznika Hadoop dla SQL Server . Na pierwszy rzut oka twój scenariusz pasuje.
Mark Storey-Smith

Odpowiedzi:

26

Ogólnie rzecz biorąc, podejrzewam, że dla takiego ustrukturyzowanego zestawu danych można napisać niestandardowy format danych, który byłby szybszy dla większości codziennych operacji (tj. Pobieranie małych danych z dowolnego czasu). Korzyści płynące z przejścia na standardowe narzędzie DB są prawdopodobne w niektórych dodatkach, na przykład w zapytaniach ad hoc, wielokrotnym dostępie, replikacji, dostępności itp. Łatwiej jest również wynająć pomoc w utrzymaniu magazynu danych opartego na standardach.

Gdybym został poproszony o utworzenie bazy danych do przechowywania tych danych, zrobiłbym następujące czynności:

Proponowany schemat

(1) Podstawowe dane są umieszczane w licznych (1000) pojedynczych tabelach, z których każda zawiera dwie kolumny:

  1. czas: typ danych SQL DATETIME lub typ liczbowy z pewnej epoki (jest to klucz podstawowy)
  2. wartość: wpisana odpowiednio do twoich danych. Domyślnie byłbym zmiennoprzecinkowy o pojedynczej precyzji, jednak typ danych o stałym punkcie może być bardziej odpowiedni dla transakcji finansowych. Jest to prawdopodobnie nieindeksowane.

Tabele te będą dość duże i możesz ręcznie podzielić je na partycje według (na przykład) roku. Ale musisz sprawdzić wydajność systemu i dostroić odpowiednio.

Te tabele wymagają unikalnych nazw i istnieje kilka opcji. Mogą być czytelne dla człowieka (np. Nyse_goog_dailyhighs_2010) lub (moje preferencje) losowe. Tak czy inaczej, wymagany jest zestaw tabel metadanych, a losowe nazwy tabel uniemożliwiają programistom wnioskowanie do nazwy, która nie powinna być wywnioskowana.

(2) Metadane są przechowywane w osobnych tabelach, zgodnie z wymaganiami aplikacji :

Wymagana jest dodatkowa tabela lub zestaw tabel, aby śledzić metadane. Tabele te będą zawierały dane o wymianie, instrumencie, wartości, częstotliwości, zakresach dat, pochodzeniu (skąd pochodzą dane) oraz wszystko, czego potrzebujesz. Są one odwzorowane na nazwy tabel danych.

Jeśli jest wystarczająca ilość danych, to wyszukiwanie może faktycznie dostarczyć nazwę tabeli i nazwę bazy danych, umożliwiając rodzaj samoobsługowego dzielenia danych (jeśli jest to prawidłowe użycie tego terminu). Ale trzymałbym to w rezerwie.

Następnie w warstwie aplikacji przeszukiwałem tabele metadanych, aby ustalić, gdzie znajdują się moje dane, a następnie wykonałem stosunkowo proste zapytania na tabelach dużych danych, aby uzyskać moje dane.

Zalety:

  • Moje (stosunkowo ograniczone) doświadczenie polega na tym, że bazy danych mogą łatwiej obsługiwać dużą liczbę małych tabel niż mniejsza liczba dużych tabel. Takie podejście umożliwia również łatwiejszą konserwację (np. Usuwanie starych danych, odbudowywanie uszkodzonej tabeli, tworzenie / przeładowywanie z kopii zapasowych, dodawanie nowego elementu). To całkowicie oddziela różne rodzaje danych, jeśli (na przykład) masz dane z różnymi prędkościami lub potrzebujesz różnych typów danych.

  • Ta koncepcja chudej tabeli powinna również umożliwiać szybki dostęp do dysku, co, jak podejrzewam, jest najczęściej spotykanym zapytaniem, ciągłym zakresem danych z jednej jednostki. Większość aplikacji danych ma ograniczoną liczbę operacji we / wy na dysku, dlatego warto to rozważyć. Jak zasugerował już komentator, będzie to idealna aplikacja do bazy danych zorientowanej na kolumny, ale jeszcze nie znalazłem produktu zorientowanego na kolumny, który byłby na tyle popularny, że mógłbym postawić na swoją karierę. Ten schemat jest bardzo zbliżony.

Niedogodności:

  • Około połowa twojego miejsca na dysku jest przeznaczona na przechowywanie znaczników czasu, kiedy całkiem szczerze mówiąc, setki lub 1000 tabel będzie miało dokładnie te same dane w kolumnie znacznika czasu. (W rzeczywistości jest to wymóg, jeśli chcesz wykonywać łatwe łączenia tabel).

  • Przechowywanie nazw tabel i przeprowadzanie dynamicznego wyszukiwania wymaga dużej złożoności aplikacji i operacji na łańcuchach, co powoduje, że mam zawroty głowy. Ale nadal wydaje się lepszy niż alternatywy (omówione poniżej).

Uwagi:

  • Uważaj na zaokrąglenia w swoim polu czasu. Chcesz, aby twoje wartości były wystarczająco okrągłe, aby umożliwić łączenia (jeśli to konieczne), ale wystarczająco precyzyjne, aby były jednoznaczne.

  • Uważaj na strefy czasowe i czas letni. Te są trudne do przetestowania. Egzekwowałbym wymóg UTC w magazynie danych (co może sprawić, że jestem niepopularny) i obsługiwałbym konwersji w aplikacji.

Wariacje:

Niektóre odmiany, które rozważałem, to:

Składanie danych: jeśli przedziały czasu są równomiernie rozmieszczone, użyj jednej kolumny znacznika czasu i (na przykład) 10 kolumn danych. Znacznik czasu odnosi się teraz do czasu pierwszej kolumny danych, a pozostałe kolumny danych są zakładane w równych odstępach między tym znacznikiem czasu a następną. Oszczędza to dużo miejsca, które wcześniej było używane do przechowywania znaczników czasu, kosztem znacznej złożoności zapytań i / lub aplikacji. Przylegający zakres, zapytania pojedynczych jednostek wymagają teraz mniejszego dostępu do dysku.

Multipleksowanie : jeśli wiadomo, że wiele szeregów czasowych używa tego samego szeregu czasowego, należy użyć jednej sygnatury czasowej i (na przykład) 10 kolumn danych, jak opisano powyżej. Ale teraz każda kolumna reprezentuje inny szereg czasowy. Wymaga to aktualizacji tabeli metadanych, która nie jest wyszukiwaniem nazwy tabeli i kolumny. Miejsce do przechowywania jest zmniejszone. Zapytania pozostają proste. Jakkolwiek ciągły zakres, zapytania pojedynczych jednostek wymagają teraz znacznie większego dostępu do dysku.

Mega-tablica: maksymalnie wykorzystaj koncepcję „multipleksowania” i umieść wszystkie dane w jednej tabeli, raz szereg czasowy na kolumnę. Wymaga to dużego dostępu do dysku dla ciągłego zasięgu, zapytań pojedynczych jednostek i jest koszmarem konserwacyjnym. Na przykład dodanie nowego elementu wymaga teraz polecenia MODIFY TABLE w tabeli o wielu TB.

Aby uzyskać dodatkową dyskusję na temat tego formatu, zobacz różne odpowiedzi w: Zbyt wiele kolumn w MySQL

W pełni znormalizowana tabela: Zamiast korzystać z wielu 2-kolumnowych tabel, możesz użyć jednej, trzykolumnowej tabeli, w której kolumny to czas, dataid i wartość. Teraz tabele metadanych muszą tylko wyszukiwać wartości identyfikatora, a nie nazwy tabel lub nazwy kolumn, co umożliwia wypychanie większej logiki do zapytań SQL, a nie warstwy aplikacji.

Około 2/3 przestrzeni dyskowej jest teraz zużywane przez kolumny normalizujące, więc zajmie to dużo miejsca na dysku.

Możesz użyć kolejności klucza podstawowego (dataid, znacznik czasu) do szybkich, ciągłych zapytań pojedynczych encji. Możesz także użyć kolejności kluczy głównych (datownik. Dataid), aby przyspieszyć wstawianie.

Jednak nawet po rozważeniu tych odmian mój plan dalszego rozwoju obejmuje wiele tabel, każda z dwiema kolumnami. To lub metoda, którą wkrótce opublikuje ktoś mądrzejszy ode mnie :).

Pościg
źródło
Bardzo dziękuję za odpowiedź. Zebrałeś bardzo ważne punkty. Całkowicie zgadzam się na przechowywanie w UTC. Realizuję ideę, że wszystkie dane są dostarczane do interfejsów użytkownika (w Internecie, na komputerach i urządzeniach mobilnych) w UTC. Mamy międzynarodowych klientów, a system operacyjny powinien być odpowiedzialny za konwersję czasu. Mam firmę DBA pracującą nad całym naszym zestawem danych i zastanawiałem się, co wymyślą inni. Dzięki jeszcze raz.
Nicolas,
Podczas gdy konsultanci DBA pracują nad ukierunkowaniem rozbudowanej instalacji SQL Server, przejdę do testowania z konfiguracją BigData.
Nicolas,
Być może jest to dobre rozwiązanie, ale aplikacja „szeregów czasowych” w czasie rzeczywistym powinna obsługiwać funkcję „powiększania danych”, a baza danych nie może w tym pomóc. Bazy danych szeregów czasowych są bardziej na temat sprytnego „powiększania” i „oddalania”.
Roman Pokrovskij
1

Korzystając z MongoDB, możesz bardzo szybko tworzyć kolekcje w locie. Spójrz na układanie danych w osobne bazy danych i kolekcje w tych bazach danych. Zastanów się, ile pamięci potrzebujesz, aby utrzymać każdy odłamek w pamięci systemowej - jeśli potrzebujesz szybkiego pobierania. Głupie, aby trzymać się własnego rozwiązania, jeśli istnieje coś świeższego, który ewoluuje zgodnie z potrzebami. Brzmi jak dobra inicjatywa.

Dantalion
źródło
2
Jak miałbyś przechowywać szeregi czasowe w Mongo? Każdy dokument to seria czasu? lub wartość określonego znacznika czasu?
RockScience
Aby to zrobić skutecznie w przypadku danych nieokresowych, a nawet okresowych, najlepiej wstępnie przydzielić porcje danych. Każda część byłaby dokumentem z niewielką ilością danych księgowych, tablicą o ustalonym rozmiarze dla twoich wartości i tablicą o ustalonym rozmiarze dla twoich czasów. Następnie przechowujesz swoje metadane dla serii w osobnym dokumencie. W tym dokumencie metadanych należy utrzymywać mały zagnieżdżony dokument, który będzie pełnił rolę księgowego dla segmentów danych, tj. Śledzi bieżący indeks tablicy i segment _id.
RYS,