Pytanie pada w niemal każdym code review: "trzymamy te dane w JSONB czy w osobnej tabeli?". Oto reguła kciuka, którą stosuję.
Tabela jeśli...
- Pola będą filtrowane / indeksowane częściej niż raz na 1000 odczytów.
- Istnieją relacje wychodzące (FK do innych encji).
- Trzeba enforce'ować integralność na poziomie schema.
JSONB jeśli...
- Pola są opcjonalne i różne dla różnych rekordów (np. konfiguracja per-tenant).
- Schemat zmienia się szybciej niż jesteś w stanie wystawiać migracje.
- Czytasz cały obiekt naraz, nie polujesz na pojedyncze pola.
Gotcha #1: indeksy
JSONB ma GIN, ale to nie jest darmowe. Każdy INSERT płaci nim. Jeśli masz dużo zapisów i kilka odczytów — może być wolniej niż osobna tabela.
Gotcha #2: migracje
Zmiana kształtu JSONB nie jest "darmowa". Trzeba pisać UPDATE'y, które fizycznie przepisują kolumnę. Przy 50M rekordach to potrafi być kilka godzin.