Twoje jezioro#
Wszystko, co synchronizuje Supernova, trafia w jedno miejsce: do jeziora Twojej organizacji. Jest ono wspólną, możliwą do odpytywania warstwą nad każdym połączonym źródłem — Stripe obok HubSpot i produkcyjnego PostgreSQL. Dane są zapisane w otwartym formacie kolumnowym, dlatego zapytanie łączące trzy narzędzia SaaS nie różni się od zapytania do jednej tabeli. Ta strona opisuje kilka zasad, według których działa jezioro. Warto poświęcić im dziesięć minut, bo pozostałe strony zakładają ich znajomość.
Tabele i nazwy#
Każde źródło synchronizuje dane do własnego schematu nazwanego od źródła. Pełna nazwa tabeli ma postać titan.<schema>.<table>:
select * from titan.stripe.charges
select * from titan.hubspot.deals
select * from titan.postgres.ordersŹródła o stałych schematach (Stripe, Zendesk, Shopify) zawsze tworzą te same tabele. Źródła o wykrywanych schematach (PostgreSQL, Salesforce, Airtable) tworzą to, co zawiera Twoje konto — na przykład Airtable synchronizuje każdą bazę do osobnego schematu airtable_<base>. Nazwy kolumn są wszędzie zapisane małymi literami w formacie snake_case, niezależnie od nazw używanych przez API źródła.
Kolumny systemowe#
Każda zsynchronizowana tabela zawiera dwie kolumny utrzymywane przez Supernova:
| Kolumna | Typ | Znaczenie |
|---|---|---|
_synced_at | timestamp | Czas ostatniej zmiany wiersza w jeziorze |
_deleted | boolean | Wiersz nie istnieje już w źródle |
Warto zapamiętać przede wszystkim _deleted. Gdy obciążenie zostanie usunięte w Stripe albo szansa sprzedaży scalona w HubSpot, jezioro nie usuwa wiersza — oznacza go. Historia pozostaje nienaruszona, a zapytania jawnie ją wykluczają:
select count(*) from titan.hubspot.deals where not _deletedDodawaj filtr not _deleted wszędzie, gdzie liczysz, sumujesz lub łączysz bieżący stan. Pomiń go, gdy celowo analizujesz historię — właśnie po to ją zachowujemy.
Jak zmieniają się wiersze#
Synchronizacje są przyrostowe: każde uruchomienie pobiera zmiany od poprzedniego i scala je według klucza podstawowego, zachowując najnowszą wersję każdego wiersza. Wynikają z tego dwie konsekwencje:
Przerwanie synchronizacji w połowie jest nieszkodliwe. Następne uruchomienie podejmuje pracę od ostatniego punktu kontrolnego. Nie powstają duplikaty, ponieważ scalanie odbywa się według klucza.
Wykrywanie usunięć zależy od źródła. Niektóre API zgłaszają usunięcia przyrostowo; inne ujawniają je dopiero podczas pełnego pobrania, więc te konektory okresowo odczytują wszystko ponownie, aby wykryć brakujące rekordy. Strona każdego konektora opisuje strategię wymuszaną przez źródło.
Migawki#
Każda synchronizacja zapisuje commit atomowo. Zapytanie zawsze odczytuje jedną spójną migawkę tabeli — nigdy częściowo zapisaną synchronizację, nawet gdy ta działa równolegle z zapytaniem. Nowe dane stają się widoczne jednocześnie po zapisaniu commitu.
Jezioro zachowuje ostatnie migawki (domyślnie przez 30 dni), a nie tylko stan bieżący. Dzięki temu atomowość jest tania, a przerwaną pracę można bezpiecznie porzucić.
Co dzięki temu zyskujesz#
Łączenie różnych źródeł bez budowania potoków: przychód według etapu sprzedaży to jedno złączenie
titan.stripe.chargesztitan.hubspot.deals.Zmiany schematu są widoczne, a nie niszczące. Gdy źródło otrzyma nową kolumnę, pojawia się ona w jeziorze, a strumień Zmiany schematu pokazuje, co i kiedy się zmieniło.
Otwarty format. Dane są przechowywane jako standardowe pliki kolumnowe ze standardowymi metadanymi tabel, a nie jako własnościowy obiekt powiązany wyłącznie z nami.
Dalej: pisanie modeli przekształca zapytania do tych tabel we własne tabele.