开始mysql学习
环境搭建:centos7+secureCRT+宝塔一键部署mysql
1.1概述
索引是帮助MySQL高效获取数据的数据结构(有序)。数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。如下面的示意图所示 :
一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。索引是数据库中用来提高性能的最常用的工具。
1.2优势劣势
优势
降低数据库的IO成本,降低CPU的消耗。
劣势
1、 实际上索引也是一张表,该表中保存了主键与索引字段,并指向实体类的记录,所以索引列也是要占用空间
的。
2) 虽然索引大大提高了查询效率,同时却也降低更新表的速度,因为更新表时,MySQL 不仅要保存数据,还要保存更新的字段。
1.3索引结构
BTREE 索引 、HASH 索引、R-tree 索引(空间索引)、Full-text (全文索引)
我们平常所说的索引,如果没有特别指明,都是指B+树
BTREE 结构
BTree又叫多路平衡搜索树,一颗m叉的BTree特性如下:
1、树中每个节点最多包含m个孩子。
2、除根节点与叶子节点外,每个节点至少有[ceil(m/2)]个孩子。
3、若根节点不是叶子节点,则至少有两个孩子。
4、所有的叶子节点都在同一层。
5、每个非叶子节点由n个key与n+1个指针组成,其中[ceil(m/2)-1] <= n <= m-1
B+TREE 结构
B+Tree为BTree的变种,B+Tree与BTree的区别为:
1、n叉B+Tree最多含有n个key,而BTree最多含有n-1个key。
2、B+Tree的叶子节点保存所有的key信息,依key大小顺序排列。
3、所有的非叶子节点都可以看作是key的索引部分。
1.4索引分类
1、单值索引 :即一个索引只包含单个列,一个表可以有多个单列索引
2、唯一索引 :索引列的值必须唯一,但允许有空值
3、复合索引 :即一个索引包含多个列
1.5索引设计原则
1、对查询频次较高,且数据量比较大的表建立索引。
2、使用唯一索引,区分度越高,使用索引的效率越高。
3、索引可以有效的提升查询数据的效率,但索引数量不是多多益善,索引越多,维护索引的代价自然也就水涨船高。
视图是一种虚拟存在的表。视图并不在数据库中实际存在。通俗的讲,视图就是一条SELECT语句执行后返回的结果集。
视图相对于普通的表的优势:简单、安全、数据独立。
存储过程和函数是 事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程和函数可以简化很多工作,减少数据在数据库和应用服务器之间的传输,提高数据处理的效率。
存储过程和函数的区别在于函数必须有返回值,而存储过程没有。
函数 : 是一个有返回值的过程 ;
过程 : 是一个没有返回值的函数 ;
触发器是与表有关的数据库对象,指在 insert/update/delete 之前或之后,触发并执行触发器中定义的SQL语句集合。
触发器的这种特性可以协助应用在数据库端确保数据的完整性 , 日志记录 , 数据校验等操作 。
通过SQLyog连接数据库,可以更清晰看清数据库结构和对象集合
java.io.File类:代表文件和目录。 在开发中,读取文件、生成文件、删除文件、修改文件的属性时经常会用到本类。
使用mkdir/mkdirs创建目录
mkdir:目录结构中有一个不存在,则不会创建整个目录树
mkdirs:目录结构中有一个不存在也没关系;创建整个目录树
异常分类
所有异常对象都是派生于Throwable类的一个实例
Throwable下面又派生了两个子类:Error和Exception
Error是程序无法处理的错误,表示运行应用程序中较严重问题。
Exception是程序本身能够处理的异常,通常Java的异常可分为:
RuntimeException 运行时异常
CheckedException 已检查异常
连接层
最上层是一些客户端和链接服务,包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于 TCP/IP的通
信。
主要完成一些类似于连接处理、授权认证、及相关的安全方案。
服务层
第二层架构主要完成大多数的核心服务功能,如SQL接口,并完成缓存的查询,SQL的分析和优化,部分内置函数的执行。
引擎层
存储引擎层, 存储引擎真正的负责了MySQL中数据的存储和提取,服务器通过API和存储引擎进行通信。
存储层
数据存储层, 主要是将数据存储在文件系统之上,并完成与存储引擎的交互。
存储引擎就是存储数据,建立索引,更新查询数据等等技术的实现方式 。存储引擎是基于表的,而不是基于库的。所以存储引擎也可被称为表类型。
Oracle,SqlServer等数据库只有一种存储引擎。MySQL提供了插件式的存储引擎架构。所以MySQL存在多种存储引擎,可以根据需要使用相应引擎,或者编写存储引擎。
MySQL5.0支持的存储引擎包含 : InnoDB 、MyISAM 、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中InnoDB和BDB提供事务安全表,其他存储引擎是非事务安全表。
各个存储引擎之间的区别:
☆InnoDB
InnoDB存储引擎是Mysql的默认存储引擎。InnoDB存储引擎提供了具有提交、回滚、崩溃恢复能力的事务安全。
但是对比MyISAM的存储引擎,InnoDB写的处理效率差一些,并且会占用更多的磁盘空间以保留数据和索引。
InnoDB存储引擎不同于其他存储引擎的特点 :
事务控制
一系列要执行的操作称为事务,而事务控制就是管理这些操作要么完全执行,要么完全不执行。
外键约束
一张表的一个字段受限于另外一张表的一个字段对应的值。
它们的关系:主从表关系
存储方式
1、共享表空间存储, 这种方式创建的表的表结构保存在.frm文件中, 数据和索引保存在
innodb_data_home_dir 和 innodb_data_file_path定义的表空间中,可以是多个文件。
2、多表空间存储, 这种方式创建的表的表结构仍然存在 .frm 文件中,但是每个表的数据和索引单独保存在
.ibd 中。
☆MyISAM
MyISAM 不支持事务、也不支持外键,其优势是访问的速度快,对事务的完整性没有要求或者以SELECT、INSERT为主的应用基本上都可以使用这个引擎来创建表 。
存储方式
每个MyISAM在磁盘上存储成3个文件,其文件名都和表名相同,但拓展名分别是 :
.frm (存储表定义);
.MYD(MYData , 存储数据);
.MYI(MYIndex , 存储索引);
MEMORY
Memory存储引擎将表的数据存放在内存中。
每个MEMORY表实际对应一个磁盘文件,格式是.frm ,该文件中只存储表的结构,而其数据文件,都是存储在内存中,这样有利于数据的快速处理,提高整个表的效率。
MEMORY类型的表访问非常地快,因为他的数据是存放在内存中的,并且默认使用HASH索引 , 但是服务一旦关闭,表中的数据就会丢失。
MERGE
MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构完全相同,MERGE表本身并没有存储数据,对
MERGE类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行的。
InnoDB : 是Mysql的默认存储引擎,用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询意外,还包含很多的更新、删除操作,那么InnoDB存储引擎是比较合适的选择。InnoDB存储引擎除了有效的降低由于删除和更新导致的锁定, 还可以确保事务的完整提交和回滚,对于类似于计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB是最合适的选择。
MyISAM : 如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。
MEMORY:将所有数据保存在RAM中,在需要快速定位记录和其他类似数据环境下,可以提供几块的访问。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。MEMORY表通常用于更新不太频繁的小表,用以快速得到访问结果。
MERGE:用于将一系列等同的MyISAM表以逻辑方式组合在一起,并作为一个对象引用他们。MERGE表的优点在于可以突破对单个MyISAM表的大小限制,并且通过将不同的表分布在多个磁盘上,可以有效的改善。MERGE表的访问效率。这对于存储诸如数据仓储等VLDB环境十分合适。
MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信息。
show[session|global] status 可以根据需要加上参数“session”或者“global”来显示 session 级(当前连接)的计结果和global 级(自数据库上次启动至今)的统计结果。如果不写,默认使用参数是“session”。
show status like ‘Com_______’;
show status like ‘Innodb_rows_%’;
show processlist
可以使用show processlist命令查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化。
1) id列,用户登录mysql时,系统分配的"connection_id",可以使用函数connection_id()查看
2) user列,显示当前用户。如果不是root,这个命令就只显示用户权限范围的sql语句
3) host列,显示这个语句是从哪个ip的哪个端口上发的,可以用来跟踪出现问题语句的用户
4) db列,显示这个进程目前连接的是哪个数据库
5) command列,显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接 (connect)等
6) time列,显示这个状态持续的时间,单位是秒
7) state列,显示使用当前连接的sql语句的状态,很重要的列。state描述的是语句执行中的某一个状态。一 个sql语句,以查询为例,可能需要经过copying to tmp table、sorting result、sending data等状态 才可以完成
8) info列,显示这个sql语句,是判断问题语句的一个重要依据
通过 EXPLAIN或者 DESC命令获取 MySQL如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序。
字段分析:
============================
type 显示的是访问类型,是较为重要的一个指标,可取值为:
一般来说, 我们需要保证查询至少达到 range 级别, 最好达到ref 。
============================
extra:其他的额外的执行计划信息,在该列展示 。
通过 have_profiling 参数,能够看到当前MySQL是否支持profile:
执行show profiles 指令, 来查看SQL语句执行的耗时:
通过show profile for query query_id 语句可以查看到该SQL执行过程中每个线程的状态和消耗的时间:
Sending data 状态表示MySQL线程开始访问数据行并把结果返回给客户端,而不仅仅是返回个客户端。由于 在Sending data状态下,MySQL线程往往需要做大量的磁盘读取操作,所以经常是整各查询中耗时最长的状态。
索引是数据库优化最常用也是最重要的手段之一, 通过索引通常可以帮助用户解决大多数的MySQL的性能优化问题。
1)全值匹配 ,对索引中所有列都指定具体值。索引生效,执行效率高。
explain select * from tb_seller where name=‘小米科技’ and status=‘1’ and address=‘北京 市’\G;
2)最左前缀法则(看不懂)
顾名思义,就是最左优先。指的是查询从索引的最左前列开始,并且不跳过索引中的列。
3)范围查询右边的列,不能使用索引 。
根据前面的两个字段name , status 查询是走索引的, 但是最后一个条件address 没有用到索引。
4)不要在索引列上进行运算操作, 索引将失效。
5)字符串不加单引号,造成索引失效。
6)尽量使用覆盖索引,避免select *。
7)以%开头的Like模糊查询,索引失效。
如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。
8)is NULL , is NOT NULL 有时索引失效。
10) in 走索引, not in 索引失效。
11)单列索引和复合索引。
尽量使用复合索引,而少使用单列索引 。
show status like ‘Handler_read%’;
show global status like ‘Handler_read%’;
当进行数据的insert操作的时候,可以考虑采用以下几种优化方案。
1)如果需要同时对一张表插入很多行数据时,应该尽量使用多个值表的insert语句,这种方式将大大的缩减客户端与数据库之间的连接、关闭等消耗。使得效率比分开执行的单个insert语句快。
原方案:
insert into tb_test values(1,'Tom');
insert into tb_test values(2,'Cat');
insert into tb_test values(3,'Jerry');
优化方案 :
insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');
2)在事务中进行数据插入。
start transaction;
insert into tb_test values(1,'Tom');
insert into tb_test values(2,'Cat');
insert into tb_test values(3,'Jerry');
commit;
3)数据有序插入。
insert into tb_test values(4,'Tim');
insert into tb_test values(1,'Tom');
insert into tb_test values(3,'Jerry');
insert into tb_test values(5,'Rose');
insert into tb_test values(2,'Cat');
优化后:
insert into tb_test values(1,'Tom');
insert into tb_test values(2,'Cat');
insert into tb_test values(3,'Jerry');
insert into tb_test values(4,'Tim');
insert into tb_test values(5,'Rose');
在使用order by时,经常出现Using filesort,因此对于此类sql语句需尽力优化,使其尽量使用Using index。
开始JDBC的学习
1)JDBC直接访问数据库
2)JDO (Java Data Object )技术
3)第三方O/R工具,如Hibernate, Mybatis 等
JDBC是java访问数据库的基石,JDO、Hibernate、MyBatis等只是更好的封装了JDBC。
JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标 准的方法、方便地访问数据库资源。