A database model represents a database schema through data types and structures. It translates domain types into storage-oriented entities whose keys, timestamps, and primitive types fit the database. section 11.2.1
Keep the database model separate from the domain model. This boundary lets each representation evolve independently and prevents database-specific types from leaking into business logic. section 12.0 section 12.1.1
Design the model around the persistence system while preserving explicit conversions:
- Use database-related types for stored entities rather than treating every value as an untyped string. section 11.2.1
- Map domain fields to database-compatible types such as INTEGER, FLOAT, and TIMESTAMP. section 12.1.1
- Convert through dedicated functions such as fromDBMeteor and toDBMeteor at the persistence boundary. section 12.1 section 12.1.1
- Choose keys deliberately; composite natural keys based on floating-point coordinates and timestamps have important drawbacks. section 12.1.1
Persisting a meteor
A domain Meteor can be converted to DBMeteor, loaded by a primary key, and converted back. In a key–value store, KVDBMeteor is serialized as JSON and saved under a meteor identifier. section 11.2.1 section 12.1
getDBMeteor :: MeteorID -> SqlDBConn -> LangL DBMeteor
getDBMeteor meteorId connection =
runDatabaseQuery connection
(loadByPrimaryKey meteorId) #1
getMeteor :: MeteorID -> SqlDBConn -> LangL Meteor
getMeteor meteorId connection = do
dbMeteor <- getDBMeteor meteorId connection
pure (fromDBMeteor dbMeteor) #2
Shows the two-step relational lookup: retrieve a database entity through a connection, then convert it into the domain type. section 12.1






















