【mysql】数据库使用的一些规范

一、MySQL存在的问题

  • 优化器对复杂SQL支持不好
  • 对SQL标准支持不好
  • 大规模集群方案不成熟,主要指中间件
  • ID生成器,全局自增ID
  • 异步逻辑复制,数据安全性问题
  • Online DDL
  • HA方案不完善
  • 备份和恢复方案还是比较复杂,需要依赖外部组件
  • 展现给用户信息过少,排查问题困难
  • 众多分支,让人难以选择

二、数据库环境介绍

通常来讲,各个互联网公司的数据库分为5个数据库环境:

  • dev : 开发环境, 开发可读写,可修改表结构; 常用的163的数据库表; 开发人员可以修改表结构, 可以随意修改其中的数据; 但是需要保证不影响其他开发同事
  • qa : 测试环境, 开发可读写, 开发人员可以通过工具修改表结构
  • sim: 模拟环境, 开发可读写, 通过web平台;发起上线请求时,会先在这个环境上进行预执行, 这个环境也可供部署上线演练或压力测试使用 可以读写
  • real: 生产数据库从库(准实时同步),只读环境,不允许修改数据,不允许修改表结构; 供线上问题查找,数据查询等使用
  • online: 线上环境;开发人员不允许直接在线上环境进行数据库操作,如果需要操作必须找DBA进行操作并进行相应记录

这些环境的机器,一定要做到权限划分明确,读写帐号分离,并且有辨识度,能区分具体业务。例如用户名w_wap, r_wap 能看出来,读写帐号是wap应用的

三、数据库开发规范

开发规范本身也包含几部分:基本命名和约束规范,字段设计规范,索引规范,使用规范等

规范存在意义

  • 保证线上数据库schema规范
  • 减少出问题概率
  • 方便自动化管理
  • 规范需要长期坚持,对开发和DBA是一个双赢的事情

约束规范

  • 表字符集选择UTF8 ,如果需要存储emoj表情,需要使用UTF8mb4(MySQL 5.5.3以后支持)
  • 存储引擎使用InnoDB
  • 变长字符串尽量使用VARCHAR VARBINARY
  • 不在数据库中存储图片、文件
  • 设计表的时候需要添加注释
  • 单表数据量控制在1亿以下,单表物理大小不超过10GB,行平均长度不超过8KB
  • 禁止在线上做数据库压?测试
  • 禁止从测试、开发环境直连数据库
create database test_crm default character set=utf8;

基本命名规范

  • 库名、表名、字段名禁止使用保留字
  • 库名、表名、字段名、索引名使用小写字母,以下划线分割 ,需要见名知意
  • 库名、表名、字段名、索引名不要设计过长,禁止超过32个字符,尽可能用最少的字符表达出表的用途
  • 临时库、临时表名必须以tmp为前缀,并以日期为后缀
  • 备份库、表必须以bak为前缀,并以日期为后缀
  • 库名、表名、字段名、索引名使用名词作为数据库名称,并且只用英文,不用中文拼音
  • 库名使用英文字母,全部小写,控制在3-7个字母以内
  • 库名如果有多个单词,则使用下划线隔开,不建义驼峰命名

分表规范

  • 禁止使用分区表
  • 拆分大字段和访问频率低的字段,分离冷热数据
  • 使用HASH进行散表,表名后缀使用十进制数,下标从0开始
  • 按?期时间分表需符合YYYY[MM][DD][HH]格式
  • 采用合适的分库分表策略

字段规范

  • 所有字段均定义为NOT NULL ,除非你真的想存NULL,但是我想不到需要用Null的情况
  • 字段类型在满足需求条件下越小越好,使用UNSIGNED存储非负整数 ,实际使用时候存储负数场景不多
  • 使用TIMESTAMP存储时间,使用UNSIGNED INT存储IPv4 地址而不是CHAR(15) ,这种方式只能存储IPv4,存储不了IPv6
  • 使用VARCHAR存储变长字符串 ,当然要注意varchar(M)里的M指的是字符数不是字节数;
  • 使用DECIMAL代替FLOAT和DOUBLE存储精确浮点数
  • 尽可能不用BLOB TEXT
  • 使用TINYINT来代替ENUM类型,将字符转化为数字
  • 禁止在数据库中存储明文密码
  • 使用VARBINARY存储大小写敏感的变?字符串

