图形化客户端
SQLyog是一个图形化的管理MySQL数据库的工具,能够在任何地点管理你的数据库,可以通过网络来维护远端的MySQL数据库,适合DBA
Navicat for MySQL是一个功能强大的MySQL数据库管理和开发工具,适用于开发者
开启远程服务
默认MySQL没有开启远程登陆支持,只能在localhost上使用
首先在localhost上登录数据库
还可以使用授权的方式进行处理 grant
alter user ‘root’@‘localhost’ identified with mysql_native_password by ‘123456’
如果连接过程中报出加密插件验证失败,则可以修改口令所采用的加密方式。在MySQL8中引入了新特性caching_sha2_password。客户端一般支持的都有mysql_native_password这种加密方法
索引是存储引擎用于快速查找记录的一种数据结构,需要额外开辟空间和数据维护工作
mysql -uroot -p123456
use 要使用的数据库名; – 切换当前系统库
update user set host=‘%’ where user=‘root’;
按照物理存储方式:聚簇和非聚簇
MyISAM:frm元数据文件、myd数据、sdi索引数据,MyISAM都是非聚簇索引,数据和索引分别存放
InnoDB:ibd元数据文件、数据和索引,innodb存储引擎支持聚簇索引
按照数据结构:B+树、hash等
按照逻辑:主键索引、普通索引、唯一索引、空间索引(针对空间类型的数据)和全文索引
B树是一种自平衡的多叉查找树,在一个B树种最多可以开m个叉(m>=2)称为m阶B树
就是在B树的基础上添加了顺序访问指针
B+树的查找过程类似B树,只是查找时,如果非叶子节点上的关键字等于给定值时,并不终止,而是继续沿着指针指到叶子节点位置。因此不管在B+树中是否查找成功,每次查找都时走了一条从根到叶子的全路径
所有关键字都存储在叶子节点上,且链表中的关键字恰好是有序的
不可能是非叶子节点命中,所有查询的执行时间稳定
非叶子节点相当于叶子节点的索引,叶子节点相当于存储数据的存储层
非常适合文件索引系统
红黑树也可以实现索引,但是文件系统和数据库系统普遍采用的是B树或者B+树
索引实际上就是关键字和数据的映射关系,关键字是从数据中提取的用于标识、检索数据的特定内容
show create table 表名称;
desc 表名称;
创建索引有2种方式:
创建表的同时建立对应索引,例如主键、唯一性约束
创建表之后建立索引
create table tb_users(
id bigint auto_increment, -- 实际会有报错
first_name varchar(16),
last_name varchar(16),
id_card varchar(18),
memo text,
primary key(id), -- 主键索引
key name1(first_name,last_name),
unique key(id_card),
fulltext key(memo)
);
create table tb_users(
id int auto_increment primary key, -- 建立了主键索引
username varchar(20) unique, -- 建立唯一性索引
memo text
);
alter table tb_users drop column username;
alter table tb_users add first_name varchar(16);
alter table tb_users add last_name varchar(16);
//一个列可以构成索引,索引也可以是由多个列构成
– 建立一个复合索引,并且命名为name1
alter table tb_users add key name1(first_name,last_name);
– 创建全文索引,具体存储采用倒排索引的方式,不支持中文分词。如果业务需要使用搜索引擎,建议使用ES
实现全文搜索
可以根据索引名称执行删除操作,对应的是普通索引、唯一索引、全文索引
语法:alter table 表名称 drop key 索引名称
删除主键索引:alter table 表名 drop primary key,这里没有索引名称,因为一个表只能有一个主键,主键可以是多个列构成。需要注意的是:如果主键自增长,那么不能直接删除。因为auto_increment需要依赖于主键索引
如果需要删除则必须先取消自增长,然后删除主键索引
实际上在具体开发中通常不会删除主键,因为主键有自然主键和代理主键两种,建议的使用的是代理主键,代理主键和业务规则无关。
当执行SQL语句时,首先会分析、优化,形成执行计划,最后按照执行计划执行操作,然会操作结果集。可以通过explain来分析sql执行前的执行计划。
查看查询操作的执行计划
alter table tb_users add fulltext(memo);
alter table tb_users drop key name1; – 删除名称为name1的复合索引
alter table tb_users drop key id_card; – 删除名称为id_card的唯一性索引
alter table tb_users drop key memo;
alter table tb_users modify id bigint;
alter table tb_users drop primary key;
create table tb_users(
id bigint primary key auto_increment,
username varchar(20) unique,
city varchar(10),
province varchar(10),
key name1 (province,city)
)
insert into tb_users values(null,‘zhangsan’,‘西安’,‘陕西’);
explain select * from tb_users where id<10;
id查询操作的唯一标识
select_type显示查询的类型
table显示本次查询相关的表
partitions查询匹配的分区
type显示访问表使用哪种类型,ALL全表查询、index使用索引树、range给定范围查询
possible_keys查询时可能会使用的索引
key使用的索引
key_len索引字段的长度
ref使用索引列等值查询时,和索引列进行等值匹配的对象信息
rows扫描出的行数
filtered按照表条件过滤出的行百分比
Extra执行形况的描述和说明
可以使用查看执行计划判断定义索引是否对特定查询起到优化查询效率的作用
这里表示没有任何索引生效,整表扫描查询数据
1、针对经常需要搜索的列和主键列
explain select * from tb_users where id>1
根据id查询记录,因为id列上创建了主键索引,因此sql语句执行的可选索引possible_keys只有主键索引,如果有多个不同索引,最终会选择一个较好的作为检索的依据
2、order by排序或者范围查询条件的列
执行order by排序操作时,如果该字段没有建立索引,那么执行计划会将查询出的所有数据使用外部排序。操作很影响性能。可以使用 alter table 表名称 add index(列名称) 建立索引,由于索引本身就是有序的,所以直接按照索引顺序逐条读取数据即可。如果还涉及分页操作时,只用获取索引表中某个
范围内的索引对应的数据,而不是获取所有数据
具体开发中做查询必做分页
如果要查询的字段都建立了索引,那么存储引擎会直接在索引表中进行查询,而不会访问原始数据,这个叫做索引覆盖。因此需要尽可能在select后写上必要查询的字段,以增加索引覆盖的几率
在满足所用使用的情况下,例如where、order by、join…on或者索引覆盖,索引也不一定被使用
1、字段要独立出现
select * from tb_users where id=20-1; -- 会使用主键索引
select * from tb_users where id+1=20; -- 不会使用主键索引,针对列使用了表达式计算或者函数
2、like查询
select * from tb_users where name like '%方%'; -- 由于使用%统配符开头,所以在name上
创建的索引无效,只能进行全表扫描,效率极低,实际开发中不建议使用;如果使用较为频繁建议引入第三方
的全文索引来实现
select * from tb_users where name like '方%'; -- name上创建的索引是有效
3、复合索引要求对左边的字段有效,最左前缀匹配原则
具体的实现原理是先按照first_name中提取的关键字进行排序,如果无法确定先后时再按照从last_name中提取的关键排序,索引复合索引生效的前提是左端的列参与的查询
alter table tb_users add index(first_name,last_name);
具体的实现原理是先按照first_name中提取的关键字进行排序,如果无法确定先后时再按照从last_name中提取的关键排序,索引复合索引生效的前提是左端的列参与的查询
select * from tb_users where first_name=’zhangsan‘; -- 可以使用索引
select * from tb_users where first_name='zhang' and last_name='san'; -- 索引生效
select * from tb_users where last_name="lisi"; -- 无法利用索引
从查询条件 first_name=? and last_name=? 来说,针对first_name和last_name创建复合索引的效率
比分别创建first_name索引和last_name索引的查询效率高
4、or条件查询
or两边都有索引时索引生效,一边有一边没有会导致整个sql语句的全表扫描
5、状态值不用索引
取值的可能性较少,例如sex或者订单状态之类的字段,这种字段即使创建索引,也往往利用不上,因为一个状态值可能匹配大量的记录,这种情况下mysql会认为索引比全表扫描的效率低,从而弃用索引。
建立索引是以浪费空间为代价,换取高查询效率。建立索引会对修改操作的性能造成影响
1、建立基础索引:在使用where、order by、join字段上建立索引
2、优化组合索引:基于业务规则和业务逻辑
一般希望索引表应该比具体的数据表要小。当建立索引时默认使用字段的全部内容建立索引,可以指定使用字段的前10个字符建立索引,而不是整个字段内容。语法: index(列名称(长度))
使用前缀索引的前提是:字段的前缀标识度比较高,例如口令比较适合创建前缀索引,因为各个密码几乎都不相同
使用前缀索引的难度就是如何定义前缀截取的长度
可以使用 select count(*)/count(distinct left(password,len)) 进行比较,通过调整len值的大小查看不同前缀的平均匹配度,接近1时就可以了
Innodb存储引擎采用的是索引组织表,在Innodb中表数据文件本身就是按照B+树组织的一个索引结构。MyISAM中主索引和辅助索引在结构上没有任何区别,只是主索引要求key值唯一的,而辅助索引的key值允许重复
在innodb中的数据文件本身就是按照主键聚集存放【聚集索引】,所以要求innodb中的数据表必须有主键,MyISAM可以没有。如果没有显式指定主键,mysql会自动选择一个可以标识的列作为主键,如果不存在可以标识的列,mysql自动为innodb表生成一个隐含字段充当主键,这个字段为6B
辅助索引首先检索辅助索引表获取对应的主键,然后再用主键到主索引表中检索对应的数据
在Innodb中索引不建议使用过长的字段作为主键,因为所有的辅助索引都要使用主索引,过长的主索引会导致辅助索引变大,建议使用整型数据充当主键,占用空间少,比较速度快。另外使用非单调的字段充当主键不是个好主意,因为innodb数据文件本身就是一个B+树,非单调的主键会造成插入新记录时数据文件为了维护B+树的特性而出现频繁的分裂调整,十分低效。最佳实践;可以考虑使用bigint auto_increment的代理主键
MyISAM主索引使用的是 B+树作为索引结构,叶子节点data域中存储的是数据记录的地址
MyISAM辅助索引也是B+树,data域中保存数据记录的地址。
MyISAM索引的检索算法是首先按照B+树的搜索算法查找对应的key,如果key存在,则获取存储在data域中的地址值,最后根据地址值获取对应行的数据,这种叶子节点不存储具体数据的方式叫做非聚集索引
在索引被载入内存中,使用hash结构存储数据
类似HashMap实现