1. 数据结构设计规范
1.1. 基本原则
- 遵循第三范式,适度冗余提升性能,并保证数据的一致性。
- 符合命名规范( 注意关键字 、长度限制)。
- 使用正确的数据类型、合适的长度。
- 新建的表对于频繁查询的字段需要建立索引。
1.2. 命名规范
表的命名:模块(缩写)+表含义,例:平台模块的表前缀为ctp_,协同模块的表前缀为col_,表单模块的表前缀为cap_。
表名与字段名使用下划线区分单词,以增加可读性。在HBM文件与POJO中则去除下划线, 第一个单词的首字母小写,其后单词的首字母大写。
- 表中相同概念的字段,应该使用相同的名字、相同的类型、相同的值域,HBM映射文件与POJO类尽量保持一致的命名。例:”创建时间“在数据库中字段名为create_time,类型为datetime;在HBM映射文件与POJO类中属性名为createTime,类型为java.util.Date。
- 索引命名:唯一,IDX_表缩写_索引字段缩写
- 表主键:id在数据库中为bigint类型,在POJO中为long类型,通过UUID算法生成。
- 表外键:被引用表缩写_id。
- 注意关键字
- 长度限制(表名、字段名、索引名长度统一不能超过25,预留PK_前缀等)
1.3. 常用数据类型
下表中是我们经常用到的一些字段的类型与值域,请大家在设计数据库之前先查询一下这张表看看类似的字段是如何定义类型与值域的。
- 单表所有VARCHAR类型的字段长度加起来,乘以4,不能超过65535。
MYSQL | ORACLE | 达梦 | POSTGRESQL/人大金仓 | SQLSERVER | HBM文件 | POJO类型 |
---|---|---|---|---|---|---|
SMALLINT | NUMBER(4) | SMALLINT | INT2 | SMALLINT | integer | java.lang.Integer |
INT | INTEGER | BIGINT | INT4 | INT | integer | java.lang.Integer |
BIGINT | INTEGER | BIGINT | INT8 | BIGINT | long | java.lang.Long |
VARCHAR | VARCHAR2 | VARCHAR2 | VARCHAR | NVARCHAR | string | java.lang.String |
DATETIME | DATE | TIMESTAMP | TIMESTAMP | DATETIME | timestamp | java.util.Date |
DECIMAL(10,2) | NUMBER(10,2) | NUMBER(10,2) | DECIMAL(10,2) | DECIMAL(10,2) | double | java.lang.Double |
LONGTEXT | CLOB | CLOB | TEXT | NTEXT | clob | java.lang.String |
1.4. 常用字段定义规范
字段名 | 中文名 | 类型(mysql) | 描述 |
---|---|---|---|
Id | 主键id | bigint(20) | |
subject | 标题 | varchar(255) | 长度统一定义为255,js前段校验为80 |
content | 正文 | longtext | 慎用!必须使用时请说明理由 |
description | 描述 | varchar(2000) | 长度统一定义为2000,js前段校验为500 |
create_member_id | 创建人id | bigint(20) | 人员表id |
update_member_id | 修改人id | bigint(20) | 人员表id |
create_time | 创建时间 | datetime | yyyy-MM-dd HH:mm:ss |
update_time | 修改时间 | datetime | yyyy-MM-dd HH:mm:ss |
1.5. 禁止
- 禁止三表以上联查,容易导致性能问题。
- 数据存储不要使用XML,避免序列化和反序列化性能问题。如果必须存储复合数据,建议使用JSON。
- 数据类型不要使用BLOB,非结构化数据请使用文件存储。
- 禁止循环SQL操作
- 禁止大字段查询
- 禁止不分页查询
2. 数据结构变更规范
2.1. 变更流程
① 开发人员:描述变更内容,提交流程 ② 开发经理:检查数据结构设计是否合理,是否有索引,索引设计是否合理 ③ DBA:审核数据库规范(半自动化) ④ 系统环境工程师:更新测试环境,知会其他人员(开发,测试)
迭代结束后,会多维度统计变更情况(按表,按类型等),分析原因,总结经验,哪些容易考虑遗漏,提前预埋,提升大家数据结构设计能力。
2.2. 变更版本
主干变更
- 发起《数据结构变更》
分支月度修复包变更(含快速需求响应)
- 原则上不允许数据结构变更,尽量减少,必须使用时发起《数据结构变更》特殊处理
2.3. 变更类型
增加表
删除表
大版本清理项,确认不使用删除初始化创建脚本,不执行升级
增加字段
修改字段类型
原则上不允许修改,除非必须修改且数据库允许修改且已产生数据不影响的前提下,建议增加新字段兼容
修改字段长度
修改字段名称
建议不修改,一般用于支持新数据库时因为使用了关键字必须修改
调整初始化数据
建议程序处理,比如每个单位下需要预制一套单位公告板块:
集团版监听单位新建事件,兼听单位修改修改事件(如新建监听失败,可尝试补偿,方便修复,内部逻辑做好兼容,有数据则不初始化)。
@ListenEvent(event = AddAccountEvent.class)
public void onAddAccount(AddAccountEvent evt) throws Exception {
bulTypeManager.initBulType(evt.getAccount().getId());
}
企业版通过系统启动初始化
public class BulSystemInitializer extends AbstractSystemInitializer {
private static Log log = LogFactory.getLog(BulSystemInitializer.class);
private OrgManager orgManager;
private BulTypeManager bulTypeManager;
public void setOrgManager(OrgManager orgManager) {
this.orgManager = orgManager;
}
public void setBulTypeManager(BulTypeManager bulTypeManager) {
this.bulTypeManager = bulTypeManager;
}
@Override
public void initialize() {
log.info("企业版初始化单位公告板块......开始");
try {
V3xOrgAccount rootAccount = orgManager.getRootAccount();
if (rootAccount != null && !rootAccount.isGroup()) {
// 内部逻辑做好兼容,有数据则不初始化
bulTypeManager.initBulType(rootAccount.getId());
}
} catch (Exception e) {
log.error("", e);
}
log.info("企业版初始化单位公告板块......结束");
}
@Override
public void destroy() {
}
}
调整索引
根据查询条件,优化索引,提升查询效率,注意索引长度限制。