开发中 MySQL 规范

一、建表规范

 
1、数据库名、表名、字段名必须使用小写字母或数字,并且禁止以数字开头

示例:goods_category、agent_operate_201812_log

 
 
2、数据库名、表名、字段名要做到见名识意

示例:goods_category,不能 gc

 
 
3、配置表建议以 xx_config 形式命名

示例:shop_payment_config

 
 
4、日志表建议以 xx_log 形式命名

示例:system_log

 
 
5、临时表建议以 temp_xx 形式命名

示例:temp_order_info_export

 
 
6、创建时间使用 create_time,更新时间使用 update_time

类型使用 int(11) unsigned

 
 
7、字段类型为字符串时需要注意的

如果存储的字符串长度几乎相等,则应该使用 char 定长字符串类型。

如果长度超过5000个字符,则应该将字段类型定义为 text,并独立出来一张表,用主键对应,避免影响其他字段的索引效率。

 
 
8、字段允许适当冗余,以提高查询性能,但必须考虑数据一致性

 
 
9、单表行数超过 500 万行 或者 单表容量超过 2GB 时,才推荐进行分库分表

 
 
10、当存储的字段为小数时,数据类型设置为 decimal,禁止使用 float 和 double

在存储的时候,float 和 double 存在精度损失的问题,很可能在比较值的时候,得到不正确的结果。

如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。

存储商品价格时,统一转为分,存储类型应为整型 int。

 
 
11、没有特殊要求的情况下,所有的数据表必须使用 Innodb 存储引擎

Innodb 支持事务,支持行级锁,拥有更好的并发性能和恢复性。

 
 
12、数据库和数据表的字符集统一使用 utf8,需要存储 emoji 表情的使用 utf8mb4

 
 
13、所有数据表和字段必须写 comment 注释说明

有条件尽量建立数据字典。

 
 
14、尽量做到冷热数据分离,减小表的宽度

表越宽,把表装进内存缓冲池时所占用的内存也就越大,也会消耗更多的 IO。

 
 
15、禁止在数据表中建立预留字段

预留字段的命名很难做到见名识意,并且无法选择合适的类型,而且对预留字段修改时,会对整张表进行锁定。

 
 
16、禁止在数据库中存储图片、文件等大的二进制数据

文件很大时,IO 将会很耗时,也会占用很多带宽,影响响应速度。

建议图片、视频、大文件统一存储在文件存储空间,比如阿里云、腾讯云的对象存储空间和文件存储空间,数据库中只记录文件地址。

 
 
17、设置合适的字符存储长度

 

对象  年龄区间类型  字节表示范围
人  150岁以内unsigned tinyint1无符号值 0~255
乌龟  数百岁unsigned smallint2无符号值 0~65535
恐龙化石数千万年unsigned int4无符号值 0~约42.9亿
太阳  约50亿年unsigned bigint8无符号值 0~约10^19

 
 


18、条件允许,就将字符串转换成数字类型存储

比如存储ip时,使用 ip2long 和 long2ip

 
 
19、避免使用 enum 类型存储字段

enum 类型的 orderby 操作效率低。

 
 
20、建议把所有列定义为 NOT NULL

索引 null 列需要额外的空间来保存,要占用更多空间。进行比较时和计算时要对 null 值进行特别处理。

 
 
21、禁止在开发环境、测试环境直接连接生产环境数据库


 

 
 二、索引规范

 
1、业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引

唯一索引影响 insert 的速度可以忽略不计,但会明显提高查询速度。

另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然会有脏数据产生。

 
 
2、禁止3个表以上join。需要join的字段,数据类型必须一致,当多表关联时,保证被关联的字段有索引


  
3、限制每张表上的索引数量,尽量不超过5个

索引增加查询效率的同时,也会降低插入和更新的效率,甚至有时会降低查询效率。

mysql优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引进行评估,以生成一个最佳的执行计划。

如果同时有很多个索引都可以用于查询,就会增加mysql优化器生成执行计划的时间,进而降低查询性能。

 
 
4、在 varchar 字段上建立索引时,必须指定索引长度

没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。一般对字符串数据,长度为20的索引,区分度就会高达 90%。

可以使用下列语句来确定区分度。

count(distinct left (列名,索引长度)) / count(*)

 

 
5、页面搜索严禁左模糊或全模糊,如果需要,请使用搜索引擎解决