索引规范

  • 单个索引字段数不超过5,单表索引数量不超过5,索引设计遵循B+ Tree索引最左前缀匹配原则
  • 选择区分度高的列作为索引,区分度高的放在前面
  • 对字符串使用前缀索引,前缀索引长度不超过8个字符
  • 建议优先考虑前缀索引,必要时可添加伪列并建立索引
  • 建立的索引能覆盖80%主要的查询,不求全,解决问题的主要矛盾
  • DML和order by和group by字段要建立合适的索引
  • 避免索引的隐式转换
  • 避免冗余索引
  • 关于主键:表必须有主键 ;不使用更新频繁的列 ;不选择字符串列 ;不使用UUID MD5 HASH ;默认使用非空的唯一键 ,建议选择自增或发号器
  • 重要的SQL必须被索引:UPDATE、DELETE语句的WHERE条件列;ORDER BY、GROUP BY、DISTINCT的字段;多表JOIN的字段
  • 核心SQL优先考虑覆盖索引
  • 不在低基数列上建立索引,例如“性别”
  • 不在索引列进行数学运算和函数运算
  • 尽量不使?外键 ,外键用来保护参照完整性,可在业务端实现;对父亲和子表的操作会相互影响,降低可用性 ;INNODB本身对online DDL的限制
  • 不使?%前导的查询,如like “%ab”
  • 不使用负向查询,如not in/like "无法使用索引,导致全表扫描

隐式转换例子,字段定义为varchar,但传入的值是个int,就会导致全表扫描,要求程序端要做好类型检查

字段:remark varchar(50) NOT Null

mysql>SELECT id, gift_code FROM gift WHERE deal_id = 640 AND remark=115127;
1 row in set (0.14 sec)
mysql>SELECT id, gift_code FROM pool_gift WHEREdeal_id = 640 AND remark=‘115127’;
1 row in set (0.005 sec)

SQL类规范

  • 使?预编译语句,只传参数,比传递SQL语句更高效,降低SQL注用概率
  • 充分利用前缀索引
  • 尽量不使用存储过程、触发器、函数等,让数据库做最擅长的事
  • 避免使用大表的JOIN,MySQL优化器对join优化策略过于简单
  • 避免在数据库中进行数学运算和其他大量计算任务
  • SQL合并,主要是指的DML时候多个value合并,减少和数据库交互
  • 合理的分页,尤其大分页
  • UPDATE、DELETE语句不使用LIMIT ,容易造成主从不一致
  • 使用in代替or,in的值不超过1000个
  • 禁止使用order by rand()
  • sql语句避免使用临时表
  • 使用union all而不是union
  • 程序应有捕获SQL异常的处理机制
  • 禁止单条SQL语句同时更新多个表
  • 读取数据时,只选取所需要的列,不要每次都SELECT *,避免产生严重的随机读问题,尤其是读到一些TEXT/BLOB列
  • 通常情况下,子查询的性能比较差,建议改造成JOIN写法
  • 多表联接查询时,关联字段类型尽量一致,并且都要有索引
  • 多表连接查询时,把结果集小的表(注意,这里是指过滤后的结果集,不一定是全表数据量小的)作为驱动表
  • 多表联接并且有排序时,排序字段必须是驱动表里的,否则排序列无法用到索引
  • 多用复合索引,少用多个独立索引,尤其是一些基数(Cardinality)太小(比如说,该列的唯一值总数少于255)的列就不要创建独立索引了
  • 类似分页功能的SQL,建议先用主键关联,然后返回结果集,效率会高很多

四、DBA规范

