Relations & Indexes
intermediate14 min readLesson 104 of 180
Primary keys, foreign keys, and secondary indexes as derived structures every write must maintain.
Modeling relations without a database
SQL thinking transfers directly to repository design:
- Primary key โ the map key (id), unique and immutable
- Foreign key โ a field referencing another aggregate's id
(
Expense.categoryId()) - JOIN โ a method that combines repositories or a denormalized view
- UNIQUE constraint โ the store checks and rejects duplicates
(
savethrows on conflicting email) - INDEX โ a secondary
Map<String, List<Expense>>byCategory, kept consistent on every write
That last one is the deep idea: an index is a derived structure. Every write path must maintain it โ the classic bug is updating the main store and forgetting the index:
public Expense save(Expense e) {
Expense old = store.put(e.id(), e);
if (old != null) byCategory.get(old.category()).remove(old);
byCategory.computeIfAbsent(e.category(), k -> new ArrayList<>()).add(e);
return e;
}
Rebuilding indexes on read (findAll filters on the fly) is correct but
O(n) per query โ the tradeoff databases charge you for.