索引文件具有最左匹配特性,如果左边的值未确定,则无法使用此索引。

 
 
6、如果有order by 的场景,请注意利用索引的有序性

正例:where a=5 and b=10 order by c; #索引 a_b_c 生效反例:where a>10 order by b #索引中有范围查找,索引 a_b 不生效

 
 
7、使用延迟关联或者子查询优化超多分页场景

MySQL 并不是跳过 offset 行,而是取 offset + n 行。

当 offset 特别大时,效率将会非常低,要么控制返回的总页数,要么对超过特定阀值的页数进行 SQL 改写。

正例:先快速定位需要获取的 id 段,然后再关联。

SELECT a.* FROM 表1 a, (select id from 表1 where 条件 LIMIT 100000,20 ) b where a.id=b.id

实例对比:

select a.* from agent_admin a, 
(select agent_admin_id from agent_admin where admin_id = 11400 limit 1000,5
) b 
where a.agent_admin_id=b.agent_admin_id;
0.017sSELECT * from agent_admin where admin_id = 11400 limit 1000,5;
0.023S

 
 
8、建立组合索引时,区分度最高的放在最左边

 
 
9、哪些字段最好建索引

(1)经常出现在 where 从句的字段

(2)包含在 order by,group by、distinct 中的字段

 
 
10、避免建立重复索引和冗余索引

建立冗余索引,ui增加查询优化器生成执行计划的时间

// 重复索引示例
primary key(id)
index(id)
unique key(id)
// 冗余索引示例
index(a,b,c)
index(a,b)
index(a)


 
 
11、创建索引时尽量避免如下误解

(1)宁滥勿缺:认为一个查询就需要建立一个索引

(2)宁缺毋滥:任务索引会消耗空间、严重拖慢更新和新增速度

(3)抵制唯一索引:认为业务的唯一性一律需要在应用层通过“先查后插”的方式解决


 

 
三、SQL 开发规范

 
 
1、不要使用 count(列名) 或 count(常量) 来替代 count(\*)

count(\*) 是 SQL92 定义的标准统计行数的语法,count(\*) 会统计值为NULL的行,而count(列名) 不会统计此列值为 null 的行。

 
2、在代码中写分页查询逻辑时,如果 count 为 0 ,应直接返回结果,避免继续执行后面的程序再返回结果

 
 
3、禁止使用存储过程

存储过程难以调试和扩展,新人接手麻烦,可移植性差。

 
 
4、禁止使用外键与级联,一切外键概念必须在应用层解决

以学生和成绩的关系为例,学生表中的student_id是主键,那么成绩表中的student_id则为外键。如果更新学生表中的 student_id,同时触发成绩表中的student_id更新,即为级联更新。

外键与级联更新适用于单机低并发,不适合分布式、高并发集群;

级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

 
 
5、建议使用预编译语句进行数据库操作

尽量使用框架自带的查询构造器,其底层均封装了预编译处理。如果特殊情况使用不了框架的查询构造器,也要手动预编译查询。

预编译语句可以重复使用优化查询器生成的执行计划,减少 SQL编译 所需要的时间,还可以解决动态 SQL 所带来的的 SQL 注入问题。

 
 
6、避免数据类型的隐式转换

select user_name,age from admin where admin_id = '11140';

 
 
7、禁止使用 select \*,必须指定要查询的具体字段


(1)无法使用覆盖索引

注:覆盖索引的含义是 select 的数据列只从索引中就能够取得,不必读取数据行,换句话说查询列已经被所建的索引覆盖。

(2)消耗更多的 cpu 和 IO 以及网络带宽资源。

 
 
8、避免使用子查询,可以把子查询优化成join查询

子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响。特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大。

注:通常子查询在in子句中,并且子查询中为简单SQL(不包含union、group by、order by、limit从句)时,才可以把子查询转化为关联查询进行优化。

 
 
9、避免使用JOIN关联太多的表

对于Mysql来说,是存在关联缓存的,缓存的大小可以由join_buffer_size参数进行设置。

在 Mysql 中,对于同一个 SQL 多关联一个表,就会多分配一个关联缓存,在一个SQL 中,关联的表越多,所占用的内存就越大。

如果程序中大量的使用了多表关联的操作,同时 join_buffer_size 设置的也不合理的情况下,就容易造成服务器内存溢出的情况,进而影响到服务器数据库性能的稳定性。

