Database per Service
Each service owning its own datastore, with no other service reading or writing it directly.
The pattern that makes a service boundary real. A service that does not own its data is not a service: its schema is a de facto public contract, any consumer can violate its invariants, and it cannot be changed or replaced independently — which removes the entire reason for separating it.
It also enables polyglot persistence honestly, since each service can choose the store its workload actually needs rather than sharing one compromise.
What it costs is significant and should be stated plainly. No joins across services, so a query spanning domains becomes an API composition, a read model, or a denormalised copy. No foreign keys or transactions across boundaries, so integrity becomes an application concern and consistency becomes eventual — which is what sagas and outboxes exist to manage. Reporting gets harder, since there is no single database to query, which is what pushes organisations towards a warehouse fed by CDC or events. And operational surface multiplies: many stores to back up, patch, monitor and tune.
Enforcement matters more than intention. Separate credentials per service, network policy preventing cross-service database access, and separate schemas or instances — because a shared database with a convention against reading other tables reverts within a year.