Why We Shifted Away from Database‑Generated IDs to 64‑Bit Domain IDs
The article explains how our team, while building a SQL Server data catalog, adopted decoupling principles to avoid coupling business logic to a specific database, opting for domain‑generated 64‑bit IDs instead of database‑generated keys, and discusses the benefits of Snowflake‑style ID generators.
Our team is building a data catalog for SQL Server and aims to optimize the system for decoupling. We base this on two core principles: avoid linear growth of system complexity with added features, and prioritize design based on customer needs, performance, query patterns, and business changes.
We reference a line from the protoactor‑go project, "software should be composed, not built," which aligns with our view.
Impact on Persistence
We do not want our state persistence to be tightly coupled to a specific database engine. In practice, this means not leaking persistence concerns into the domain layer, because relying on a particular database (e.g., SQL Server) may not meet future capability requirements.
Consequently, persistence must appear in domain events rather than the storage system, leading to varied storage needs.
Fortunately, well‑known patterns such as CQRS and aggregate design in Domain‑Driven Design can address this with low cost.
Code‑Generated ID vs. Database‑Generated ID
Many storage systems (including SQL Server) can generate unique identifiers for each record using auto‑increment keys. However, depending on the database to generate IDs couples the business layer to the storage system, making it hard to switch to a store that does not support auto‑increment keys and causing inconsistencies across different databases.
In distributed environments, auto‑increment keys also hinder horizontal scaling.
By letting the domain‑layer consumer (the transport layer that communicates via commands and queries) generate unique identifiers, we reduce environmental dependencies and avoid relying on the database for IDs. This approach also supports distribution, allowing tables to be partitioned across multiple SQL Server instances.
Our Decision
Based on these facts, we decided to let the domain layer generate identifiers for aggregate roots, representing them as 64‑bit unsigned integers. Domain consumers can serialize these IDs as needed (e.g., as strings in ASP.NET Core MVC).
Why 64‑Bit Integers Instead of UUIDs?
While UUIDs are convenient, they incur higher storage and indexing costs. Mature algorithms like Twitter Snowflake provide efficient 64‑bit integer IDs suitable for distributed systems. We adopted the open‑source IdGen library by Rob Janssen, which implements a Snowflake‑style ID generator for .NET.
Source: Why Did We Shift Away From Database‑Generated IDs
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
