A relational model represents application information through tables organized by a schema and connected through references rather than nested domain structures. Starting with this database representation can bias program types toward less intuitive relational shapes, so a domain model usually comes first and the database model follows. section 12.0 section 12.3
Designing and implementing a relational model involves several trade-offs:
- Separate the domain model from the database model so each can evolve independently as the application grows. section 12.0
- Distribute unavoidable complexity among database storage, an intermediate layer, and the database model. section 12.2.1
- Use a schema description rather than bare string-based queries when maintainability and type safety matter. section 12.2.1
- Balance type safety, convenience, simplicity, and coupling instead of assuming one mapping technique solves every problem. section 12.3
A typed Haskell database subsystem
A Haskell application can declare its relational model through an SQL connector such as beam, Selda, or Esqueleto. The beam approach uses Higher-Kinded Data to represent related model variations and reduce repeated declarations. This offers stronger typing than unstructured queries, but the mapping remains technically complex and can introduce high coupling. section 12.2.1 section 12.3
Figure 12.3 Database subsystem layers
Use the database-subsystem layer diagram to locate storage, intermediate mapping, and relational-model responsibilities. section 12.2.1

