本文主要介绍微服务API网关的数据库设计,分为两个方面:
MySQL数据库表设计 - E-R图及关系模式Redis键值设计
目录 Table of Contents
数据库
数据库三范式
- 1NF是对属性的原子性,要求属性不可再分解。
 - 2NF是对记录的唯一性,要求记录有唯一标识,即不存在部分依赖。
 - 3NF是对字段的冗余性,要求任何字段不能由其他字段中派生出来,即不存在传递依赖。
 
绘制E-R图例
- 确定所有的实体(矩形框)
 - 确定实体的联系(连线)
 - 确定实体和联系的属性(椭圆框)
 - 确定实体的键(下划线)
 
转换关系模式
| 类型 | 映射方法 | 说明 | 
|---|---|---|
| 一元联系 | 直接映射 | 实体的属性→关系模式的属性;实体的主键→关系模式的主键 | 
| 二元联系 - 一对一 | 合并关系模式 | 合成一个关系模式 R;任一实体的全部主键→关系模式的主键 | 
| 二元联系 - 一对多 | 引入外键 | 一方实体的主键→多方实体的外键;联系的属性→多方实体的属性 | 
| 二元联系 - 多对多 | 增加关系模式 | 增加一个关系模式 R;两个实体的主键并集→关系模式的主键;联系的属性→关系模式的属性 | 
| 超类子类 | 分化关系模式 | 分化两个关系模式 R1 和 R2;R1是父关系模式,包括R1主键和R1非主键;R2是子关系模式,包括R1主键和R2非主键;若概括是全部的,不用创建父关系模式,子关系模式包括所有 | 
| 复合属性 | 由子属性代替 | 复合属性 A → 多个子属性代替 A1, A2, A3, … | 
| 多值属性 | 拆分关系模式 | 拆成两个关系模式 R1 和 R2;R1包括R的主键和M的本身;R2包括R的主键和除多值属性外的属性;注意设置级联操作 | 
MySQL 数据库表设计
用户的数据库表设计

实体
- 用户实体拥有用户ID、用户名称、加密密码和加密盐值四种属性,其中出于安全性的考虑,密码需要经过盐值加密后存储在数据库而非直接明文存储。
 
联系
- 没有联系可以分析。
 
转换
- 对用户的E-R图进行一元联系类型转换,得出关系模式:用户实体的属性为独立的一张表。
 
服务的数据库表设计

实体
- 服务实体拥有服务ID、服务名称、服务描述和协议类型四种属性,其中协议类型是多值属性,用于扩展和适配接入不同协议的服务,目前可支持 
HTTP、HTTPS和WebSocket协议。 - 协议接入与请求重写配置实体固定具有地址和重写规则属性,从协议接入与请求重写配置中可以泛化出各种类型的协议配置,不同协议的配置内容不尽相同。
 - 权限认证配置实体包含ip黑白名单的属性,用于鉴别请求来源。
 - 流量控制配置实体是相对服务而言的,具有限流间隔和限流次数属性,可以支持周期灵活的限流策略。
 - 负载均衡配置实体有三大属性,分别为ip列表、weight列表和算法类型,其中算法类型是多值属性,标识了负载均衡使用的算法,目前支持随机负载均衡、轮询负载均衡、加权轮询负载均衡和一致性哈希负载均衡四种算法。
 
联系
- 服务实体与协议接入与请求重写配置实体、权限认证配置实体、流量控制配置实体、负载均衡配置实体和反向代理配置实体的关系都是一对一的拥有关系。特别地,协议接入配置实体存在泛化,可以衍生出不同类型的协议接入与请求重写配置。
 
转换
- 对服务的E-R图进行二元联系类型转换,得出关系模式:服务实体与权限认证配置实体、流量控制配置实体、负载均衡配置实体和反向代理配置实体合并为一张数据库表,为了考虑后续对其他协议进行扩展,故每种协议配置都建议新建一张数据库表。
 
应用的数据库表设计

实体
- 应用实体拥有应用ID、应用标识、应用名称和应用密钥四种属性,其中出于安全性的考虑密钥应该存储加密后的密文而非明文。
 - 权限认证配置实体包含ip黑白名单的属性,用于鉴别请求来源。
 - 流量控制配置实体是相对应用而言的,具有QPD(每日请求量)限制和QPS(每秒请求量)限制两种属性。
 
联系
- 应用实体与权限控制配置实体和流量控制配置实体的关系都是一对一的拥有关系。
 
转换
- 对应用的E-R图进行二元联系类型转换,得出关系模式:服务实体与权限认证配置实体和流量控制配置实体合并为一张数据库表。
 
Redis 键值设计
会话的键值设计
| 键 | 值类型 | 值内容 | 
|---|---|---|
session_{session_id} | 
Binary | 会话信息 | 
配置的键值设计
| 键 | 值类型 | 值内容 | 
|---|---|---|
app_{app_id} | 
String | app po as json | 
service_{service_id} | 
String | service po as json | 
lb_{lb_id} | 
String | load balance po as json | 
ac_{ac_id} | 
String | access control po as json | 
计数器的键值设计
| 键 | 值类型 | 值内容 | 
|---|---|---|
flow_day_count_{day_format}_flow_total_count | 
String | 总计每一天的流量统计数 | 
flow_hour_count_{hour_format}_flow_total_count | 
String | 总计每小时的流量统计数 | 
flow_day_count_{day_format}_flow_service_count_{service_name} | 
String | 单个服务每一天的流量统计数 | 
flow_hour_count_{hour_format}_flow_service_count_{service_name} | 
String | 单个服务每小时的流量统计数 | 
flow_day_count_{day_format}_flow_app_count_{app_id} | 
String | 单个应用每一天的流量统计数 | 
flow_hour_count_{hour_format}_flow_app_count_{app_id} | 
String | 单个应用每小时的流量统计数 | 
限流器的键值设计
| 键 | 值类型 | 值内容 | 
|---|---|---|
rate_flow_service_count_{service_name} | 
String | 单个服务调用结束的时间点 | 
rate_flow_app_count_{app_id} | 
String | 单个应用调用结束的时间点 |