版本选择

  • MySQL社区版,用户群体最大
  • MySQL企业版,收费
  • Percona Server版,新特性多
  • MariaDB版,国内用户不多

建议选择优先级为:MySQL社区版 > Percona Server > MariaDB > MySQL 企业版

主要内容

  • SQL审核,DDL审核和操作时间,尤其是OnlineDDL
  • 高危操作检查,Drop前做好数据备份
  • 日志分析,主要是指的MySQL慢日志和错误日志
  • 数据备份方案

Online DDL

原生MySQL执行DDL时需要锁表,且锁表期间业务是无法写入数据的,对服务影响很大,MySQL对这方面的支持是比较差的

推荐使用pt-online-schema-change

使用pt-online-schema-change的优点有:

  • 无阻塞写入
  • 完善的条件检测和延时负载策略控制

使用pt-online-schema-change的限制有:

  • 改表时间会比较长(相比直接alter table改表)
  • 修改的表需要有唯一键或主键
  • 在同一端口上的并发修改不能太多

MySQL集群方案

  • 基于主从复制;
  • 基于中间件/proxy
  • 基于NDB引擎
  • 基于Galera协议

优先推荐MHA:可以采用一主多从,或者双主多从的模式,这种模式下,可以采用MHA或MMM来管理整个集群,最新的MHA也已支持MySQL 5.6的GTID模式了

MHA的优势很明显:

  • 开源,用Perl开发,代码结构清晰,二次开发容易;
  • 方案成熟,故障切换时,MHA会做到较严格的判断,尽量减少数据丢失,保证数据一致性;
  • 提供一个通用框架,可根据自己的情况做自定义开发,尤其是判断和切换操作步骤;
  • 支持binlog server,可提高binlog传送效率,进一步减少数据丢失风险。

不过MHA也有些限制:

  • 需要在各个节点间打通ssh信任,这对某些公司安全制度来说是个挑战,因为如果某个节点被黑客攻破的话,其他节点也会跟着遭殃;
  • 自带提供的脚本还需要进一步补充完善,当然了,一般的使用还是够用的。

拆分问题

  • 解决单机写入压力过大和容量问题
  • 有垂直拆分和水平拆分两种方式
  • 拆分要适度,切勿过度拆分
  • 有中间层控制拆分逻辑最好,否则拆分过细管理成本会很高

数据备份

  • 全量备份 VS 增量备份
  • 热备 VS 冷备
  • 物理备份 VS 逻辑备份
  • 延时备份
  • 全量binlog备份

建议方式:

  • 热备+物理备份
  • 核心业务:延时备份+逻辑备份
  • 全量binlog备份

主要做的几点:

  • 备份策略集中式调度管理
  • xtrabackup热备
  • 备份结果统计分析
  • 备份数据一致性校验
  • 采用分布式文件系统存储备份

备份系统采用分布式文件系统原因:

  • 解决存储分配的问题
  • 解决存储NFS备份效率低下问题
  • 存储集中式管理
  • 数据可靠性更好
时间: 2024-10-16 01:17:53

【mysql】数据库使用的一些规范的相关文章

mysql数据库设计开发规范

1.设计 1. 一般都使用INNODB存储引擎,除非读写比率<1%,才考虑使用MYISAM存储引擎:其他存储引擎请在DBA的建议下使用. 2. Stored procedure (包括存储过程,函数,触发器)对于MYSQL来说还不是很成熟,没有完善的出错记录处理,不建议使用. 3. UUID(),USER()这样的MYSQL INSIDE函数对于复制来说是很危险的,会导致主备数据.不一致.所以请不要使用.如果一定要使用UUID作为主键,让应用程序来产生. 4. 请不要使用外键约束,如果数据存在外

MySql数据库规范与原则