MySQL 最多允许关联61个表,建议不超过5个

 
 
10、减少和数据库的交互操作

合并多个相同的操作到一起,可以提高处理效率。比如批量更新时,将语句处理合并后,在提交到 MySQL 中进行处理,这样效率会更高。

一定要避免在循环中执行 SQL。

 
 
11、对同一列进行 or 判断时,使用 in 代替 or

举例:

select user_name,age from admin where city in (1024, 1028);

in 操作可以更有效的利用索引,or 大多数情况下很少能利用到索引。但需要注意的是,in 的值不要超过500个。

 
 
12、禁止在 SQL 语句中进行函数转换和计算

将数据取出来再在程序中进行处理,比如格式化时间和转换ip时。

 
 

13、在明显不会有重复值时使用 UNINON ALL,而不是 UNION

UNION 会把两个结果集的所有数据放到临时表,再进行去重操作

UNINON ALL不会再对结果集进行去重操作

 
 
14、拆分复杂的大 SQL 为多个小 SQL

SQL 拆分后可以通过并行执行来提高处理效率。

 
 
15、大批量操作分批执行

大批量修改数据,会造成表中大量数据行被锁定,从而造成大量的阻塞。

长时间的阻塞会占满数据库所有的可用连接,使生产环境中的其他应用无法连接到数据库。

因此一定要注意大批量写操作一定要分批执行。

 

原文链接:https://www.haveyb.com/article/149

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PaddleOCR在 Linux下的webAPI部署方案

很多小伙伴在使用OCR时都希望能采用API的方式调用,这样就可以跨端跨平台了。本文将介绍一种基于python的PaddleOCR识别WebAPI部署方案。喜欢的可以关注公众号,获取更多内容。一、 Linux环境下部署1.环境要求操作系统:CenterOS7;主…

影响程序员生涯的三个错误观念,你千万不要犯!

程序员在社会上,到底是怎样一个生活群体?是否能找到自己方向?其实,路一直都在那里,只是你看不到而已! 当初的你,可能一直被一些技术牵着鼻子走,并不是自己在做着自己想做的&#xff…

心电图计算心率公式_心电图到底能反应啥问题,看过之后你也能当“医生”

只要是经历过健康体检的健康人,或者做过手术的患者,基本都做过心电图检查。都说久病成医,所以有些人对血、尿常规等各项检查的结果都门清儿得很,最起码看一眼也能说出个大概齐。偏偏心电图这种常做的检查,不但老病号如…

获取正在运行的服务

手机上安装的App,在后台运行着很多不同功能的服务,最常见的例如消息推送相关的服务。如何查看这些服务?如何判断某个服务是否正在运行?如何停止某一个服务呢?请看下面的方法: package com.example.servicel…

openstack的vnc启动ssl

1、制作ssl证书# cd /etc/pki/tls/certs [rootwww certs]# make vnc.key Enter pass phrase:# 输入密码 Verifying - Enter pass phrase:#确认# 从private key 中删除密码# openssl rsa -in vnc.key -out vnc.key # make vnc.csr Country Name (2 letter code) [XX]:CN# 国家 S…

开发composer包

一、初始化&#xff08;生成composer.json文件&#xff09; composer init#输入你要创建的composer包项目命名空间 Package name (<vendor>/<name>) [root/tiny-laravel]: #haveyb/tiny-laravel #输入composer包的描述 Description []:#this is a tiny laravel h…

Linux本地yum源配置以及使用yum源安装gcc编译环境

本文档是图文安装本地yum源的教程&#xff0c;以安装gcc编译环境为例。 适用范围&#xff1a;所有的cetos,红帽,fedroa版本 适用人群&#xff1a;有一点linux基础的小白 范例系统版本&#xff1a;CentOS Linux release 7.3.1611 (Core) 范例环境&#xff1a;vmware 虚拟机 安装…

word如何设置上标形式_如何在word中设置特殊页码

获取更多业界资讯和深度好文● 点击蓝字关注我们 ●在日常工作中&#xff0c;我们编辑的word文档经常需要设置页码&#xff0c;但有时文档的第一页是封面&#xff0c;第二页才是正文&#xff0c;或者第二页是目录&#xff0c;第三页才是正文&#xff0c;如下图所示&#xff0c;…

[cf797c]Minimal string(贪心+模拟)

