A Data Model That Still Holds Up in Five Years?
We model it with you from the ground up — or review an existing model honestly and tell you what holds up and what becomes a mortgage. With a remediation path, if needed.
Most Dataverse problems in remediation projects aren't platform faults — they're modeling decisions made under time pressure and never corrected. An overly loose data type, a wrong relationship behavior: harmless individually, in sum a model nobody dares to touch anymore.
This post is the practical guide: the decisions that keep a data model sustainable in five years. The overall context is provided by our Dataverse guide — here we get into the nitty-gritty.
The most important rule is an attitude: Dataverse is data-centric. You don't build an app; you build a data model around which several apps, flows, and reports grow. Whoever starts with the app screen builds a model that understands exactly one app and blocks every second one. Concretely: before the first screen exists, the entity model is on the whiteboard — tables, relationships, keys. It feels slower on day one and is noticeably faster across the project.
Normalize first. Every business concept gets its own table; repetitions are mapped through relationships — a project has a customer via a lookup, not the customer name duplicated. There is exactly one good reason to denormalize: read performance on frequent, expensive queries. For that, Dataverse has rollup columns and calculated columns. Both are controlled denormalization: redundant, but kept consistent by the platform — the difference from a manually copied field that drifts apart at the first update.
The next diagram shows the decision: when to normalize, when to denormalize in a controlled way.
Choose the narrowest data type that meets the requirement — the one rule that saves the most work in remediations and is violated most often:
The pain comes delayed: while modeling you feel nothing. At the first report, the first integration, the first migration, you pay — with data cleanup on top.
Dataverse knows 1:N, N:1, and N:N — the kind is usually obvious. What's almost always overlooked is the cascade behavior: what happens to child records when the parent record is deleted, reassigned, or shared?
The platform defaults are rarely what you want from a business standpoint. "Cascade All" on delete means: whoever deletes a customer deletes every related project, every activity, every note along with it — one of the most common data losses in young environments, invisible until it happens.
The practical rule: create every relationship with deliberately set behavior, never wave the default through. Three questions — Delete? Reassign? Share? — answered on business grounds, not guessed technically.
For N:N, additionally: a native N:N relationship carries no attributes of its own. As soon as the link itself has data (date, role, status), you need an intermediate table with two lookups. Decided early it's cheap — retrofitted it's a migration.
Unsexy, but it shapes the project. Three rules we enforce:
hub_afa_methode becomes hub_afamethode in the API. Code against it without checking the schema name builds in runtime errors.The temptation to stuff everything into Account and Contact is strong. The rule of thumb is simple and still gets violated constantly:
Every violation — a standalone concept as a loose bundle of fields on Account — makes analysis, permissioning, and reuse harder. Permissioning is no side aspect here: an own table can be permissioned at the row level; a field bundle on Account inherits the account's visibility. More on this: Security Roles in Dataverse.
The next diagram shows the decision.
Two building blocks with great leverage:
Choices: if a value catalog is needed in more than one place — status, priority, region — it belongs global, defined once and referenced everywhere. Otherwise you maintain the same list five times and they drift apart. A genuinely table-specific choice stays local, or the global namespace gets cluttered.
Alternate keys: for every table into which data is fed from outside (integration, import, ERP sync), you define an alternate key on the business key — customer number, SKU, document number. Without it, every integration identifies records via the GUID it doesn't know and creates duplicates. It decides between a clean or a duplicated data foundation. More on this in the Dataverse guide and in Dataverse vs. SQL vs. SharePoint.
What we go through before every go-live:
N:N links with their own data carry a real intermediate table?If even one point is answered with "no," it's corrected before go-live — not "later." Almost free now, expensive with production data.
Good Dataverse modeling is unspectacular: narrow data types, deliberate relationship behaviors, own tables for standalone concepts, global choices for reused lists, an alternate key for every integration. None of it is difficult — all of it gets skipped under time pressure.
The honest truth: almost every "we'll clean that up later" never gets cleaned up and costs a multiple in the end. The hour of clean modeling at the start is the cheapest in the entire project.
We model it with you from the ground up — or review an existing model honestly and tell you what holds up and what becomes a mortgage. With a remediation path, if needed.