微服务之数据建模
Posted on Tue 03 June 2025 in Journal
Abstract | 微服务之数据建模 |
---|---|
Authors | Walter Fan |
Category | learning note |
Status | v1.0 |
Updated | 2025-06-03 |
License | CC-BY-NC-ND 4.0 |
Here's my polished version of your article with improved flow and readability while maintaining your original voice and technical depth:
微服务数据建模:构建稳固的地基
数据建模是微服务设计的"地基"。没有扎实的数据建模,再漂亮的微服务架构也会变成空中楼阁。就像盖别墅群——每栋别墅可以有自己的水电系统(独立服务),但如果地基不牢,业主很快就会找上门来投诉。
一、数据建模的正确起点
很多人误以为数据建模就是"设计几张表,加几个字段和索引"。但在微服务架构中,盲目建表就像刚认识就送房送车——风险高、代价大,还可能被拉黑。
在微服务世界中,首先要问:这个服务的核心职责是什么?这是领域建模的起点。
以外卖平台为例: - 用户服务(注册/登录/认证) - 订单服务(下单/支付/取消) - 商户服务(餐厅/菜单管理) - 配送服务(骑手调度/轨迹追踪)
切忌为省事把所有表塞进一个数据库——这不是微服务,而是"伪服务"。数据该分则分,各自管理,避免服务间越界。
二、领域驱动设计(DDD)的应用
DDD强调的领域划分和聚合根设计在微服务中尤为重要。以订单服务为例:
订单(Order)聚合:
- Order(主表)
- OrderItem(明细)
- DiscountSnapshot(优惠)
- PaymentStatus(支付状态)
关键原则: - 相关数据围绕聚合根组织 - 不要直接依赖其他服务的表 - 避免跨服务join(需要数据时存快照或通过API获取)
三、数据隔离的黄金法则
微服务最忌讳共享数据库/表/字段。正确做法: 1. 每个服务独立数据库 2. 仅通过API或事件通信 3. 禁止跨服务join
获取其他服务数据的方案: - 事件驱动(如商户服务发布"餐厅更新"事件) - API调用(需加缓存避免频繁调用)
四、实用的表设计原则
设计表字段时考虑: - 查询需求 → 决定是否加索引 - 更新频率 → 避免热点字段集中 - 枚举类型 → 明确范围和含义 - 扩展性 → 考虑JSON字段
记住:数据库既不是Excel,也不是对象存储
五、Keycloak身份建模案例
Keycloak是身份认证系统,其核心概念建模:
1. Realm(领域)
像武林门派,完全隔离的顶级聚合
plaintext
Realm
- id(UUID)
- name(唯一)
- enabled
- config(JSON扩展配置)
-
User(用户)
核心但可塑性强的实体 ```plaintext User- id
- realm_id
- username
- attributes(JSON扩展) ```
-
Role(角色)
分为门派通用头衔(realm roles)和客户端特有头衔(client roles) ```plaintext Role- id
- realm_id
- client_id
- name ```
-
Client(客户端)
接入认证系统的应用 ```plaintext Client- id
- realm_id
- client_id
- protocol(OIDC/SAML) ```
-
Session(会话)
临时性数据应轻量化 ```plaintext UserSession- id
- user_id
- ip_address
- last_refresh ```
六、Keycloak设计陷阱与规避
-
JSON字段滥用
问题:难以查询和约束
方案:稳定结构拆分为独立字段 -
模糊的所有权边界
问题:Realm与Client角色混用
方案:明确区分RealmRole和ClientRole -
万能主键
问题:缺乏语义的UUID主键
方案:使用realm_id等明确归属字段 -
权限与资源紧耦合
问题:角色名包含业务逻辑
方案:建立权限策略中心管理 -
Session设计问题
问题:不适合高并发
方案:使用Redis缓存+短TTL
七、微服务友好型建模总结
原则 | 实施建议 |
---|---|
明确边界 | 强化聚合归属 |
结构清晰 | 避免过度JSON化 |
语义明确 | 字段名体现业务含义 |
权限管理 | 策略中心化 |
高频数据 | 缓存优先 |
八、自定义用户中心设计
从Keycloak模型出发,构建更适合业务的方案:
- 服务拆分
- Auth服务:认证/Token
- User服务:资料管理
- ACL服务:权限控制
-
Tenant服务:多租户支持
-
表设计优化 ```sql / User服务 / CREATE TABLE users ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, email VARCHAR UNIQUE, status VARCHAR(20) CHECK(status IN ('active','locked')) );
/ ACL服务 / CREATE TABLE permissions ( resource VARCHAR, action VARCHAR, PRIMARY KEY(resource, action) ); ```
- 架构设计
[User Service] → [Auth Service] → [ACL Service] ↑ ↓ [Tenant Service] ← [Event Bus]
关键结论
数据建模是微服务成功的基础: - 不是"先建表再思考",而是先理解业务边界 - 借鉴但不要照搬通用方案(如Keycloak) - 每个决策都要考虑演进性和团队协作成本
下次有人问"怎么设计表结构"时,你可以反问:"我们先聊聊领域边界和聚合根?"
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。