MySQL 开发规范
数据库对象命名规范
数据库对象
数据库对象是数据库的组成部分,常见的有以下几种:表(Table )、索引(Index)、视图(View)、图表(Diagram)、缺省值(Default)、规则(Rule)、触发器(Trigger)、存储过程(Stored Procedure)、 用户(User)等。命名规范是指数据库对象如数据库(SCHEMA)、表(TABLE)、索引(INDEX)、约束(CONSTRAINTS)等的命名约定。
数据库对象全局命名规范
- 命名应做到见名知意,词汇中间以下划线分隔
- 命名只能使用英文字母、数字、下划线,以英文字母开头
- 避免用MySQL的保留字如:
backup、call、group
等 - 所有数据库对象必须使用小写字母,实际上MySQL中是可以设置大小写是否敏感的,为了保证统一性,我们这边规范全部小写表示
数据库命名规范
- 数据库命名尽量不超过30个字符
- 数据库命名一般为项目名称+代表库含义的简写,比如IM项目的工作流数据库,可以是
im_flow
- 数据库创建时字符集统一使用
utf8mb4
- 命名应使用小写
表命名规范
- 常规表表名以t_开头,t代表table的意思,命名规则即 t + 模块(包含模块含义的简写)+ 表(包含表含义的简写),比如用户模块的权限信息表:
t_user_rolesinfo
- 临时表(RD、QA或DBA同学用于数据临时处理的表),命名规则:temp前缀+模块+表+日期后缀:
temp_user_rolesinfo_20211109
- 备份表(用于保存和归档历史数据或者作为灾备恢复的数据)命名规则,bak前缀+模块+表+日期后缀:
bak_user_rolesinfo_2021109
- 同一个模块的表尽可能使用相同的前缀,表名称尽可能表达含义
- 多个单词以下划线 _ 分隔
- 常规表表名尽量不超过30个字符,temp表和bak表视情况而定,也尽量简短为宜,命名应使用小写
字段命名规范
- 字段命名需要表示其实际含义的英文单词或简写,单词之间用下划线 _ 进行连接,如 service_ip、service_port
- 各表之间相同意义的字段必须同名,比如a表和b表都有创建时间,应该统一为create_time,不一致会很混乱
- 多个单词以下划线 _ 分隔
- 字段名尽量不超过30个字符,命名应该使用小写
索引命名规范
- 唯一索引使用uni + 字段名 来命名:
create unique index uni_uid on t_user_basic(uid)
- 非唯一索引使用idx + 字段名 来命名:
create index idx_uname_mobile on t_user_basic(uname,mobile)
- 多个单词以下划线 _ 分隔
- 索引名尽量不超过50个字符,命名应该使用小写,组合索引的字段不宜太多,不然也不利于查询效率的提升
- 多单词组成的列名,取尽可能代表意义的缩写,如
test_contact
表member_id
和friend_id
上的组合索引:idx_mid_fid
- 理解组合索引最左前缀原则,避免重复建设索引,如果建立了
(a,b,c)
,相当于建立了(a), (a,b), (a,b,c)
视图命名规范
- 视图名以v开头,表示view,完整结构是v+视图内容含义缩写
- 如果视图只来源单个表,则为v+表名。如果视图由几个表关联产生就用v+下划线(_)连接几个表名,视图名尽量不超过30个字符。如超过30个字符则取简写
- 如无特殊需要,严禁开发人员创建视图
- 命名应使用小写
存储过程命名规范
- 存储过程名以sp开头,表示存储过程(
storage procedure
)。之后多个单词以下划线(_)进行连接。存储过程命名中应体现其功能。存储过程名尽量不能超过30个字符 - 存储过程中的输入参数以i_开头,输出参数以o_开头
- 命名应使用小写
函数命名规范
- 函数名以func开始,表示function。之后多个单词以下划线(_)进行连接,函数命名中应体现其功能。函数名尽量不超过30个字符
- 命名应使用小写
触发器命名规范
- 触发器以trig开头,表示trigger 触发器
- 基本部分,描述触发器所加的表,触发器名尽量不超过30个字符
- 后缀(_i,_u,_d),表示触发条件的触发方式(insert,update或delete)
- 命名应使用小写
约束命名规范
-
唯一约束:uk_表名称_字段名。uk是UNIQUE KEY的缩写。比如给一个部门的部门名称加上唯一约束,来保证不重名,如下:
ALTER TABLE t_dept ADD CONSTRAINT un_name UNIQUE(name);
-
外键约束:fk_表名,后面紧跟该外键所在的表名和对应的主表名(不含t_)。子表名和父表名用下划线(_)分隔。如下:
ALTER TABLE t_user ADD CONSTRAINT fk_user_dept FOREIGN KEY(depno) REFERENCES t_dept (id);
-
非空约束:如无特殊需要,建议所有字段默认非空(not null),不同数据类型必须给出默认值(default)
`id` int(11) NOT NULL, `name` varchar(30) DEFAULT '', `deptId` int(11) DEFAULT 0, `salary` float DEFAULT NULL,
-
出于性能考虑,如无特殊需要,建议不使用外键。参照完整性由代码控制。这个也是我们普遍的做法,从程序角度进行完整性控制,但是如果不注意,也会产生脏数据。
-
命名应使用小写。
用户命名规范
- 生产使用的用户命名格式为 code_应用
- 只读用户命名规则为 read_应用
数据库对象设计规范
存储引擎的选择
-
如无特殊需求,必须使用innodb存储引擎。
可以通过
show variables like 'default_storage_engine'
来查看当前默认引擎。主要有MyISAM 和 InnoDB,从5.5版本开始默认使用 InnoDB 引擎。如何选择InnoDB还是MyISAM
- 若要支持事务,则选择InnoDB
- 若表为只读表,则可以考虑MyISAM
字符集的选择
- 如无特殊要求,必须使用utf8或utf8mb4。在国内,选择对中文和各语言支持都非常完善的utf8格式是最好的方式,MySQL在5.5之后增加utf8mb4编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode,所以utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。
表设计规范
- 不同应用间所对应的数据库表之间的关联应尽可能减少,不允许使用外键对表之间进行关联,确保组件对应的表之间的独立性,为系统或表结构的重构提供可能性。目前业内的做法一般 由程序控制参照完整性。
- 表设计的角度不应该针对整个系统进行数据库设计,而应该根据系统架构中组件划分,针对每个组件所处理的业务进行数据库设计。
- 表必须要有PK,主键的优势是唯一标识、有效引用、高效检索,所以一般情况下尽量有主键字段,核心业务表可以使用全局唯一字段(雪花算法、有序UUID)做主键。
- 一个字段只表示一个含义。
- 表不应该有重复列。
- 禁止使用复杂数据类型(数组,自定义等),Json类型的使用视情况而定。
- 需要join的字段(连接键),数据类型必须保持绝对一致,避免隐式转换。比如关联的字段都是int类型。
- 设计应至少满足第三范式,尽量减少数据冗余。一些特殊场景允许反范式化设计,但在项目评审时需要对冗余字段的设计给出解释。
- TEXT字段作为大体量文本存储,必须放在独立的表中 , 用PK与主表关联。如无特殊需要,禁止使用TEXT、BLOB字段。
- 需要定期删除(或者转移)过期数据的表,通过分表解决,我们的做法是按照2/8法则将操作频率较低的历史数据迁移到历史表中,按照时间或者自增Id做切割点。
- 单表字段数不要太多,建议最多不要大于50个。过度的宽表对性能也是很大的影响。
- MySQL在处理大表时,性能就开始明显降低,所以建议单表物理大小限制在16GB,表中数据行数控制在2000W内。业内的规则是超过2000W性能开始明显降低。但是这个值是灵活的,你可以根据实际情况进行测试来判断,比如阿里的标准就是500W,百度的确是2000W。实际上是否宽表,单行数据所占用的空间都有起到作用的。
- 如果数据量或数据增长在前期规划时就较大,那么在设计评审时就应加入分表策略,数据拆分的做法:垂直拆分(垂直分库和垂直分表)、水平拆分(分库分表和库内分表);
- 无特殊需求,谨慎使用分区表,跨分区查询效率可能会更低,建议采用物理分表的方式管理大数据
- 冷热数据分离,减小表的宽度。
- 减少磁盘IO,保证热数据的内存缓存命中率(表越宽,把表装载进内存缓冲池时所占用的内存也就越大,也会消耗更多的IO)
- 更有效的利用缓存,避免读入无用的冷数据
- 经常一起使用的列放到一个表中(避免更多的关联操作)
- 禁止在表中建立预留字段
- 禁止在数据库中存储图片,文件等大的二进制数据,可以存储到文件服务器,数据库只存储地址信息
- 对于日志类的日志表、报警表或流水表,不要使用传统的KEY_BLCOK_SIZE的页压缩。类别设计,用ENUM+CHECK约束,不要使用INT类型的设计
- MySQL通过KV的方式访问表中的数据,若业务只是简单的SET、GET请求,可以考虑将其转化为Memached的KV形式,减少SQL解析的开销,性能至少有50%的提升
字段设计规范
-
INT:如无特殊需要,存放整型数字使用UNSIGNED INT型,整型字段后的数字代表显示长度。比如
int(11) NOT NULL
-
DATETIME:所有需要精确到时间(时分秒)的字段均使用DATETIME,不要使用TIMESTAMP类型,精确到毫秒用DATETIME(6)
对于TIMESTAMP,它把写入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。而对于DATETIME,不做任何改变,基本上是原样输入和输出。另外DATETIME存储的范围也比较大:
- timestamp所能存储的时间范围为:‘1970-01-01 00:00:01.000000’ 到 ‘2038-01-19 03:14:07.999999’
- datetime所能存储的时间范围为:‘1000-01-01 00:00:00.000000’ 到 ‘9999-12-31 23:59:59.999999’
但是特殊情况,对于跨时区的业务,TIMESTAMP更为合适。
-
VARCHAR:所有动态长度字符串 全部使用VARCHAR类型,类似于状态等有限类别的字段,也使用可以比较明显表示出实际意义的字符串,而不应该使用INT之类的数字来代替;
VARCHAR(N)
,N表示的是字符数而不是字节数。比如VARCHAR(255),可以最大可存储255个字符(字符包括英文字母,汉字,特殊字符等)。但N应尽可能小,因为MySQL一个表中所有的VARCHAR字段最大长度是65535个字节,且存储字符个数由所选字符集决定。
如UTF8存储一个字符最大要3个字节,那么varchar在存放占用3个字节长度的字符时不应超过21845个字符。同时,在进行排序和创建临时表一类的内存操作时,会使用N的长度申请内存。(如无特殊需要,原则上单个varchar型字段不允许超过255个字符)
-
TEXT:仅仅当字符数量可能超过20000个的时候,才可以使用TEXT类型来存放字符类数据,因为所有MySQL数据库都会使用UTF8字符集。所有使用TEXT类型的字段必须和原表进行分拆,与原表主键单独组成另外一个表进行存放,与大文本字段的隔离,目的是。如无特殊需要,不使用MEDIUMTEXT、TEXT、LONGTEXT类型。
-
对于精确浮点型数据存储,需要使用DECIMAL,严禁使用FLOAT和DOUBLE。
-
如无特殊需要,尽量不使用BLOB类型
-
如无特殊需要,字段建议使用NOT NULL属性,可用默认值代替NULL
-
自增字段类型必须是整型且必须为UNSIGNED,推荐类型为INT或BIGINT,并且自增字段必须是主键或者主键的一部分。
-
敏感字段加密,使用动态盐+非固定加密算法(MD5/AES256等)加多轮加密,不要简单使用MD5加密,容易被暴力破解。
索引设计规范
-
索引区分度
索引必须创建在索引选择性(区分度)较高的列上,选择性的计算方式为:
selecttivity = count(distinct c_name)/count(*)
; 如果区分度结果小于0.2,则不建议在此列上创建索引,否则大概率会拖慢SQL执行。 -
遵循最左前缀
对于确定需要组成组合索引的多个字段,设计时建议将选择性高的字段靠前放。使用时,组合索引的首字段,必须在where条件中,且需要按照最左前缀规则去匹配。
-
禁止使用外键,可以在程序级别来约束完整性
- 外键会导致表与表之间耦合,UPDATE与DELETE操作都会涉及相关联的表,十分影响SQL的性能,甚至会造成死锁。
-
Text类型字段如果需要创建索引,必须使用前缀索引
-
单张表的索引数量理论上应控制在5个以内。经常有大批量插入、更新操作表,应尽量少建索引,索引建立的原则理论上是多读少写的场景。
-
ORDER BY,GROUP BY,DISTINCT的字段需要添加在索引的后面,形成覆盖索引
-
正确理解和计算索引字段的区分度,文中有计算规则,区分度高的索引,可以快速得定位数据,区分度太低,无法有效的利用索引,可能需要扫描大量数据页,和不使用索引没什么差别。
-
正确理解和计算前缀索引的字段长度,文中有判断规则,合适的长度要保证高的区分度和最恰当的索引存储容量,只有达到最佳状态,才是保证高效率的索引。
-
联合索引注意最左匹配原则:必须按照从左到右的顺序匹配,MySQL会一直向右匹配索引直到遇到范围查询(>、<、between、like)然后停止匹配。
如:depno=1 and empname>’’ and job=1 如果建立(depno,empname,job)顺序的索引,job是用不到索引的。
-
应需而取策略,查询记录的时候,不要一上来就使用*,只取需要的数据,可能的话尽量只利用索引覆盖,可以减少回表操作,提升效率。
-
正确判断是否使用联合索引(上面联合索引的使用那一小节有说明判断规则),也可以进一步分析到索引下推(IPC),减少回表操作,提升效率。
-
避免索引失效的原则:禁止对索引字段使用函数、运算符操作,会使索引失效。这是实际上就是需要保证索引所对应字段的”干净度“。
-
避免非必要的类型转换,字符串字段使用数值进行比较的时候会导致索引无效。
-
模糊查询’%value%'会使索引无效,变为全表扫描,因为无法判断扫描的区间,但是’value%'是可以有效利用索引。
-
索引覆盖排序字段,这样可以减少排序步骤,提升查询效率
-
尽量的扩展索引,非必要不新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
举例子:比如一个品牌表,建立的的索引如下,一个主键索引,一个唯一索引
PRIMARY KEY (`id`), UNIQUE KEY `uni_brand_define` (`app_id`,`define_id`)
当你同事业务代码中的检索语句如下的时候,应该立即警告了,即没有覆盖索引,也没按照最左前缀原则:
select brand_id,brand_name from ds_brand_system where status=? and define_id=? and app_id=?
建议改成如下:
select brand_id,brand_name from ds_brand_system where app_id=? and define_id=? and status=?
-
MySQL的查询基于CBO(Cost-based Optimizer),所有查询基于成本而不是规则,若发现SQL执行计划发生变化,不要怀疑SQL出错,请先分许数据特点、索引创建是否合理,是否可以通过直方图校准数据。
-
不要陷入设置单表行数、列数限制的固有印象,其他关系型数据库没有行数、列数限制 ,MySQL 也没有,大表的缺点不是性能,而是后续的 DDL 管理问题,随着 MySQL 8.0 快速加列功能的上线,大表 DDL 问题基本已解决
-
MySQL 是索引组织表,表中的数据以 B+ 树索引结构,根据主键逻辑排序,由于 B+树索引的特点是树的高度为 3~4 层,所以从数十亿的记录中,通过主键查询一条记录只需要 3、4 次 I/O,当前到 SSD 存储设备设置每秒至少能完成 10000 次的 I/O 查询,不要担心通过索引查询一条或几条记录的性能,每秒百万次查询并不难
-
MySQL 是索引组织表,二级索引只存储(键值、主键值),因此需要再通过一次主键索引查询得到记录,这种方式成为回表。在核心业务中,使用索引覆盖技术,提升索引查询性能,对于回表记录数比较大的场景,甚至可以有 10 倍的性能提升; 对类似 WHERE a = ? ORDER BY b 这样的查询,一定要创建(a、b)组合索引,这样可以避免一次额外排序,提升查询性能。
-
MySQL JOIN 支持 NLJ(Nested Loop Join)和 NHJ(Nested Hash Join)两种方式。
- 对于 OLTP 业务,放心大胆使用 JOIN,但一定要做好索引的设计和索引覆盖的考虑(不考虑分布式数据库场景);
- 对于 OLAP 业务,MySQL 8.0 版本开始,支持 Hash Join,对于大数据量的关联,性能提升非常多,可以在不超过 10T 的数仓场景中考虑使用,超过10T数据量,请一定使用大数据产品,如 Hive、Spark、麒麟等产品。
-
MySQL 5.7 版本开始子查询优化已经做得不错,但是编写的子查询不能是关联子查询 ,上线前一定需要确认,若发现关联子查询,请改写子查询为 JOIN 或其他方式。
-
不要因为数据量大,使用分区表,MySQL 是索引组织表,数据量再大,定位记录也只需要3、4 次 I/O。
- 可以考虑分区表唯一的应用场景是:需要定期清理历史流水类数据,但如果业务可以按月、按天做分表,那么当前 MySQL 8.0 版本,分区表也不推荐使用。
-
业务上线或新版本发布前,DBA 一定要进行所有 SQL Review,确保 SQL 走索引,否则不予上线,或由业务以邮件等正式方式,通知 DBA 该 SQL 不会引起线上事故,业务方承担后续责任。
-
DBA 每天要对数据库进行巡检,及早发现慢查询或潜在数据库风险,将任何潜在问题尽早抛出,否则后续自己承担相关责任
约束设计规范
- PK应该是有序并且无意义的,由开发人员自定义,尽可能简短,并且是自增序列。
- 表中除PK以外,还存在唯一性约束的,可以在数据库中创建以“uk_”作为前缀的唯一约束索引。
- PK字段不允许更新。
- 禁止创建外键约束,外键约束由程序控制。
- 如无特殊需要,所有字段必须添加非空约束,即not null。
- 如无特殊需要,所有字段必须有默认值。
高可用设计规范
- MySQL 高可用的基石是利用二进制日志的复制技术,核心业务一定要使用无损半同步方式,但凡不适用无损半同步的高可用架构,请业务方业务以邮件等正式方式回复,数据
丢失等后续问题自己承担相关责任。 - MySQL 5.7 版本开始,一定要使用基于 WRITESET 的从机回放,避免主从延迟。 当前 MySQL 发生主从延迟的可能性主要是存在大事务,比如定期计算收益等操作,这类大事务,一定要通知业务方将大事务拆成小事务,否则不予上线;若要上线,请业务方以邮件等方式回复,自己承担后续主从延迟带来的后续一系列问题。
- MySQL 8.0 版本开始推荐金融业务使用 MGR(MySQL Group Replication),通过Paxos 协议保证数据一致性,并自己完成选主的逻辑,也可以使用多主模式,数据不冲突的情况下,可以大幅提升写入性能。
- 对于核心业务,必须遵循互不信任原则,数据一致性不单单依赖 MySQL 复制本身,DBA 这里需要通过逻辑的方式,对主从数据进行核对,业务这里也需要一套业务层的逻辑进行“对账”。
- 核心业务,务必使用一地三中心,两地三中心的跨机房复制架构,这样发生机房级故障 ,可以切换到另一个机房,保证业务可用性。
- 同城容灾架构一定要评估切换到另一个机房后业务访问的性能,多次跨机房访问 DB,虽然每次只多了 2~3ms,但也存在业务雪崩问题,推荐 DB 切换机房,上层业务跟着一起联动切换。
- 对于有跨城容灾需求的业务,可以考虑使用三地五中心架构,但是由于 30ms 延迟,业务需要进行评估,对于核心业务,务必使用业务层的跨城机制,将数据层的多次网络耗时合并为一次,这样能大大提升业务的性能。
- 业界的 MHA、Ochestrator 等高可用套件都是基于 ssh 访问 MySQL,稳定性、安全性不高,不推荐大厂使用;自己开发一个数据库管理平台,通过 agent 的模式管理高可用和 MySQL 数据库的日常操作更为安全、有效。
- 一定做好数据备份架构的设计,全备 + 增量备份 + 延迟备机(可选),做到可以基于任何一点恢复和回滚,同时,遵循互不信任原则,备份文件一定要进行检查,确保需要时一定能够进行恢复
SQL使用规范
select 检索的规范性
-
尽量避免使用
select *
,join
语句使用select *
可能导致只需要访问索引即可完成的查询需要回表取数。一种是可能取出很多不需要的数据,对于宽表来说,这是灾难;一种是尽可能避免回表,因为取一些根本不需要的数据而回表导致性能低下,是很不合算。 -
严禁使用
select * from t_name
,而不加任何where条件,道理一样,这样会变成全表全字段扫描。 -
MySQL中的text类型字段存储:
- 不与其他普通字段存放在一起,因为读取效率低,也会影响其他轻量字段存取效率。
- 如果不需要text类型字段,又使用了
select *
,会让该执行消耗大量io,效率也很低下
-
在取出字段上可以使用相关函数,但应尽可能避免出现
now() , rand() , sysdate()
等不确定结果的函数,在Where条件中的过滤条件字段上严禁使用任何函数,包括数据类型转换函数。大量的计算和转换会造成效率低下,这个在索引那边也描述过了。 -
分页查询语句全部都需要带有排序条件 , 否则很容易引起乱序
-
用
in()/union
替换or
,效率会好一些,并注意in的个数小于300 -
严禁使用
%
前缀进行模糊前缀查询:如:select a,b,c from t_name where a like '%name'
; 可以使用%模糊后缀查询如:select a,b from t_name where a like 'name%';
-
避免使用子查询,可以把子查询优化为join操作。
通常子查询在in子句中,且子查询中为简单SQL(不包含
union、group by、order by、limit
从句)时,才可以把子查询转化为关联查询进行优化。子查询性能差的原因:
- 子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能 会受到一定的影响;
- 特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大;
- 由于子查询会产生大量的临时表也没有索引,所以会消耗过多的CPU和IO资源,产生大量的慢查询。
-
不会有重复值时使用UNION ALL 而不是UNION
- UNION 会把两个结果集的所有数据放到临时表中后再进行去重操作
- UNION ALL 不会再对结果集进行去重操作
-
拆分复杂的大SQL为多个小SQL
- 大SQL逻辑复杂,需要占用大量的CPU进行计算,一个SQL只能使用一个CPU进行计算,拆分之后可以通过并行执行提高处理效率。
-
不要使用 count(列名)或 count(常量)来替代 count(),count()是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关
- count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。
-
使用 ISNULL()来判断是否为 NULL 值
-
提高SQL的效率,避免不必要的无用查询。
- 在代码中写分页查询逻辑时,若 count 为 0 应直接返回,避免执行后面的分页语句
操作的规范性
-
禁止使用不含字段列表的INSERT语句
如:
insert into values ('a','b','c');
应使用insert into t_name(c1,c2,c3) values ('a','b','c');
。 -
大批量写操作(UPDATE、DELETE、INSERT),需要分批多次进行操作
-
大批量操作可能会造成严重的主从延迟,特别是主从模式下,大批量操作可能会造成严重的主从延迟,因为需要slave从master的binlog中读取日志来进行数据同步。
-
binlog日志为row格式时会产生大量的日志
-
避免产生大事务操作
大批量修改数据,一定是在一个事务中进行的,这就会造成表中大批量数据进行锁定,从而导致大量的阻塞,阻塞会对MySQL的性能产生非常大的影响。特别是长时间的阻塞会占满所有数据库的可用连接,这会使生产环境中的其他应用无法连接到数据库,因此一定要注意大批量写操作要进行分批
-
对于大表使用pt-online-schema-change修改表结构
- 避免大表修改产生的数据延迟
- 避免锁表
pt-online-schema-change它会首先建立一个与原表结构相同的新表,并且在新表上进行表结构的修改,然后再把原表中的数据复制到新表中,并在原表中增加一些触发器。把原表中新增的数据也复制到新表中,在行所有数据复制完成之后,把新表命名成原表,并把原来的表删除掉。把原来一个DDL操作,分解成多个小的批次进行
-
-
建议使用预编译语句进行数据库操作
预编译语句可以重复使用这些计划,减少SQL编译所需要的时间,还可以解决动态SQL所带来的SQL注入的问题只传参数,比传递SQL语句更高效相同语句可以一次解析,多次使用,提高处理效率。
程序上的约束
后续我们团队的目标是研发评审工具对开发同学提交的建库、建表、刷数据、查询的语句进行分析,看看是否符合应有的规范。如果不符合,驳回修改。
权限管理的规范性
- 禁止为程序使用的账号赋予super权限
- 当达到最大连接数限制时,还运行1个有super权限的用户连接
- super权限只能留给DBA处理问题的账号使用
- 对于程序连接数据库账号,遵循权限最小原则
- 程序使用数据库账号只能在一个DB下使用,不准跨库
- 程序使用的账号原则上不准有drop权限