ClickHouse, kolumnowa baza do analityki
ClickHouse to kolumnowa baza danych zbudowana wokół jednego zadania: liczenia agregatów po miliardach wierszy w czasie mierzonym w setkach milisekund. Ceną za tę szybkość jest model danych, w którym zmiana albo usunięcie pojedynczego wiersza jest operacją kosztowną, a nie rutynową. Ten tekst opisuje, kiedy taka wymiana się opłaca.
Do czego ClickHouse jest zbudowany, a do czego nie
Różnica między bazą wierszową a kolumnową brzmi jak szczegół implementacyjny, a rozstrzyga o wszystkim, co dzieje się wyżej. W PostgreSQL wiersz leży w pliku jako jeden ciągły kawałek bajtów, więc pobranie całego rekordu po kluczu podstawowym to jeden odczyt. W ClickHouse każda kolumna jest osobnym plikiem, skompresowanym niezależnie od pozostałych. Zapytanie sumujące jedną kolumnę po dziesięciu miliardach wierszy dotyka wyłącznie tej jednej kolumny i nie wczytuje z dysku ani bajtu pozostałych. Zapytanie pobierające cały wiersz musi natomiast odwiedzić tyle plików, ile jest kolumn w tabeli.
Stąd bierze się cały podział zastosowań. ClickHouse nadaje się do zdarzeń analitycznych, logów, metryk, danych telemetrycznych i wszystkiego, co spływa w dużych ilościach i jest odpytywane zbiorczo. Nie nadaje się do przechowywania stanu aplikacji, koszyka zakupowego, sesji użytkownika ani niczego, co wymaga odczytu i zapisu pojedynczych rekordów po identyfikatorze. Do tego drugiego zestawu masz Postgresa, Supabase albo Redisa i żadna z tych rzeczy nie jest przez ClickHouse zastępowana.
Typowy układ produkcyjny stawia obie bazy obok siebie. Baza transakcyjna trzyma stan, ClickHouse dostaje strumień zdarzeń i odpowiada na pytania analityczne. Tak działa między innymi PostHog, który przechowuje metadane w Postgresie, a zdarzenia produktowe w ClickHouse, i który jest dobrym przykładem tego, jak wygląda ten podział w prawdziwym produkcie.
Brakuje tu też rzeczy, których obecność w bazie SQL uznaje się za oczywistą. Nie ma transakcji obejmujących wiele instrukcji. Klucz podstawowy nie jest unikalny i nie wymusza unikalności, bo pełni zupełnie inną rolę niż w bazie wierszowej. Klucze obce nie istnieją. Złączenia działają, ale są znacznie słabszym miejscem systemu niż agregacje i przy dużych tabelach po obu stronach potrafią rozczarować.
Wersje, licencja i sposób dystrybucji
Numeracja wydań idzie według schematu rok kropka miesiąc. Najnowsze wydanie stabilne w chwili pisania to 26.6.3.62, opublikowane w rejestrze obrazów 19 sierpnia 2026 roku pod znacznikiem latest. Równolegle utrzymywane są linie długoterminowe: obrazy 26.3.20.7 oraz 25.8.31.9 trafiły do rejestru 20 sierpnia 2026 roku, czyli dzień po wydaniu bieżącym. Jeśli prowadzisz własne wdrożenie, ta druga ścieżka jest rozsądniejsza, bo tempo wydań głównych jest bardzo szybkie.
Licencja jest tym rzadkim przypadkiem, w którym trzy sprawdzane źródła mówią to samo. Plik LICENSE w gałęzi głównej repozytorium zawiera pełny tekst Apache License 2.0 z notą prawnoautorską ClickHouse, Inc. na lata 2016 do 2026. Pole license w rejestrze npm dla pakietu @clickhouse/client ma wartość Apache-2.0. Rozpakowana paczka opublikowana w rejestrze zawiera plik LICENSE z tym samym tekstem Apache 2.0, przy czym nota prawnoautorska mówi tam o latach 2016 do 2024. To rozbieżność w dacie, nie w warunkach, więc dla audytu zależności nie ma znaczenia, ale pokazuje, że plik licencyjny w paczce nie jest odświeżany przy każdym wydaniu. Ten sam wynik daje ekosystem Pythona: pakiet clickhouse-connect w wersji 1.7.2 deklaruje Apache-2.0 zarówno w polu license, jak i w klasyfikatorach.
Sterownik dla Node deklaruje wersję 1.23.1. Warto rozróżniać te numery od numeru serwera, bo biblioteki klienckie mają własny cykl wydawniczy i wersja 1.23.1 nie mówi nic o tym, z jakim serwerem rozmawia.
Praktyczny wniosek z licencji jest krótki. Cały rdzeń, razem z replikacją, przechowywaniem na dyskach obiektowych i wszystkimi silnikami tabel z rodziny MergeTree, jest na licencji permisywnej i wolno go używać komercyjnie bez opłat. Podział na płatne i darmowe przebiega gdzie indziej: nie przez licencję kodu, tylko przez to, co jest dostępne wyłącznie w usłudze zarządzanej.
Model danych, czyli MergeTree i klucz sortowania
Silnik MergeTree i jego pochodne to fundament, na którym stoi reszta. Dane wstawiane do tabeli lądują w niezmiennych fragmentach zwanych częściami, a proces w tle scala małe części w większe. Każda część jest posortowana według klucza sortowania podanego w klauzuli ORDER BY.
CREATE TABLE analytics.events
(
project_id UInt32,
event_type LowCardinality(String),
event_time DateTime,
user_id UInt64,
session_id UUID,
country LowCardinality(String),
duration_ms UInt32,
properties Map(String, String)
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(event_time)
ORDER BY (project_id, event_type, event_time)
TTL event_time + INTERVAL 90 DAY DELETE
SETTINGS index_granularity = 8192;Klauzula ORDER BY jest tu najważniejszą decyzją projektową i jednocześnie tą, którą najtrudniej później zmienić. To ona wyznacza fizyczną kolejność wierszy na dysku oraz rzadki indeks podstawowy, który zamiast wskaźnika na każdy wiersz trzyma jeden wpis na każde index_granularity wierszy, domyślnie na każde 8192. Zapytanie filtrujące po przedrostku tego klucza czyta tylko te ziarna, które mogą zawierać pasujące dane. Zapytanie filtrujące po kolumnie spoza klucza czyta wszystko.
Z tego wynika reguła kolejności kolumn w ORDER BY: najpierw kolumny o niskiej liczbie różnych wartości i te, po których filtrujesz zawsze, na końcu kolumny o wysokiej liczności, zwykle czas. Odwrotna kolejność, czyli identyfikator użytkownika na początku, praktycznie unieważnia indeks dla większości zapytań i jednocześnie psuje kompresję, bo sąsiadujące wartości przestają być podobne.
Typ LowCardinality(String) w powyższej definicji nie jest ozdobnikiem. Zamienia powtarzalne łańcuchy znaków na słownik z indeksami całkowitymi, co przy kolumnie w rodzaju nazwy zdarzenia albo kodu kraju zmniejsza zajętość i przyspiesza grupowanie. Przy kolumnie o dużej liczbie unikalnych wartości ten sam typ pogarsza sytuację, więc nie stosuje się go do identyfikatorów ani adresów URL.
Partycjonowanie działa inaczej, niż podpowiada intuicja z Postgresa. Klauzula PARTITION BY służy głównie do zarządzania danymi, czyli do szybkiego usuwania całych okresów przez DROP PARTITION oraz do reguł TTL. Do przyspieszania zapytań służy ORDER BY. Nadmiar partycji, na przykład podział dzienny przy trzyletniej retencji, tworzy tysiące katalogów i realnie spowalnia system.
Aktualizacje i usuwanie, najdroższa część układu
To jest miejsce, w którym przyzwyczajenia z bazy transakcyjnej kończą się najboleśniej. Części danych są niezmienne, więc nie istnieje coś takiego jak nadpisanie wiersza w miejscu. Każda zmiana oznacza zapisanie nowych danych i pogodzenie ich ze starymi w trakcie scalania albo odczytu.
Historycznie jedyną drogą były mutacje, czyli ALTER TABLE ... UPDATE i ALTER TABLE ... DELETE. Mutacja przepisuje całe kolumny we wszystkich częściach, których dotyczy warunek. Przy tabeli o wielkości kilkuset gigabajtów zmiana jednego pola w jednym wierszu może oznaczyć przepisanie znacznej części tabeli. Mutacja działa asynchronicznie, a jej postęp śledzi się w tabeli systemowej.
-- mutacja: przepisuje cale kolumny w dotknietych czesciach
ALTER TABLE analytics.events
UPDATE duration_ms = 0
WHERE event_type = 'heartbeat';
-- postep i ewentualny blad
SELECT mutation_id, command, parts_to_do, is_done, latest_fail_reason
FROM system.mutations
WHERE database = 'analytics' AND table = 'events' AND is_done = 0;Lżejsza droga pojawiła się później i wciąż jest oznaczona jako funkcja w wersji beta. Instrukcja DELETE FROM ... WHERE oznacza wiersze jako usunięte bez natychmiastowego przepisywania kolumn, a fizyczne usunięcie następuje przy kolejnym scaleniu. Oznacza to, że przez nieokreślony czas dane nadal leżą na dysku, tylko przestają być widoczne w wynikach. Przy usuwaniu na żądanie użytkownika, na przykład w ramach realizacji prawa do bycia zapomnianym, ten szczegół ma znaczenie prawne i istnieje ustawienie tabeli min_age_to_force_merge_seconds, które wymusza scalenie w przewidywalnym czasie.
Instrukcja UPDATE ... SET ... WHERE działa na podobnej zasadzie, zapisując tak zwane części łatające zamiast przepisywać kolumny. Ma jednak twarde warunki wstępne, o których łatwo się potknąć.
-- warunek konieczny dla lekkich aktualizacji
ALTER TABLE analytics.events
MODIFY SETTING enable_block_number_column = 1,
enable_block_offset_column = 1;
-- lekka aktualizacja, dziala tylko dla rodziny MergeTree
UPDATE analytics.events
SET duration_ms = 0
WHERE event_type = 'heartbeat' AND event_time >= '2026-08-01';
-- usuniecie oznaczajace wiersze, fizycznie znikaja przy scaleniu
DELETE FROM analytics.events
WHERE user_id = 918273;Ograniczenia są konkretne. Lekka aktualizacja obsługuje wyłącznie rodzinę silników MergeTree. Wymaga materializacji kolumn _block_number i _block_offset, włączanej ustawieniami tabeli enable_block_number_column oraz enable_block_offset_column. Nie wolno zmieniać kolumn wchodzących do klucza podstawowego ani do klucza partycjonowania. Zachowanie przy współbieżności regulują ustawienia update_sequential_consistency i update_parallel_mode, a format zapisywanych części łatających ustawienie patch_parts_version, które trzeba przypiąć do wartości v1 na czas aktualizacji kroczącej klastra.
Jeśli aktualizacje są częścią normalnego przepływu danych, a nie wyjątkiem, właściwą odpowiedzią nie jest żadna z powyższych instrukcji, tylko inny silnik tabeli. ReplacingMergeTree przyjmuje kolejne wersje tego samego klucza i przy scalaniu zostawia jedną.
CREATE TABLE analytics.subscriptions
(
subscription_id UInt64,
plan LowCardinality(String),
status LowCardinality(String),
updated_at DateTime,
is_deleted UInt8
)
ENGINE = ReplacingMergeTree(updated_at, is_deleted)
ORDER BY subscription_id;
-- FINAL scala wersje w locie, kosztem czasu zapytania
SELECT subscription_id, plan, status
FROM analytics.subscriptions FINAL
WHERE status = 'active';Pierwszy argument silnika to kolumna wersji, drugi to znacznik usunięcia, przy czym drugiego nie da się użyć bez pierwszego. Kluczowa pułapka polega na tym, że scalanie zachodzi kiedyś, a nie natychmiast, więc bez modyfikatora FINAL zapytanie może zobaczyć kilka wersji tego samego rekordu. Modyfikator FINAL daje poprawny wynik, ale przenosi koszt scalania na czas zapytania i przy dużych tabelach jest odczuwalny.
Wstawianie danych i widoki zmaterializowane
Wstawianie ma jedną regułę, której złamanie kończy się awarią w każdym wdrożeniu. Każda instrukcja INSERT tworzy nową część na dysku, a proces scalania nadąża tylko do pewnego tempa. Wstawianie po jednym wierszu zalewa system tysiącami mikroskopijnych części i kończy się błędem o zbyt wielu częściach w partycji. Dane wstawia się partiami, w praktyce od kilku tysięcy do kilkuset tysięcy wierszy naraz.
import { createClient } from '@clickhouse/client'
const client = createClient({
url: process.env.CLICKHOUSE_URL,
username: process.env.CLICKHOUSE_USER,
password: process.env.CLICKHOUSE_PASSWORD,
database: 'analytics',
max_open_connections: 10,
request_timeout: 30_000,
clickhouse_settings: {
async_insert: 1,
wait_for_async_insert: 1
}
})
await client.insert({
table: 'events',
values: batch,
format: 'JSONEachRow',
columns: ['project_id', 'event_type', 'event_time', 'user_id', 'duration_ms']
})Ustawienie async_insert przenosi buforowanie na stronę serwera, co ratuje sytuację, gdy aplikacja nie ma naturalnego miejsca na kolejkę. Włączone wait_for_async_insert sprawia, że wywołanie wraca dopiero po zapisaniu bufora, czyli zachowuje potwierdzenie zapisu kosztem opóźnienia. Wyłączenie go daje szybszą odpowiedź i ryzyko utraty danych przy awarii węzła, więc to świadomy wybór, a nie ustawienie do skopiowania bez zastanowienia.
Widoki zmaterializowane są w ClickHouse czymś innym niż w Postgresie i to jedno z najczęstszych nieporozumień. Nie są okresowo odświeżaną migawką zapytania. To wyzwalacz działający przy wstawianiu: każda nowa część w tabeli źródłowej przechodzi przez zapytanie widoku, a wynik trafia do tabeli docelowej. Dane wstawione wcześniej niż widok nie zostaną przetworzone.
CREATE TABLE analytics.events_hourly
(
project_id UInt32,
event_type LowCardinality(String),
hour DateTime,
events_count UInt64,
unique_users AggregateFunction(uniq, UInt64)
)
ENGINE = AggregatingMergeTree
ORDER BY (project_id, event_type, hour);
CREATE MATERIALIZED VIEW analytics.events_hourly_mv
TO analytics.events_hourly
AS SELECT
project_id,
event_type,
toStartOfHour(event_time) AS hour,
count() AS events_count,
uniqState(user_id) AS unique_users
FROM analytics.events
GROUP BY project_id, event_type, hour;
SELECT project_id, sum(events_count), uniqMerge(unique_users)
FROM analytics.events_hourly
WHERE hour >= now() - INTERVAL 7 DAY
GROUP BY project_id;Wzorzec z sufiksami State i Merge jest tu obowiązkowy. Funkcja uniqState zapisuje stan pośredni agregatu w kolumnie typu AggregateFunction, a uniqMerge scala te stany przy odczycie. Pominięcie tego kroku i zapisanie samej liczby daje wynik, który nie sumuje się poprawnie między okresami, bo liczby unikalnych użytkowników z dwóch godzin nie da się dodać. Zasilanie tabel wsadowo, w rytmie dobowym, częściej realizuje się zewnętrznym harmonogramem w rodzaju Apache Airflow, a widoki zmaterializowane zostawia dla agregatów liczonych w locie.
ClickHouse Cloud, cennik i funkcje tylko w chmurze
Usługa zarządzana rozlicza się za rzeczywiste zużycie w czterech pozycjach: moc obliczeniowa, przechowywanie, transfer danych oraz mechanizm wczytywania danych ClickPipes. Nie ma abonamentu za samą dostępność planu, jest cena za jednostki. Poniższe liczby pochodzą z dokumentacji rozliczeń dla regionu AWS w Wirginii Północnej i są przykładami, a nie stawkami cennikowymi.
Plan Basic zaczyna się od 66,52 USD miesięcznie dla usługi z jedną repliką o 8 GiB pamięci i 2 rdzeniach wirtualnych, 500 GB skompresowanych danych i taką samą kopią zapasową, przy sześciu godzinach aktywności dziennie. Ta kwota rozkłada się na 39,91 USD za moc obliczeniową, 25,30 USD za przechowywanie, 1,15 USD za ruch wychodzący do internetu i 0,16 USD za ruch międzyregionowy. Przy dwunastu godzinach dziennie ta sama usługa kosztuje 106,44 USD, a przy pracy ciągłej 186,27 USD, bo rośnie wyłącznie składnik obliczeniowy.
Plan Scale zaczyna się od 499,38 USD miesięcznie przy dwóch replikach po 8 GiB i pracy przez całą dobę. Podniesienie replik do 16 GiB podnosi sam składnik obliczeniowy do 873,89 USD. Dla planu Enterprise dostawca nie podaje ceny wejściowej, tylko przykłady: dwie repliki po 32 GiB z 5 TB danych i jedną kopią zapasową dają razem 2669,40 USD miesięcznie.
Stawki transferu są podawane osobno dla każdego regionu i dają się sprawdzić. Dla regionu w Wirginii Północnej strona cennika podaje 0,1152 USD za gigabajt ruchu wychodzącego do internetu oraz 0,0312 USD za gigabajt ruchu międzyregionowego, co po przemnożeniu przez wolumeny z przykładu Basic daje dokładnie kwoty 1,15 i 0,16 USD z tabeli. Ta pozycja rachunku jest łatwa do przeoczenia przy planowaniu, a przy pulpitach odpytujących bazę bezpośrednio z przeglądarki potrafi urosnąć.
Rozliczenie prowadzone jest w jednostkach nazwanych ClickHouse Credit, gdzie jeden kredyt równa się jednemu dolarowi. Przy płatnościach przez Stripe faktura pokazuje jeden kredyt jako 0,01 USD, ponieważ ten operator nie obsługuje ułamkowych ilości. To rozbieżność wyłącznie w prezentacji, ale przy automatycznym parsowaniu faktur trzeba o niej wiedzieć. Nowe konto dostaje trzydziestodniowy okres próbny.
Podział funkcji między planami jest równie istotny co ceny. Plan Basic ogranicza przechowywanie do 1 TB, pamięć do przedziału 8 do 12 GiB, działa w jednej strefie dostępności i wykonuje kopie zapasowe co 24 godziny z jednodniową retencją, bez możliwości konfiguracji. Plan Scale znosi limit przechowywania, daje konfigurowalną pamięć, dwie lub więcej stref dostępności, sieć prywatną, automatyczne skalowanie pionowe i rozdzielenie zasobów obliczeniowych. Plan Enterprise dokłada logowanie jednokrotne SAML, regiony prywatne, szyfrowanie kluczem klienta, zgodność z HIPAA i PCI, planowane aktualizacje oraz czas reakcji trzydziestu minut dla zgłoszeń najwyższej wagi.
Funkcje wyłącznie chmurowe istnieją i trzeba je znać przed wyborem drogi wdrożenia. Rodzina silników SharedMergeTree, zaprojektowana jako zamiennik ReplicatedMergeTree działający na przechowywaniu obiektowym, napędza usługę zarządzaną i nie jest częścią wydania otwartego. ClickPipes, czyli zarządzane wczytywanie danych z Kafki, Kinesis, S3 i innych źródeł, działa wyłącznie w chmurze. Rozdzielenie zasobów obliczeniowych jest dostępne dopiero w planach Scale i Enterprise, więc nie tylko wymaga chmury, ale i konkretnego poziomu. Osobno rozwijany jest zarządzany Postgres zintegrowany z ClickHouse, w wersji beta, wyceniany od 0,125 USD za jednostkę na godzinę.
ClickHouse a alternatywy
| Cecha | ClickHouse | PostgreSQL | Elasticsearch | DuckDB | Snowflake |
|---|---|---|---|---|---|
| Model przechowywania | kolumnowy | wierszowy | odwrócony indeks | kolumnowy | kolumnowy |
| Typowe zastosowanie | agregaty po zdarzeniach | stan aplikacji | wyszukiwanie tekstu | analiza lokalna | hurtownia zarządzana |
| Zmiana pojedynczego wiersza | kosztowna, asynchroniczna | tania i natychmiastowa | przepisanie dokumentu | wymaga przepisania | kosztowna |
| Transakcje wieloinstrukcyjne | brak | pełne ACID | brak | jednoprocesowe | pełne |
| Sposób uruchomienia | serwer lub chmura | serwer lub chmura | serwer lub chmura | biblioteka w procesie | wyłącznie chmura |
| Licencja rdzenia | Apache 2.0 | PostgreSQL | AGPLv3, ELv2, SSPL | MIT | zamknięta |
Wybór rozstrzyga się na kilku pytaniach. Jeśli dane mieszczą się na jednej maszynie i analiza jest jednorazowa, DuckDB załatwia sprawę bez serwera i bez utrzymania. Jeśli pytania dotyczą treści tekstu, a nie liczb, właściwym narzędziem jest Elasticsearch. Jeśli wolumen mieści się w kilkuset gigabajtach i zapytania nie są szczególnie ciężkie, rozszerzenia kolumnowe do Postgresa wystarczą i oszczędzają całą osobną bazę do utrzymania. ClickHouse zaczyna się opłacać tam, gdzie liczba wierszy przekracza miliardy, zapytania agregują po kilku kolumnach z wielu, a czas odpowiedzi ma być mierzony w setkach milisekund przy stale rosnącym strumieniu zapisu.
Typowe błędy
Pierwszy to traktowanie klucza podstawowego jak w bazie transakcyjnej. W ClickHouse ORDER BY nie wymusza unikalności i nie zapobiega duplikatom. Ponowne wstawienie tych samych danych da dwa komplety wierszy, a nie błąd naruszenia ograniczenia, więc idempotentność musi zapewnić warstwa wczytująca albo silnik ReplacingMergeTree.
Drugi to wstawianie po jednym wierszu, zwykle w kodzie obsługującym żądanie HTTP. Każdy taki zapis tworzy osobną część, proces scalania nie nadąża i baza zaczyna odrzucać zapisy komunikatem o zbyt wielu częściach. Buforuj w aplikacji albo włącz async_insert po stronie serwera.
Trzeci to używanie mutacji jako codziennego narzędzia. Instrukcje ALTER TABLE ... UPDATE i ALTER TABLE ... DELETE przepisują całe kolumny w dotkniętych częściach, działają asynchronicznie i potrafią obciążyć klaster na godziny. Jeśli piszesz je w pętli, model danych jest zaprojektowany źle.
Czwarty to modyfikator FINAL dopisywany do każdego zapytania, żeby uniknąć duplikatów z ReplacingMergeTree. To działa, ale przenosi scalanie na czas odczytu i przy dużej tabeli kasuje przewagę wydajnościową, która była powodem wyboru ClickHouse. Sensowniejszy układ to agregacja z ostatnią wersją wybieraną funkcją argMax albo pogodzenie się z krótkim oknem niespójności.
Piąty to złe partycjonowanie. Podział dzienny przy wieloletniej retencji tworzy tysiące partycji, a każda z nich to osobny zestaw plików. Podział miesięczny to rozsądny punkt startu, a przyspieszaniem zapytań zajmuje się klucz sortowania, nie partycja.
Szósty to zapytania w postaci SELECT * przeniesione z Postgresa. W bazie kolumnowej gwiazdka oznacza odczyt wszystkich plików kolumn i jest najdroższą możliwą formą zapytania. Wypisuj kolumny jawnie, nawet gdy potrzebujesz ich większości.
Siódmy to niedoszacowanie kosztu transferu w chmurze. Pulpit odpytujący bazę bezpośrednio z przeglądarki, przy stawce rzędu jedenastu centów za gigabajt ruchu wychodzącego, potrafi wygenerować pozycję na rachunku porównywalną ze składnikiem obliczeniowym.
FAQ
Czy ClickHouse może zastąpić PostgreSQL?
Nie w roli bazy transakcyjnej. Brakuje transakcji obejmujących wiele instrukcji, unikalnych kluczy podstawowych, kluczy obcych i taniej aktualizacji pojedynczego wiersza. Standardowy układ to obie bazy obok siebie: Postgres na stan aplikacji, ClickHouse na zdarzenia i analitykę.
Jak usunąć dane jednego użytkownika na jego żądanie?
Instrukcją DELETE FROM ... WHERE, pamiętając, że oznacza ona wiersze jako usunięte, a fizycznie znikają one dopiero przy kolejnym scaleniu. Przy wymogach prawnych ustaw tabeli min_age_to_force_merge_seconds, żeby scalenie nastąpiło w przewidywalnym czasie, i sprawdź, czy dane nie są powielone w widokach zmaterializowanych.
Czy wersja otwarta ma wszystkie funkcje chmury?
Nie. Rodzina silników SharedMergeTree, mechanizm wczytywania ClickPipes oraz rozdzielenie zasobów obliczeniowych są dostępne wyłącznie w usłudze zarządzanej, a ostatnia z tych rzeczy dodatkowo dopiero w planach Scale i Enterprise. Rdzeń, replikacja i wszystkie silniki z rodziny MergeTree są otwarte na licencji Apache 2.0.
Ile realnie kosztuje ClickHouse Cloud?
Zależy od czasu aktywności usługi i wolumenu danych. Dokumentacja podaje przykład planu Basic od 66,52 USD miesięcznie przy sześciu godzinach pracy dziennie i 186,27 USD przy pracy ciągłej, oraz plan Scale od 499,38 USD miesięcznie. Do tego dochodzi transfer, wyceniany osobno dla każdego regionu.
Czy da się zmienić klucz sortowania po utworzeniu tabeli?
Praktycznie nie. Do klucza można dopisać kolumny na końcu, ale nie da się zmienić kolejności istniejących ani usunąć kolumny z klucza. Zmiana oznacza utworzenie nowej tabeli z właściwym ORDER BY i przepisanie danych, dlatego jest to decyzja, którą trzeba przemyśleć przed pierwszym wstawieniem.
Kiedy używać widoku zmaterializowanego, a kiedy zwykłego zapytania?
Widok zmaterializowany opłaca się, gdy ten sam agregat jest odpytywany wielokrotnie, a strumień zapisu jest stały. Nie przetworzy danych wstawionych przed jego utworzeniem i dokłada koszt do każdego wstawienia, więc do zapytań uruchamianych sporadycznie zwykłe zapytanie po tabeli źródłowej jest tańsze.
Dokumentację znajdziesz w serwisie ClickHouse, szczegóły rozliczeń na stronie cennika, a kod źródłowy w repozytorium na GitHubie.