引擎介绍:
InnoDB
用于事务处理应用程序,支持外键和行级锁。如果应用对事物的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包括很多更新和删除操作,那么InnoDB存储引擎是比较合适的。InnoDB除了有效的降低由删除和更新导致的锁定,还可以确保事务的完整提交和回滚,对于类似计费系统或者财务系统等对数据准确要求性比较高的系统都是合适的选择。
MySaim
如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不高,那么可以选择这个存储引擎。
Memory
将所有的数据保存在内存中,在需要快速定位记录和其他类似数据的环境下,可以提供极快的访问。Memory的缺陷是对表的大小有限制,虽然数据库因为异常终止的话数据可以正常恢复,但是一旦数据库关闭,存储在内存中的数据都会丢失。
关于引擎相关的sql语句:
查看当前的默认存储引擎:
mysql> show variables like "default_storage_engine";
查询当前数据库支持的存储引擎
mysql> show engines \G;
需要在建表时指定:
ENGINE=引擎名
引擎在配置文件中指定:
#my.ini文件
[mysqld]
default-storage-engine=INNODB
别名:
- 文件夹【数据库】
- 文件【表】
- 数据行【行】
操作文件夹【数据库】
show databases ;# 查看所有数据库 create database 文件名 [default charset utf8];# 创建数据库#加上default charset utf8 就可以创建包含中文的数据库; drop database 文件名 ;# 删除数据库 use 数据库;# 进入数据库
备份数据库:数据表结构+数据
mysqldump -u 用户名 -p 需要备份的数据库名>导出文件路径.dump (其他后缀也是可以的)
备份数据库:数据表结构
mysqldump -u 用户名 -d -p 需要备份的数据库名>导出文件路径.dump (其他后缀也是可以的)
导入数据库:
mysqldump -u 用户名 -p 导入数据库的文件名<导出文件路径 #导入前需要先创建数据库 或已登录 可以直接用 source 导出文件路径
操作文件【表】
show tables;#查看所有的表; show create table 表名;查看表示如何创建的(以表格的形式显示); \G;将表格显示形式反转; desc 表名;#查看表的信息; 临时表:() as name;#在已有的表中提取一段数据加上括号as name就是一个临时表; select 后可以跟一个动态结果(取得列只有一列)
操作表相关
create table 表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型[(宽度) 约束条件] ) [ENGINE=引擎][DEFAULT CHARSET=utf8]; #注意: 1. 在同一张表中,字段名是不能相同 2. 宽度和约束条件可选 3. 字段名和类型是必须的 4.加入default charset=utf8;创建默认utf-8的表 alter table 表名 auto_increment=num修改(自增初始值) show session variables like 'auto_inc%';#(查看步长 会话级别) set session auto_increment_increment=num;#(修改步长 会话级别) set session auto_increment_offset=num;#(修改起始值 会话级别) show global variables like 'auto_inc%';#(查看步长 全局级别) set global auto_increment_increment=num;#(修改步长 全局级别不推荐使用) set global auto_increment_offset=num;#(修改起始值 全局级别不推荐使用) delete from 表名;#清空表 不会清空约束条件自增 下次插入会延续自增; truncate table 表名;#清空 会清空自增 速度快; drop table 表名;#删除表; 添加列:alter table 表名 add 列名 类型 删除列:alter table 表名 drop column 列名 修改列: alter table 表名 modify column 列名 类型; -- 类型 alter table 表名 change 原列名 新列名 类型; -- 列名,类型 添加主键: alter table 表名 add primary key(列名); 删除主键: alter table 表名 drop primary key; alter table 表名 modify 列名 int, drop primary key; 添加外键: alter table 从表 add constraint 外键名称(形如:FK_从表_主表) foreign key 从表(外键字段) references 主表(主键字段);(从表 被限制的表) 删除外键: alter table 表名 drop foreign key 外键名称 修改默认值: ALTER TABLE 表名 ALTER 列名 SET DEFAULT num; 删除默认值: ALTER TABLE 表名 ALTER列名 DROP DEFAULT;
插入数据
1. 插入完整数据(顺序插入) 语法一: INSERT INTO 表名(字段1,字段2,字段3…字段n) VALUES(值1,值2,值3…值n); 语法二: INSERT INTO 表名 VALUES (值1,值2,值3…值n); 2. 指定字段插入数据 语法: INSERT INTO 表名(字段1,字段2,字段3…) VALUES (值1,值2,值3…); 3. 插入多条记录 语法: INSERT INTO 表名 VALUES (值1,值2,值3…值n), (值1,值2,值3…值n), (值1,值2,值3…值n); 4. 插入其他表的内容 语法: INSERT INTO 表名(字段1,字段2,字段3…字段n) SELECT 字段1,字段2,字段3…字段n FROM 表2 WHERE …;
删除更新数据
delete from 表名 [where 条件];#把满足条件的内容删除 truncate table 表名;#清空 会清空自增 速度快; update 表名 set 需要修改的列名=需要修改的内容 [where 条件] ;#把满足条件的内容修改成需要修改的内容;
查询数据
select *(*代表所有 或者单列的列名)[as 别名][多加额外的列,当列所有数据相同] from 表名[where];#查看表的数据 (*查看所有 ,或者单列出来的相应名称对应的数据 可多选) *select 后可以跟 列名,常量,select的查询结果(结果列唯一)查询结果的条件可以从外层的行数据查找; 单表查询语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数
关键字执行的优先级
from 1.找到表:from; where 2.拿着where指定的约束条件,去文件/表中取出一条条记录; group by 3.将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组; having 4.将分组的结果进行having过滤; select 5.执行select; distinct 6.去重;select distinct 列1, 列2 from 表 # distinct必须在前面 order by 7.将结果按照条件排序 order by limit 8.限制结果的显示条数
where 约束
1. 比较运算符:> < >= <= <> != 2. between num1 and num2 值在num1到num2之间 3. in(num1,num2,num3) 值是num1或num2或num3;in后也可以跟select其他表的内容; 4. like 列名 'egon%' pattern可以是%或_, %表示任意多字符 _表示一个字符 5. 逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not
group by 分组
单独使用GROUP BY关键字分组 SELECT 列名 FROM 表名 GROUP BY 列名; 注意:我们按照列名字段分组,那么select查询的字段只能是列名,想要获取组内的其他相关信息,需要借助函数 GROUP BY关键字和GROUP_CONCAT()函数一起使用; 将group by产生的同一个分组中的值连接起来,返回一个字符串结果。 group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符']) GROUP BY与聚合函数一起使用
聚合函数:
COUNT(name);#计数 MAX(name);#最大值 MIN(name);#最小值 AVG(name);#平均值 SUM(name);#和
HAVING过滤
HAVING与WHERE不一样的地方在于!!!!!! #!!!执行优先级从高到低:where > group by > having #1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。 #2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数
ORDER BY 查询排(可以指定多个列名进行不同的排序,按照先后顺序)
ORDER BY 列名;#按照列名排序 ORDER BY 列名 ASC;#按照类名从小到大排序 ORDER BY 列名 DESC;#按照类名从大到小排序
多表连接查询
#重点:外链接语法 SELECT 字段列表 FROM 表1 INNER|LEFT|RIGHT JOIN 表2 ON 表1.字段 = 表2.字段;(left join 左边的全部显示 right join 右边的全显示 inner 将出现null时的整行隐藏) #上下连表 SELECT 字段列表 FROM 表1 UNION/UNION ALL 表2 ON 表1.字段 = 表2.字段;(union 自动去重 union all 不去重)
LIMIT 限制查询的记录数
LIMIT num;#查询num 条数; LIMIT num1,num2; #从第num1开始,即先查询出第num1+1条,然后包含这一条在内往后查num2条;
约束条件:
为了防止不符合规范的数据进入数据库,在用户对数据进行插入、修改、删除等操作时,DBMS自动按照一定的约束条件对数据进行监测,使不符合规范的数据不能进入数据库,以确保数据库中存储的数据正确、有效、相容。
约束条件与数据类型的宽度一样,都是可选参数,主要分为以下几种:
NOT NULL :非空约束,指定某列不能为空; 是否可空,null表示空,非字符串 not null - 不可空 null - 可空 DEFAULT: 我们约束某一列不为空,如果这一列中经常有重复的内容,就需要我们频繁的插入,这样会给我们的操作带来新的负担,于是就出现了默认值的概念。 默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值 UNIQUE : 唯一约束,指定某列或者几列组合不能重复 PRIMARY KEY :主键,指定该列的值可以唯一地标识该列记录 主键为了保证表中的每一条数据的该字段都是表格中的唯一值。换言之,它是用来独一无二地确认一个表格中的每一行数据。 主键可以包含一个字段或多个字段。当主键包含多个栏位时,称为组合键 (Composite Key),也可以叫联合主键。 主键可以在建置新表格时设定 (运用 CREATE TABLE 语句),或是以改变现有的表格架构方式设定 (运用 ALTER TABLE)。 主键必须唯一,主键值非空;可以是单一字段,也可以是多字段组合。 AUTO_INCREMENT:# 约束字段为自动增长,被约束的字段必须同时被key约束 FOREIGN KEY :外键,指定该行记录从属于主表中的一条记录,主要用于参照完整性,如果主键是多个的时候可以关联多个; foreign key(需要关联的字段名) references 表名(要被关联的字段名)
数据类型:
bit[(M)] 二进制位(101001),m表示二进制位的长度(1-64),默认m=1 tinyint[(m)] [unsigned] [zerofill] 小整数,数据类型用于保存一些范围的整数数值范围: 有符号: -128 ~ 127. 无符号: 0 ~ 255 特别的: MySQL中无布尔值,使用tinyint(1)构造。 int[(m)][unsigned][zerofill] 整数,数据类型用于保存一些范围的整数数值范围: 有符号: -2147483648 ~ 2147483647 无符号: 0 ~ 4294967295 特别的:整数类型中的m仅用于显示,对存储范围无限制。例如: int(5),当插入数据2时,select 时数据显示为: 00002 bigint[(m)][unsigned][zerofill] 大整数,数据类型用于保存一些范围的整数数值范围: 有符号: -9223372036854775808 ~ 9223372036854775807 无符号: 0 ~ 18446744073709551615 decimal[(m[,d])] [unsigned] [zerofill] 准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。 特别的:对于精确数值计算时需要用此类型 decaimal能够存储精确值的原因在于其内部按照字符串存储。 decimal(65,30) 表示35个小数点前30个后 FLOAT[(M,D)] [UNSIGNED] [ZEROFILL] 单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。 无符号: -3.402823466E+38 to -1.175494351E-38, 0 1.175494351E-38 to 3.402823466E+38 有符号: 0 1.175494351E-38 to 3.402823466E+38 **** 数值越大,越不准确 **** DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL] 双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。 无符号: -1.7976931348623157E+308 to -2.2250738585072014E-308 0 2.2250738585072014E-308 to 1.7976931348623157E+308 有符号: 0 2.2250738585072014E-308 to 1.7976931348623157E+308 **** 数值越大,越不准确 **** char (m) char数据类型用于表示固定长度的字符串,可以包含最多达255个字符。其中m代表字符串的长度。 查找快,char列最好放在前面,速度快,因为总是m个字符。 PS: 即使数据小于m长度,也会占用m长度 varchar(m) varchars数据类型用于变长的字符串,可以包含最多达255个字符。其中m代表该数据类型所允许保存的字符串的最大长度,只要长度小于该最大值的字符串都可以被保存在该数据类型中。 注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡 text text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 ? 1)个字符。 mediumtext A TEXT column with a maximum length of 16,777,215 (2**24 ? 1) characters. longtext A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 ? 1) characters. enum 枚举类型, An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.) 示例: CREATE TABLE shirts ( name VARCHAR(40), size ENUM('x-small', 'small', 'medium', 'large', 'x-large') ); INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small'); set 集合类型 A SET column can have a maximum of 64 distinct members. 示例: CREATE TABLE myset (col SET('a', 'b', 'c', 'd')); INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d'); DATE YYYY-MM-DD(1000-01-01/9999-12-31) TIME HH:MM:SS('-838:59:59'/'838:59:59') YEAR YYYY(1901/2155) DATETIME YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 Y) TIMESTAMP YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)
用户管理:
查看用户信息 use mysql; select host,user,password from user; 创建用户: create user '用户名'@'IP' identified by '密码';# 在IP地址可以使用%站位,例如 192.168.1.% 只要是192.168.1的机器都可以登录该用户 或者IP地址为 % 代表所有的机器都可以登录该用户; 删除用户: drop user '用户名'@'IP地址'; 修改用户 rename user '用户名'@'IP地址'; to '新用户名'@'IP地址'; 修改密码 set password for '用户名'@'IP地址' = Password('新密码')
授权管理:
show grants for '用户'@'IP地址' ;# 查看权限 grant 权限 on 数据库/表(*号代表所有 (数据库.*) 该数据库下所有的表) to '用户名'@'IP'(用户) ;#给用户授权 revoke 权限 on 数据库.表 from '用户'@'IP地址';# 取消权限
如果root用户授予权限后无法远程登录 # 远程连接设置哦设置所有库,所有表的所有权限,赋值权限给所有ip地址的root用户 # mysql > grant all privileges on *.* to root@'%' identified by 'password';
权限对应表:
all privileges 除grant外的所有权限 select 仅查权限 select,insert 查和插入权限 ... usage 无访问权限 alter 使用alter table alter routine 使用alter procedure和drop procedure create 使用create table create routine 使用create procedure create temporary tables 使用create temporary tables create user 使用create user、drop user、rename user和revoke all privileges create view 使用create view delete 使用delete drop 使用drop table execute 使用call和存储过程 file 使用select into outfile 和 load data infile grant option 使用grant 和 revoke index 使用index insert 使用insert lock tables 使用lock table process 使用show full processlist select 使用select show databases 使用show databases show view 使用show view update 使用update reload 使用flush shutdown 使用mysqladmin shutdown(关闭MySQL) super 使用change master、kill、logs、purge、master和set global。还允许mysqladmin调试登陆 replication client 服务器位置的访问 replication slave 由复制从属使用
对于权限:
对于目标数据库以及内部其他: 数据库名.* 数据库中的所有 数据库名.表 指定数据库中的某张表 数据库名.存储过程 指定数据库中的存储过程 *.* 所有数据库 用户名@IP地址 用户只能在改IP下才能访问 用户名@192.168.1.% 用户只能在改IP段下才能访问(通配符%表示任意) 用户名@% 用户可以再任意IP下访问(默认IP地址为%) 特殊的: flush privileges,将数据读取到内存中,从而立即生效。
进阶
事物条件
case when 情况条件 then 满足结果 else 不满足结果 end IF( expr1 , expr2 , expr3 ) expr1 的值为 TRUE,则返回值为 expr2 expr1 的值为FALSE,则返回值为 expr3
视图: (临时使用 不常用)
视图是一个虚拟表(非真实存在),其本质是【根据SQL语句获取动态的数据集,并为其命名】,用户使用时只需使用【名称】即可获取结果集,并可以将其当作表来使用。 创建视图: create view 视图名称 as sql语句 删除视图: drop view 视图名称 修改视图: alter view 视图名称 as sql语句 使用视图 select * from 视图名称
触发器:#数据级别做的操作,通过代码也可以实现
delimiter 新符号 #更改';'结尾 遇到新符号结束sql语句; NEW表示即将插入的数据行 OLD表示即将删除的数据行,用在delete和update 创建触发器:(each row 每一次执行都会触发触发器) ***触发器中执行的sql 语句可以使用new/old关键字 new表示即将插入的数据行,old表示即将删除的数据行 在触发器中需要更改delimiter delimiter // # 表示以//为终止符 ...触发器 delimiter ; # 改回以;为终止符 在插入之前 create trigger 触发器名称 befforer insert on 表名 for each row begin 执行语句;#需要delimiter更改';'结尾 end 在插入之后 create trigger 触发器名称 after insert on 表名 for each row begin 执行语句;#需要delimiter更改';'结尾 end 在删除之前 create trigger 触发器名称 befforer delete on 表名 for each row begin 执行语句;#需要delimiter更改';'结尾 end 在删除之后 create trigger 触发器名称 after delete on 表名 for each row begin 执行语句;#需要delimiter更改';'结尾 end 在更新之前 create trigger 触发器名称 befforer update on 表名 for each row begin 执行语句;#需要delimiter更改';'结尾 end 在更新之后 create trigger 触发器名称 after update on 表名 for each row begin 执行语句;#需要delimiter更改';'结尾 end 删除触发器: drop trigger 触发器名称
函数:#会导致sql运行变慢
select 函数();#执行函数
内置函数:
date_format()#格式化时间 与python 格式化时间类似; curdate()#获取当前日期; CHAR_LENGTH(str)#计算字符串的长度; concat(str1,str2...)#字符串拼接; concat_ws(符号,str1,str2...)#(自定义链接字符)字符串拼接; conv(待转换字符,现在的进制,转化后的进制)#进制转换 FORMAT(X,D)#将数字X 的格式写为'#,###,###.##',以四舍五入的方式保留小数点后 D 位, 并将结果以字符串的形式返回。若 D 为 0, 则返回结果不带有小数点,或不含小数部分。 INSERT(str,pos,len,newstr) 在str的指定位置插入字符串 pos:要替换位置起始位置 len:替换的长度 newstr:新字符串 特别的: 如果pos超过原字符串长度,则返回原字符串 如果len超过原字符串长度,则由新字符串完全替换 INSTR(str,substr)#返回字符串 str 中子字符串的第一个出现位置。 LEFT(str,len)#返回字符串str 从开始的len位置的子序列字符。 LOWER(str)#变小写 UPPER(str)#变大写 LTRIM(str)#返回字符串 str ,其引导空格字符被删除。 RTRIM(str)#返回字符串 str ,结尾空格字符被删去。 SUBSTRING(str,pos,len)#获取字符串子序列 LOCATE(substr,str,pos)#获取子序列索引位置 REPEAT(str,count)#返回一个由重复的字符串str 组成的字符串,字符串str的数目等于count 。若 count <= 0,则返回一个空字符串。若str 或 count 为 NULL,则返回 NULL 。 REPLACE(str,from_str,to_str)#返回字符串str 以及所有被字符串to_str替代的字符串from_str 。 REVERSE(str)#返回字符串 str ,顺序和字符顺序相反。 RIGHT(str,len)#从字符串str 开始,返回从后边开始len个字符组成的子序列 SPACE(N)#返回一个由N空格组成的字符串。 now()#现在的时间 函数官方网址: https://dev.mysql.com/doc/refman/5.7/en/functions.html
自定义函数:(有返回值)
delimiter \\ create function 函数名( 参数1 数据类型, 参数2 数据类型) returns 数据类型(#返回的数据类型) BEGIN declare 变量 数据类型;(声明变量为什么数据类型) set 变量 =操作; return(变量); END \\ delimiter ; delimiter \\ create function f1( i1 int, i2 int) returns int BEGIN declare num int; set num = i1 + i2; return(num); END \\ delimiter ; -- 相当于: -- def f1(i1,i2): -- num=i1+i2 -- return(num)
存储过程:
#存储过程是一个SQL语句集合,当主动去调用存储过程时,其中内部的SQL语句会按照逻辑执行 # 可以理解为函数的进阶版,对结果集合返回值进行复杂操作
1.-- 无参数存储过程-- 创建存储过程 delimiter // create procedure 存储过程名() begin 执行的sql语句 end delimiter ; 执行存储过程 call 存储过程名() -- 2.有参数存储过程-- 创建存储过程 对于存储过程,可以接收参数,其参数有三类: in 仅用于传入参数用 out 仅用于返回值用 inout 既可以传入又可以当作返回值 delimiter // create procedure 存储过程名( in/out/onout 参数名 数据类型, in/out/onout 参数名 数据类型, ... ) begin 执行的sql语句 end delimiter ; 执行存储过程 如果参数是 out 或者 inout是需要传变量需要先定义 set @变量名1 = 初始值 set @变量名2 = 初始值 call 存储过程名(num,@变量名1,@变量名2) select @变量名1 @变量名2 (#拿回out和inout的结果) 3.事务 delimiter \\ create PROCEDURE 事务名(OUT 参数名 数据类型) BEGIN DECLARE exit handler for sqlexception#声明如果出现异常执行以下代码 BEGIN 参数名=num; rollback;#关键字 事务回滚 END; START TRANSACTION;#开始事务 数据操作 COMMIT;#提交数据 参数名 = num2; END\\ delimiter ; 补充: 锁 # innodb支持两种锁(行锁,表锁) mysaim只支持表锁 终端: begin # 开始 select .... for update; # for update 加锁 commit # 解锁 pymysql: cursor.execute("sql for update") django: from django.db import transaction#引入事务 with transaction.atomic():#如果以下缩进语句中出现报错则启动事务进行数据回滚操作 model.User.object.all().for_update() 4.游标 delimiter // create procedure 存储过程名()#创建一个存储过程 begin declare 变量名1 数据类型; #声明变量名1 declare 变量名2 数据类型(长度); #声明变量名1 DECLARE 变量名3 INT DEFAULT FALSE;#声明变量名3默认值为false 此变量用户判断循环数据是否为空 DECLARE 游标名称 CURSOR FOR 列名 from 表;#声明游标去表中找列 DECLARE CONTINUE HANDLER FOR NOT FOUND SET 变量名称3 = TRUE;#声明当游标中没有值得时候 变量名称3=true open 游标名称;#打开游标 xxoo(随便写): LOOP#开始循环 fetch 游标名称 into 列名;#从游标中获取列名 if 变量名称3 then #如果变量名称=True 执行结束循环 leave xxoo;#结束循环 END IF; 需要执行的sql语句 end loop xxoo;#终止循环 close 游标名称;#关闭游标 end // delimter ; 执行游标 call 存储过程名() 5.动态执行SQL(防SQL注入) delimiter \\ creater procedure 存储过程名( in 变量名1 数据类型(数据长度) in 变量名2 数据类型(数据长度) ) begin set @变量名2=变量名2; prepare prod from execute prod using @变量名2; deallocate prepare prod; end \\ delimiter ;
索引
#索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可。 -a.额外的文件保存特殊的数据结构 -b.查询快;插入更新删除慢 -c.命中索引(创建索引要正确使用索引) 索引种类:(某种格式存储) hash索引:#不是很常用 查找单值快 查找范围慢——因为hash索引存储是无序的查找范围时会很慢 btree索引: 二叉树 主键索引: # 加速查找,不重复,非空 普通索引:# 加速查找 在创建表时创建: index 索引名(列名) 创建普通索引 create index 索引名 on 表名(列名);#类名(num)可以指定索引的长度 查看索引: show index from 表名; 删除索引: drop index 索引名 on 表名; 唯一索引:#加速查找 不能相同 在创建表时创建: unique 索引名(列名) 创建唯一索引 create unique index 索引名 on 表名(列名); 查看索引: show index from 表名; 删除索引: drop unique index 索引名 on 表名; 联合索引/联合唯一索引:#对于同时搜索n个条件时,组合索引的性能好于多个单一索引合并 创建联合索引/联合唯一索引 create index/unique index 索引名 on 表名(列名1,列名2); 联合索引/联合唯一索引 遵守最左前缀匹配 列名1 and 列名2 --使用索引 列名1 --使用索引 列名2 --不适用索引 查看索引: show index from 表名; 删除联合索引/联合唯一索引: drop index/unique index 索引名 on 表名; 名词解释: 覆盖索引: 在索引文件中直接获取数据 例如:select 数据 from 表 where 带有索引的条件; 索引合并:#索引合并没有组合索引效率高 把多个单列索引合并使用 例如:select * from 表 where 带有索引1的条件,带有索引2的条件; 命中索引:(以下情况会不走索引导致变慢) -like; -使用函数; -or;#特别的:当or条件中有未建立索引的列才失效;#or未建立索引的列and索引的列不会失效; -类型不一致;#如果列是字符串类型,传入条件是必须用引号引起来,否则失效; -!=;#特别的:如果是主键,则还是会走索引; ->;#特别的:如果是主键或索引是整数类型,则还是会走索引; -order by;#当根据索引排序时候,选择的映射如果不是索引,则不走索引;特别的:如果对主键排序,则还是走索引 -最左前缀; 其他注意事项: - 避免使用select * - count(1)或count(列) 代替 count(*) - 创建表时尽量时 char 代替 varchar - 表的字段顺序固定长度的字段优先 - 组合索引代替多个单列索引(经常使用多个条件查询时) - 尽量使用短索引 - 使用连接(JOIN)来代替子查询(Sub-Queries) - 连表时注意条件类型需一致 - 索引散列值(重复少)不适合建索引,例:性别不适合 补充: - 内存代替表,如:性别等 - 读写分离(copy数据库编程两个一模一样的库进行配置同步后进行读写分离减轻压力) - 分库 - 分表 - 水平分表 (例如 onetoone) - 垂直分表 (例如 时间切分) - 命中索引 - 如果取一条数据时,使用limit = 1
执行计划
explain + 查询SQL - 用于显示SQL执行信息参数,根据参考信息可以进行SQL优化; select_type#查询类型 SIMPLE 简单查询 PRIMARY 最外层查询 SUBQUERY 映射为子查询 DERIVED 子查询 UNION 联合 UNION RESULT 使用联合的结果 type#查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const all:#全局扫描,对于数据表头到尾找一遍; #特别的:如果有limit限制,则找到之后就不在继续向下扫描 INDEX:#全索引扫描,对索引从头到尾找一遍; RANGE:#对索引列进行范围查找 INDEX_MERGE:#合并索引,使用多个单列索引搜索 REF:# 根据索引查找一个或多个值 EQ_REF:#连接时使用primary key 或 unique类型 CONST:#常量 SYSTEM :# 系统 possible_keys#可能使用的索引 key#真实使用的索引 key_len#MySQL中使用索引字节长度 rows#mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值 extra#该列包含MySQL解决查询的详细信息 “Using index” 此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。 “Using where” 这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。 “Using temporary” 这意味着mysql在对查询结果排序时会使用一个临时表。 “Using filesort” 这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。 “Range checked for each record(index map: N)” 这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。
慢日志
查看当前配置信息: show variables like '%query%' 修改当前配置:#在内存中更改,立即生效不需要重启 set global 变量名 = 值 配置MySQL自动记录慢日志 slow_query_log = OFF 是否开启慢日志记录 long_query_time = 2 时间限制,超过此时间,则记录 slow_query_log_file = /usr/slow.log 日志文件 log_queries_not_using_indexes = OFF 为使用索引的搜索是否记录 或者创建配置文件:#修改配置文件之后,需要重启服务; mysqld --defauts-file='配置文件路径'#启动服务时找配置文件 配置文件内容: slow_query_log = OFF 是否开启慢日志记录 long_query_time = 2 时间限制,超过此时间,则记录 slow_query_log_file = /usr/slow.log 日志文件 log_queries_not_using_indexes = OFF 为使用索引的搜索是否记录