题意&#xff1a; 给出了字符串s的内容&#xff0c;字符串t&#xff0c;u初始默认为空&#xff0c;允许做两种操作&#xff1a; 1、把s字符串第一个字符转移到t字符串最后 2、把t字符串最后一个字符转移到u字符串最后 最后要求s、t字符串都为空&#xff0c;问u字符串字典序最小…

发布composer包到 Packagist,并设置自动同步(从github到Packagist)

一、发布composer包 1、将我们写好的项目包发布到github上 这一步不赘述&#xff0c;应该都会。 但是需要注意的是&#xff0c;我们一定要为我们的项目包打上tag之后再提交&#xff0c;否则 我们composer require时可能会报错 Could not find a version of package。 # 设置…

教你在CorelDRAW中导入位图

在CorelDRAW软件中不能直接打开位图图像&#xff0c;在实际操作中&#xff0c;用户需要使用导入位图图像的方法进行操作。导入位图图像时&#xff0c;可以导入整幅图像&#xff0c;也可以在导入的过程中对图像进行裁剪&#xff0c;或重新取样图像&#xff0c;导入整幅位图图像时…

.NET 6 中将 ASP.NET Core 注册成 Windows Service

前言使用 Visual Studio 中的 Worker Service项目模板:我们很容易创建出 Windows Service&#xff1a;IHost host Host.CreateDefaultBuilder(args).UseWindowsService().ConfigureServices(services >{services.AddHostedService<Worker>();}).Build();await host.R…

19.12 添加自定义监控项目 配置邮件告警 测试告警

9月12日任务19.12 添加自定义监控项目19.13/19.14 配置邮件告警19.15 测试告警19.16 不发邮件的问题处理19.12 添加自定义监控项目需求&#xff1a;监控某台web的80端口连接数&#xff0c;并出图两步&#xff1a;1&#xff09;zabbix监控中心创建监控项目&#xff1b;2&#xf…

wab框架

http协议 一、http简介 1.HTTP是一个基于TCP/IP通信协议来传递数据&#xff08;HTML 文件, 图片文件, 查询结果等&#xff09;。 2.HTTP是一个属于应用层的面向对象的协议&#xff0c;由于其简捷、快速的方式&#xff0c;适用于分布式超媒体信息系统。它于1990年提出&#xff0…

c++ 二维矩阵 转vector_Python线性代数学习笔记——矩阵的基本运算和基本性质,实现矩阵的基本运算...

当学习完矩阵的定义以后&#xff0c;我们来学习矩阵的基本运算&#xff0c;与基本性质矩阵的基本运算&#xff1a;矩阵的加法&#xff0c;每一个对应元素相加&#xff0c;对应结果的矩阵例子&#xff1a;矩阵A和矩阵B表示的是同学上学期和下学期的课程的成绩&#xff0c;两个矩…

android 4.4以上能够实现的沉浸式状态栏效果

仅仅有android4.4以及以上的版本号才支持状态栏沉浸效果 先把程序执行在4.4下面的手机上,看下效果: 在4.4以上的效果: 当然图片也是能够作为背景的.效果: 代码: if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {Window window getWindow();window.setFlags(Wind…

为abp vnext生成C#客户端给非abp第三方net程序使用

abp vnext提供了动态C#API客户端和静态C#API客户端来调用abp项目的接口&#xff0c;但是有局限性&#xff1b;要使用动态C#API客户端的项目必须也是ABP vnext的项目。静态C#API客户端也依赖abp的包&#xff0c;如下图为的静态客户端依赖于 Volo.Abp.DependencyInjection、Volo.…

项目中引入composer包

假如在云服务器上&#xff0c;项目根目录在 /data/shop&#xff0c;则 示例&#xff1a; cd /data/shop响应的结果可能会有两种: 1、第一种是直接require成功 示例&#xff1a; composer require haveyb/tiny-laravel #响应结果 ./composer.json has been created Loading …

圆的拟合

1.三点求圆心和半径 https://blog.csdn.net/liyuanbhu/article/details/52891868 2.最小二乘拟合圆转载于:https://www.cnblogs.com/yhlx125/p/9671641.html

printf()函数不能直接输出string类型

因为string不是c语言的内置数据&#xff0c;所以直接printf输出string类型的是办不到的。 要这样输出: printf("%s\n",a.c_str()); 举例: #include<bits/stdc.h> using namespace std; int main(){string a"人生";printf("%s\n",a.c_str()…