A municipal asset registry must keep device rows consistent with site and owner tables, enforce foreign keys, and support ad-hoc joins under transactions. Which database type best fits that stated need?
Select an answer to reveal the explanation.
Short Explanation
City property records need ledgers that refuse orphan rows—the classic relational job. When joins, foreign keys, and transactions are the requirement, pick relational. Flattening into schemaless documents drops the integrity you asked for.
Full Explanation
A relational store that supports joins, constraints, and transactions best fits a municipal asset registry that must keep device rows consistent with site and owner tables, enforce foreign keys, and support ad-hoc joins under transactions. Relational engines are built for integrity across related entities: foreign keys prevent orphan device rows, transactions keep multi-table updates atomic, and SQL joins answer ownership and site questions without application-level glue. When the stated requirement is ledger-like consistency across tables, relational is the matching official database type.
A time-series store optimized for append-only counter samples answers heartbeat and windowed metric questions, not foreign-key integrity across device, site, and owner. A graph database chosen only because the network has a topology diagram optimizes for path traversal; it is not justified merely by a picture if the workload is constrained joins and transactions. A document store with no integrity constraints across collections can hold flexible JSON but drops the cross-collection guarantees the registry explicitly requires.
Exam caveat: relational fit assumes you actually need constraints and joins—do not force every inventory blob into rigid tables when the access pattern is whole-document cache. Operational check: attempt an insert of a device row with a non-existent site foreign key in a staging registry and confirm the engine rejects it; then run a transactional update that moves ownership and verify a mid-failure rollback leaves no half-applied rows.