1.数据库表名命名规范 采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成; 命名简洁明确,多个单词用下划线'_'分隔; 例如:user_login, user_profile, user_detail, user_role, user_role_relation, user_role_right, user_role_right_relation 表前缀'user_'可以有效的把相同关系的表显示在一起; 2.数据库表字段名命名规范 采用26个英文字母(区分大小写

MySQL 数据库规范--调优篇(终结篇)

前言 这篇是MySQL 数据库规范的最后一篇--调优篇,旨在提供我们发现系统性能变弱.MySQL系统参数调优,SQL脚本出现问题的精准定位与调优方法. 目录 1.MySQL 调优金字塔理论 2.MySQL 慢查询分析--mysqldumpslow.pt_query_digest工具的使用(SQL脚本层面) 3.选择合适的数据类型 4.去除无用的索引--pt_duplicate_key_checker工具的使用(索引层面) 5.反范式化设计(表结构) 6.垂直水平分表 7.MySQL 重要参数调优

MySQL数据库(7)_用户操作与权限管理、视图、存储过程、触发器、基本函数

用户操作与权限管理 MySQL用户操作 创建用户 方法一: CREATE USER语句创建 CREATE USER "用户名"@"IP地址" IDENTIFIED BY "密码"; 方法二: INSERT语句创建 INSERT INTO mysql.user(user,host, password,ssl_cipher,x509_issuer,x509_subject) VALUES('用户名','IP地址',password('密码'),'',

MYSQL数据库设计规范与原则

MYSQL数据库设计规范 1.数据库命名规范 采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成; 命名简洁明确(长度不能超过30个字符); 例如:user, stat, log, 也可以wifi_user, wifi_stat, wifi_log给数据库加个前缀; 除非是备份数据库可以加0-9的自然数:user_db_20151210; 2.数据库表名命名规范 采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成; 命名简洁明确,多

[python] 专题九.Mysql数据库编程基础知识

在Python网络爬虫中,通常是通过TXT纯文本方式存储,其实也是可以存储在数据库中的:同时在WAMP(Windows.Apache.MySQL.PHP或Python)开发网站中,也可以通过Python构建网页的,所以这篇文章主要讲述Python调用MySQL数据库相关编程知识.从以下几个方面进行讲解: 1.配置MySLQ 2.SQL语句基础知识 3.Python操作MySQL基础知识 4.Python调用MySQL示例 一. 配置MySQL 首先下载mysql-5.0.96-winx64,安装

Mysqldb连接Mysql数据库(转)

python操作mysql数据库 Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口. Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库: GadFly mSQL MySQL PostgreSQL Microsoft SQL Server 2000 Informix Interbase Oracle Sybase 你可以访问Python数据库接口及API查看详细的支持数据库列表. 不同的数据库你需要下载

二进制包安装MySQL数据库

1.1二进制包安装MySQL数据库 1.1.1 安装前准备(规范) [[email protected]_server ~]# mkdir -p /home/shangbao_zhangdc/tools  ##创建指定工具包存放路径[[email protected]_server ~]# wget http://ftp.ntu.edu.tw/pub/MySQL/Downloads/MySQL-5.5/mysql-5.5.32-linux2.6-x86_64.tar.gz  ##下二进制包,这个

php中和mysql数据库相关函数

什么是API? 一个应用程序接口(Application Programming Interface的缩写),定义了类,方法,函数,变量等等一切 你的应用程序中为了完成特定任务而需要调用的内容.在PHP应用程序需要和数据库进行交互的时候所需要的API 通常是通过PHP扩展暴露出来(给终端PHP程序员调用). API可以是面向过程的,也可以是面向对象的.对于面向过程的API,我们通过调用函数来完成任务,而对于面向对象的API, 我们实例化类,并在实例化后得到的对象上调用方法.对于这两种接口而言,后

mysql数据库的基本操作

安装(基于centos) yum -y install mariadb mariadb-server # centos7版本 yum -y install mysql mysql-server #centos7以下版本 启动 service mysqld start #开启 centos7以下版本 chkconfig mysqld on #设置开机自启 OR systemctl start mariadb #centos7 systemctl enable mariadb 设置密码 1 mysq