MySQL索引及优化(3)设计数据库
一、范式和反范式
优秀的库表设计是高性能数据库的基础。如何才能设计出高性能的库表结构呢?这里必须要提到数据库范式。范式是基础规范,反范式是针对性设计。
1.1、范式
范式是设计数据库结构过程中所要遵循的规则和指导方法
其实范式有很多,目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般来说,数据库只需满足第三范式(3NF)就行了。但是一般我们就用到前三个范式
第一范式(确保每列保持原子性)
第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要 用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。 但是如果系统经常会访问“地址”属性中的“城市”部分,那么就
非要将“地址”这个属 性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一 部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式,如下表所 示。
上表所示的用户信息遵循了第一范式的要求,这样在对用户使用城市进行分类的 时候就非常方便,也提高了数据库的性能。
第二范式(确保表中的每列都和主键相关)
第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一 列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。 也就是说在一个数据库表中,一个表中只能保存一种数据,
不可以把多种数据 保存在同一张数据库表中。
比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编 号和商品编号作为数据库表的联合主键。
第三范式(确保每列都和主键列直接相关,而不是间接相关)
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立 相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司 等)的字段。
总结:1NF:无重复的列,属性不可以拆分(强调列的原子性,比如家庭电话和个人电话)
2NF:属性完全依赖于主键
3NF:属性不传递依赖于其他非主属性
1.2、范式的优点缺点
优点:避免数据冗余,减少数据的空间,数据变更速度更快
缺点:范式等级越高,表的数量越多,获取数据时表关联过多,性能较差
1.3、反范式
范式设计的表无法满足性能需求时,需要根据业务场景,在范式的基础上灵活设计
1.业务场景
2.响应时间
3.字段冗余
1.4、反范式和范式的对比
二、基础规范和命名规范
2.1、基础规范
想要发挥 MySQL 的最佳性能,需要遵循 3 个基本使用原则。
1.回归存储的基本职能(MySQL 数据库只用于数据的存储,不进行数据的复杂计算,不承载业务逻辑,确保存储和计算分离)
2.查询时尽量单表查询,减少跨库查询和多表关联
3.杜绝大事务、大SQL、大批量、大字段等性能杀手
大事务:运行步骤较多,涉及的表和字段较多,容易造成资源的争抢,甚至形成死锁。一旦事务回滚,会导致资源占用时间过长。
大 SQL:复杂的 SQL 意味着过多的表的关联,MySQL 数据库处理关联超过 3 张表以上的 SQL 时,占用资源多,性能低下。
大批量:意味着多条 SQL 一次性执行完成,必须确保进行充分的测试,并且在业务低峰时段或者非业务时段执行。
大字段:blob、text 等大字段,尽量少用。必须要用时,尽量与主业务表分离,减少对这类字段的检索和更新。
下面具体讲解数据库的基本设置规则:
- 必须指定默认存储引擎为 InnoDB,并且禁用 MyISAM 存储引擎,随着 MySQL 8.0 版本的发布,所有的数据字典表都已经转换成了 InnoDB,MyISAM 存储引擎已成为了历史。
- 默认字符集 UTF8mb4,以前版本的 UTF8 是 UTF8mb3,未包含个别特殊字符,新版本的 UTF8mb4 包含所有字符,官方强烈建议使用此字符集。
- 关闭区分大小写功能。设置 lower_case_tables_name=1,即可关闭区分大小写功能,即大写字母 T 和小写字母 t 一样。
这里在实践中有个小问题,如何让系统中区分大小写的库表转换为不区分大小写的库表呢?因为要修改底层数据,还是比较麻烦的,操作步骤如下。
MySQL dump 导出数据库。
修改参数 lower_case_tables_name=1。
导入备份数据时,必须停止数据库,停止业务,影响非常大。
开启 per-table 表空间,开启后,每张业务表会单独创建一个独立于系统表空间的表空间,便于空间的回收,数据的迁移。
禁用功能
MySQL 数据库提供的功能很全面,但并不是所有的功能性能都高效。
存储过程、触发器、视图、event。为了存储计算分离,这类功能尽量在程序中实现。这些功能非常不完整,调试、排错、监控都非常困难,相关数据字典也不完善,存在潜在的风险。一般在生产数据库中,禁止使用。
lob、text、enum、set。这些字段类型,在 MySQL 数据库的检索性能不高,很难使用索引进行优化。如果必须使用这些功能,一般采取特殊的结构设计,或者与程序结合使用其他的字段类型替代。比如:set 可以使用整型(0,1,2,3)、注释功能和程序的检查功能集合替代。
2.2、命名规范
- 名称的字符范围为:a-z,0-9和_(下划线)
- 所有表名小写
- 不允许使用-(横杠)、空格
- 不允许其他字符作为名称例如:@&*%¥#等等
库名:1位数据库类型代码+项目简称+识别代码+序号
表名:
字段名:
三、Innodb表要求
- 主键列,UNSIGNED证书,使用auto_increment(这个如果在实际项目中不一定的,大多数不会用自增,因为在分库分表会有问题,会用雪花算法计算id)
- 必须添加comment注解(主要是为了方便他人理解)
- 必须显式指定engine(引擎)
- 表必备三字段:id,xxx_create,xxx_modified(主键id,创建时间,更新时间)
四、字段设计要求
数据值进行参考
- 合理的类型,最短的长度,NotNULL
- 表字段少而精
- 单表个数必须控制在2000个以内
- 单表分表个数必须控制在1024个以内
- 单表字段数上限控制在20-50
总结
- 以高性能为目标,库表设计以范式为主,根据特殊业务场景使用反范式,允许必要的空间换时间。
- 规范数据库的使用原则,统一规范命名,减少性能隐患,减少隐式转换。
- 高性能表设计的原则:合适的字段、合适的长度、NOT NULL。
- 从不同角度思考 IP、timestamp 的转换,拓宽设计思路。
- 规范的命名可提高可读性,反范式设计可提高查询性能。
MySQL索引及优化(3)设计数据库的更多相关文章
- MySQL数据库索引类型、MySQL索引的优化及MySQL索引案例
关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车.对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型 ...
- mysql索引的优化
MySQL索引的优化 上面都在说使用索引的好处,但过多的使用索引将会造成滥用.因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT.UPDATE和DEL ...
- MySQL索引及优化(1)存储引擎和底层数据结构
在昨天的面试中问到了MySQL索引怎么优化(查询很慢怎么办),回答的很不理想,所以今天来总结几篇关于MySQL索引的知识. 1.什么是索引? 首先我们一定要明确什么是索引?我自己的总结就是索引是一种数 ...
- 理解MySQL——索引与优化
转自:理解MySQL——索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存 ...
- 【真·干货】MySQL 索引及优化实战
热烈推荐:超多IT资源,尽在798资源网 声明:本文为转载文章,为防止丢失所以做此备份. 本文来自公众号:GitChat精品课 原文地址:https://mp.weixin.qq.com/s/6V7h ...
- mysql索引与优化
mysql 索引与优化 http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html
- 【索引】理解MySQL——索引与优化
MySQL 索引 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索 ...
- (转)理解MySQL——索引与优化
参考资料:http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html ———————————— 全文: 写在前面:索引对查询的速度有着 ...
- 1020理解MySQL——索引与优化
转自http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性 ...
随机推荐
- 如何优雅的维护 K8S Worker 节点
前言 正常维护工作节点的流程 当我们要进行 K8S 节点维护时往往需要执行 kubectl drain, 等待节点上的 Pod 被驱逐后再进行维护动作. 命令行如下: kubectl drain NO ...
- Python与Excel交互——Xlwings实战
这一期直接来实战. 比如说,我们在一个快递网站上爬取了几个快递的轨迹信息,我们需要将数据保存下来,一个常规做法是把数据保存在数据库里(Mysql,MongoDB,Redis),另一个是用Excel的形 ...
- Linux系统管理第五六七章 权限及归属管理 磁盘管理 文件系统与lvm
第五六七章 alias 查看系统别名 67 chmod 设置文件或目录的权限 -R表示以递归的方式设置目录及目录下的所有子目录及文件的权限 u:属主 g:属组 o:其他人 a:所有人 +:添加 ...
- c语言-----劫持系统03
1. 回顾 在前2节我们已经实现了劫持原理.函数指针等一些概念,下面进行系统劫持 2. 工具 vs2017 Detours 3. windows如何创建一个进程? (1)创建进程函数 CreatePr ...
- 老男孩教育每日一题-2017年3月29日-使用ifconfig取出网卡eth0的ip地址-看看你有多少方法...
方法1:sed命令 [root@oldboyedu ~]# ifconfig eth0 |sed -n '2p' |sed's#^.*addr:##g'|sed 's# B.*$##g' 10.0. ...
- ES6中Fetch的封装及使用,炒鸡简单~
之前写过一篇<ajax.axios.fetch之间的详细区别以及优缺点> 戳这里 1.封装 (http.js) class Ajax { get(url) { return new Pro ...
- 数制转换itoa atoi int转字符串 字符串转int string转int int转string
在苦于昨晚最后一个数制转换题,他的转换结果必须是整形数,纳尼?转换完放数组里又要变成整形数.这是什么操作,而且如果是16进制,用字母A,B-表示,在进行运算时都难以计算. 突发奇想,当十进制成立的时候 ...
- CF--思维练习--CodeForces - 216C - Hiring Staff (思维+模拟)
ACM思维题训练集合 A new Berland businessman Vitaly is going to open a household appliances' store. All he's ...
- CodeForces - 262C 贪心
Maxim always goes to the supermarket on Sundays. Today the supermarket has a special offer of discou ...
- POJ 1330 Nearest Common Ancestors(裸LCA)
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 39596 Accept ...