What is the data model of a wide-column store, and why is it described as a sparse, sorted map rather than a table of fixed columns?
answer
- a map, not a grid
- key, column, timestamp, value
- absent columns cost nothing
- stored in key order
basics
~20 sA wide-column store maps a key plus a column name plus a timestamp to a value. Only the cells a row actually has are stored, so rows can differ in their columns, and rows are stored in key order.
solid answer
~50 sA wide-column table is best read as a **map**, not a grid: a key leads to a set of cells, each cell is addressed by a column name and a **timestamp**, and holds a value. Two properties follow. It is **sparse**: a row stores only the columns it was written with, so one row can have three columns and its neighbour three thousand, and an unused column costs nothing. It is **sorted**: rows sit in key order on disk (across the whole table in stores with one sorted row key, within each partition in stores that hash the partition key), which is what makes a lookup by key or a range read along the key cheap. What it does not give you is a fixed schema of typed columns you can filter on freely: everything efficient starts from the key.
go deeper
Be able to say the data model in one sentence, a sorted map from key, column and timestamp to a value, and explain what sparse means for a row.
Explain how sorting by key makes key lookups and range reads cheap, and why filtering on a non-key column forces a scan.
Show how the model shapes design choices, such as putting data that is read together under one key and using column names to carry data in wide rows.
Be ready to argue when the flexibility of a sparse, schema-light model is worth the lost joins, ad-hoc queries and type safety for a team's workload.
## From tables to a sorted map A relational table is a grid: every row has the same typed columns, and a missing value is still a slot holding `NULL`. A **wide-column store** starts from a different picture. Its data model is a **map** whose lookup key has several parts: 1. a **row key** (in some stores split into a partition key and clustering columns), 2. a **column name** — usually a column **family** plus a **qualifier** inside it, 3. a **timestamp**, and whose value is an uninterpreted value (often just bytes). The original description of the design called it a *sparse, distributed, persistent, multi-dimensional sorted map*, and every word earns its place. ## Sparse: only the cells that exist are stored Because a column is just part of a cell's address, a row stores **only the cells that were written to it**. Two rows in the same table can have completely different columns, and a table can hold millions of distinct column names while each row carries a handful. There is no per-row cost for a column a row does not use. This is why the model suits: - **heterogeneous records** (a product catalogue where each category has its own attributes), - **wide rows** where column names themselves carry data (one column per follower, per sensor reading, per day), - schemas that grow without a migration: a new attribute is simply a new column name in the next write. The price is that the store knows little about types or shape; validation lives in the application. ## Sorted: order is part of the contract Rows are kept **sorted by key** on disk. In stores with a single sorted row key that order runs across the whole table; in stores that hash a partition key, partitions are placed by hash and the order runs **inside each partition**, by its clustering columns. Sorting is not a cosmetic detail: it is what makes the two cheap operations cheap. | operation | why it is cheap | what makes it expensive | |---|---|---| | read one key | the key locates the server and the position on disk | nothing, if you know the key | | read a range of adjacent keys or rows | neighbours are stored together, read sequentially | a range that does not follow the sort order | | filter on a non-key column | not supported efficiently | the store must scan and discard | So the design question is always *what order do I want the data in*, because that order is fixed by the key. ## Timestamps: the third dimension Every cell carries a **timestamp**. Stores use it in two ways: to decide which value is current when the same cell is written more than once (the newest timestamp wins), and, in some stores, to keep several **versions** of a cell readable, trimmed by a per-family rule such as "keep the last three" or "keep seven days". Even where only the newest value is visible, the timestamp is what lets replicas and background merges agree on which write is current. ## What the model gives up - **No joins**: related data you want together must be stored together, under the same key. - **No ad-hoc filtering**: a predicate on a column that is not part of the key means scanning. - **Weak typing**: the store will happily hold two different shapes under one column name. ## Putting it together A good mental model for interviews: *"a distributed, persistent sorted map from (key, column, timestamp) to value, where only written cells exist."* From that sentence you can derive why keys are designed around queries, why wide rows are possible, and why a query that does not start from the key is the one the store punishes.
- If rows can have different columns, where does schema enforcement happen?Mostly in the application. Some stores declare column families or typed columns up front, but the set of column names inside a family is open. Teams usually enforce shape in the writing code and document the layout, because the store will accept whatever cells it is given.
- Why does sorted storage matter for time-series data?If the key places readings for one source next to each other in time order, a "last hour for this device" query becomes one contiguous range read instead of many scattered lookups. Order is chosen by the key, so the key has to be designed with that read in mind.
It is like a filing cabinet sorted by folder label, where each folder holds only the sheets that were ever written and every sheet is date-stamped; there is no blank form for fields nobody filled in.
saying these in an interview costs you the question
- Treating a wide-column table like a relational table with nullable columns
- Believing a column that a row does not use still takes space in that row
- Expecting to filter efficiently on any column, not just the key
- Thinking wide-column means the data is stored column by column for analytics