it-swarm.dev

Timeseries: SQL czy NoSQL?

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., W zasadzie 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ół (może podzielony na części), jeden stół na rynek lub instrument, jeden stół na szereg czasowy.

Z góry dziękuję.

33
Nicolas

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) poszczególnych tabelach, z których każda zawiera dwie kolumny:

  1. czas: albo typ danych SQL DATETIME, albo typ liczbowy z jakiejś 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 w celu ustalenia, 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 także ł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.

Wady:

  • Około połowa twojego miejsca na dysku jest przeznaczona na przechowywanie znaczników czasu, kiedy szczerze mówiąc setki lub 1000 tabel będą miały dokładnie takie 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ć sprzężenia (w razie potrzeby), 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 czasowe są równo 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.

Multi-plexing: 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 zasięg, zapytania do pojedynczych encji wymagają teraz znacznie większego dostępu do dysku.

Mega-tabela: Ekstremalnie podchodź do koncepcji „multipleksowania” i umieść wszystkie dane w jednej tabeli, raz szereg czasowy na kolumnę. Wymaga to dużej ilości 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 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, gdzie 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żna 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 :).

26
Pursuit

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.

1
Dantalion