Columnar storage
Storing each column together so analytical queries can read only the fields they need and compress repeated values efficiently.
See it
What it is
Columnar storage lays values from the same column next to one another instead of storing each complete row together. A query asking for sum of revenue by country can read those columns and skip names, addresses, and every other field. Similar adjacent values also compress well, and engines can evaluate batches with vectorized instructions. Apache Parquet, ClickHouse, and most cloud warehouses use this layout.
Reach for it when queries scan many records but touch a small subset of columns, especially aggregates and reporting workloads. File formats such as Parquet also store row-group statistics, so an engine can skip chunks whose minimum and maximum values cannot match a filter.
Gotcha: reconstructing one whole record can require reads from many column regions, and frequent single-row updates fight the layout. Tiny files also erase much of the benefit by adding metadata and scheduling overhead. Use a row store for transactional point lookups, compact small analytical files, and select only the columns you need rather than writing SELECT *.
Ask AI for it
Convert this event export to Apache Parquet with DuckDB. Select only typed analytics columns, derive an event_date partition, and write files with COPY ... TO using FORMAT PARQUET and COMPRESSION ZSTD. Target files of roughly 128 MB instead of one file per batch, set an explicit ROW_GROUP_SIZE so row groups are not tiny, preserve UTC timestamps, and sort each partition by tenant_id and occurred_at so row-group statistics can skip irrelevant data. Show EXPLAIN ANALYZE for a seven-day query that selects three columns, compare bytes read with the original JSON, and add a compaction step for undersized files.