关系型数据库
本篇介绍关于关系型数据库设计与使用的最佳实践。
选择数据库
在.NET生态中,第一选择是SQL Server,其次是PostgreSQL。
付费选择SQL Server,免费选择PostgreSQL。
简要原因
- 自身功能强大,适用性广泛。
- .NET生态有非常好的支持,背后都有微软开发团队的支持。
- EF Core支持非常好,更新及时。
Note
新项目直接上SQL Server 2025+和PostgreSQL 18+。
操作数据库
使用Entity Framework Core
EF Core是微软官方的ORM框架,推荐使用EF Core来作为常规的数据访问方式,它也支持原生SQL查询,并经过官方和社区的优化,查询效率非常高。
批量操作
这里指专注于速度的大批量的数据插入、更新、删除等操作。
EF Core并不适合这类操作,你可以使用:EFCore.BulkExtensions,针对不同的数据库,使用不同的底层实现,来实现高效的批量操作。
数据库表结构设计
我们推荐一些常见的实践和指导,帮助你节省下在设计上争论的时间。
外键
❌ 统一不使用外键是"脑瘫"的做法,丧失了关系型数据库的重要特性。
我们推荐你在同一领域模型中使用外键,以增强约束。而在跨领域模型中,有选择的使用外键。
典型场景就是用户实体,它通常是跨领域的,甚至是跨服务,跨数据库的,这种情况下,不应或无法使用外键关联。
字段类型选择
同样,为了减少争论花费的时间,我们推荐一些常见的字段类型选择。
- ✅主键使用
Guid,客户端生成,使用Guid V7。 - ✅避免使用字符串分隔符表示多个值,也不使用关联表,直接使用数组类型(PostgreSQL)或者JSON类型(SQL Server)。
- ✅时间类型使用
DateTimeOffset,入库时,统一转换为UTC时间。 - ✅日期类型使用
DateOnly,入库时,统一转换为UTC日期。 - ✅仅在必要时,使用乐观锁字段,比如
RowVersion。
Tip
避免在无意义的争论中浪费时间,直接使用这些推荐的做法,除非它不符合你的业务需求。
数据库迁移
在开发迭代过程中,数据库结构也会更新,推荐使用Code First的方式,来集中管理数据库结构,避免由于手动操作导致的差异。
MigrationsService项目,就是用来更新数据库结构的,当我们通过AppHost启动应用时,它会自动应用最新的数据库迁移,其他服务在它执行完成后再启动。
在scripts目录下,提供了生成迁移的脚本EFMigrations.ps1,你可以直接使用它来生成迁移,或根据实际需要进行修改,生成的迁移文件默认会在EntityFramework/Migrations目录下。
多数据库支持
在EntityFramework项目的AppDbContext目录下,添加额外的DbContext。
然后在ServiceDefaults项目的FrameworkExtensions扩展类中,注入添加的DbContext。
在使用是,通过UniversalDbFactory工厂类,获取对应的DbContext实例。