select @@sql_mode;mysql>select @@sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
ONLY_FULL_GROUP_BY含义:sql中select后面的字段必须出现在group by后面,或者被聚合函数包裹,如下列语句,group by 所有字段,或者group by 主键
select column1, column2 from table group by column1 , column2
STRICT_TRANS_TABLES含义:存储引擎启用严格模式,非法数据值被拒绝。
STRICT_TRANS_TABLES和STRICT_ALL_TABLES,只要把SQL_MODE设置为其中的一个,就被称为严格模式
这两个选项对于Innodb表是相同的作用,对于单个insert操作,无论插入单行或是多行,只要插入数据与字段类型不兼容,则insert操作失败并回滚。
对于Myisam表是不同的作用:我们可以通过SHOW CREATE TABLE 表名;查看表的存储引擎
1.STRICT_TRANS_TABLES,对于单个insert操作,插入单行数据与字段类型不兼容,则insert操作失败并回滚;插入多行数据,如果插入数据的第一行内容与字段类型不兼容,则insert操作失败并回滚,如果插入数据的第一行内容与字段类型兼容,但后续的数据行存在不兼容的情况,则兼容的数据正常插入,不兼容的数据会转换成符合字段类型的格式再插入,不会中断和回滚;
2.STRICT_ALL_TABLES,与STRICT_TRANS_TABLES不同的是,如果插入数据的第一行内容与字段类型兼容,但后续的数据行存在不兼容的情况,则兼容的数据正常插入,不兼容的数据则会报错并终止insert操作。
一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
NO_ZERO_IN_DATE在严格模式,这个模式不接受月和日部分为0的日期。可以接受年为0的日期。
NO_ZERO_DATE这个模式影响着插入的’0000-00-00’值是否作为合法的数值,这个结果和是否启用严格模式有关。如果这个模式禁用,则’0000-00-00’被允许并且插入没有警告,如果这个模式启用,则’0000-00-00’被运行并且插入产生一个警告信息;如果这个模式和严格模式被启用,则’0000-00-00’不被允许并且插入产生错误,除非ignore被使用。NO_ZERO_DATE不是严格模式的一部分,应该和严格模式一起被使用。因为NO_ZERO_DATE将会被放弃在将来的mysql中,它的影响将会被包含进严格模式中。
ERROR_FOR_DIVISION_BY_ZERO如果这个模式未启用,那么零除操作将会插入空值并且不会产生警告;如果这个模式启用,零除操作插入空值并产生警告;如果这个模式和严格模式都启用,零除从操作将会产生一个错误,除非使用来ignore来忽略错误。例如insert ignore和update ignore,这样的话零除操作将插入空并发出警告。ERROR_FOR_DIVISION_BY_ZERO不是严格模式的一部分,应该和严格模式一起启用,默认是启用的。
NO_AUTO_CREATE_USER禁止grant语句自动创建用户,除非认证信息被指定,语句必须包含一个非空的密码使用identified by或使用认证插件identified with.
grant语句可以对用户授权,如果对应的用户不存在,那么mysql将会自动创建对应的用户
NO_ENGINE_SUBSTITUTIOmysql 在create table 时可以指定engine子句;这个engine子句用于指定表的存储引擎,如果把引擎指定成一个并不存在的引擎,在设置了
NO_ENGINE_SUBSTITUTIO的情况下会报错,如果没设置,会将引擎设置为默认引擎
set sql_mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
GRANT privileges ON databasename.tablename TO 'username'@'host';privileges:用户的操作权限,如SELECT,INSERT,UPDATE等,如果要授予所的权限则使用ALL
databasename:数据库名,可用*表示所有数据库
tablename:表名,如果要授予该用户对所有数据库和表的相应操作权限则可用*表示,如*.*
host可指定用户连接的主机,可指定用户通过某个网段的地址连接数据库
grant all privileges on 数据库.* to 用户y@'192.168.%.%';
grant execute on function 数据库名.表名 to 用户@host;
show grants for username@host;
SELECT * FROM mysql.user WHERE user='root';
revoke "要移除的权限" on 数据库.表 from 用户@host

B+树里的每个节点都是一个页,默认的页大小为16KB。非叶子节点存的是索引值以及页的偏移量,而叶子节点上存放的则是完整的每行记录
File Header 文件头部 38 字节 页的一些通用信息
Page Header 页面头部 56 字节 数据页专有的一些信息
Infimum + Supremum 最小记录和最大记录 26 字节 两个虚拟的行记录
User Records 用户记录 大小不确定 实际存储的行记录内容
Free Space 空闲空间 大小不确定 页中尚未使用的空间
Page Directory 页面目录 大小不确定 页中的某些记录的相对位置
File Trailer 文件尾部 8 字节 校验页是否完整
非叶子节点能存放的索引记录
= (页大小 - File Header - Page Header - …) / ( 记录头 + 主键 + 页偏移量)
= (16KB - 128B) / (5B + 4B + 4B)
= 16256 / 13
= 1250 条
叶子节点能存放的数据记录
= (页大小 - File Header - Page Header - …) / ( 主键 + 字段 + 下一条记录的偏移量)
= (16KB - 128B) / (1B + 5B + xB + 6B + 7B)
= 16256 / 19 + x
叶子节点能存放的数据记录
= 16256 / 29
560 条
5.7.26show variables like 'innodb_page_size';。
innodb_page_size,报错,MySQL本身没有提供修改页大小的参数
innodb_page_size =8K ,重启mysql,发现MySQL无法启动
DELIMITER $$
CREATE
PROCEDURE 数据库名.存储过程名(in/out/inout 参数名 参数类型(长度))
BEGIN
存储过程的语句块;
END$$
DELIMITER ;
在命令行定义存储过程时 ,需要用关键字delimiter定义结束符号(默认是;) ,这里改为$$,创建后,将结束符号改回
;
select * from information_schema.routines where routine_schema = '数据库名'; --查看指定数据库的存储过程及状态信息
show create procedure 存储过程名字 ; --查看某个存储过程的定义sql语句
drop procedure [if exists] 存储过程名字;
IN类型:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
OUT类型:该值可在存储过程内部被改变,并可返回
INOUT类型:输入输出参数:调用时指定,并且可被改变和返回
in/out/inout 参数名 参数类型(长度),DECLARE中用来声明变量,变量默认赋值使用的DEFAULT,语句块中改变变量值,使用SET 变量=值;
DELIMITER $$ #定义结束符号为
CREATE
# 接收两个参数,分别是需要统计的name和接收的统计结果repeat_num,name不能被改变设置IN类型,需要返回repeat_num设置为OUT类型
PROCEDURE user.repeat_name(in name vaarchar(50), out repeat_num int)
BEGIN
# 把SQL中查询的结果通过INTO赋给变量
select * count(*) into repeat_num where username = name; # 把SQL中查询的结果通过INTO赋给变量
END$$
DELIMITER ;
call user.repeat_num('pw',@num); # @num表示接收返回结果的repeat_num结果
select @num

# 查看系统变量
show [session|global] variables; --查看所有的系统变量
show [session|global] variables like ‘...’; --可以通过like模糊匹配方式查找变量
select @@[session/global.]系统变量名; --查看指定变了的值,注意可选参数里面的
# 设置系统变量
set [session|global] 系统变量名字 = 值; --不需要@,查询是才需要@
上面这种设置全局变量方法重启后就失效,不想失效就修改参数文件, 然后重启mysql
# 赋值
set @var_name = 值;
set @var_name := 值; --推荐使用这种冒号等于的方式定义
select 字段名 into @var_name from 表名; -- 将查询结果赋值给用户变量
# 查看变量
select @var_name ; --如果使用select 一个不存在的用户变量名会返回null而不会报错
# 声明:
declare 变量名 变量类型(长度) [default 默认值]
# 变量类型就是数据库字段类型:int、bigint、char、varchar、date、time
赋值:
set 变量名 = 值;
set 变量名 := 值;
select 字段名 into 变量名 from 表名;
IF 条件1 THEN
sql语句;
ELSE 条件2 THEN # 可选
sql语句;
ELSE # 可选
sql语句 ;
DELIMITER $$
CREATE
PROCEDURE `demo`.`demo3`(IN `day` INT)
BEGIN
IF `day` = 0 THEN
SELECT '星期天';
ELSEIF `day` = 1 THEN
SELECT '星期一';
ELSEIF `day` = 2 THEN
SELECT '星期二';
ELSE
SELECT '无效日期';
END IF;
END$$
DELIMITER ;
# 语法一
CASE case_value
WHEN when_value1 THEN
sql语句;
WHEN when_value2 THEN
sql语句;
ELSE
sql语句;
END CASE;
DELIMITER $$
CREATE
PROCEDURE demo5(IN num INT)
BEGIN
CASE num -- 条件开始
WHEN 1 THEN
SELECT '输入为1';
WHEN 0 THEN
SELECT '输入为0';
ELSE
SELECT '不是1也不是0';
END CASE; -- 条件结束
END$$
DELIMITER;
CASE
WHEN contidion1 THEN
sql语句;
WHEN condition2 THEN
sql语句;
ELSE
sql语句;
END CASE;
DELIMITER $$
CREATE
PROCEDURE demo4(IN num INT)
BEGIN
CASE -- 条件开始
WHEN num<0 THEN
SELECT '负数';
WHEN num>0 THEN
SELECT '正数';
ELSE
SELECT '不是正数也不是负数';
END CASE; -- 条件结束
END$$
DELIMITER;
WHILE 条件 DO
sql语句;
END WHILE;
REPEAT
sql语句;
UNTIL 条件
END REPEAT;
LEAVE:配合循环使用,退出循环;ITERATE::必须用在循环中,跳出当前循环剩下的语句,直接进入下一次循环[begin_label:] LOOP
SQL逻辑;
END LOOP [end_label];
LEAVE lable; # 退出指定标记的循环体
ITERATE lable; # 直接进入下一次循环
DELIMITER $$
CREATE
PROCEDURE demo8(IN num INT,OUT SUM INT)
BEGIN
SET SUM = 0;
demo_sum:LOOP-- 循环开始
SET num = num+1;
IF num > 10 THEN
LEAVE demo_sum; -- 结束此次循环
ELSEIF num <= 9 THEN
ITERATE demo_sum; -- 跳过此次循环
END IF;
SET SUM = SUM+num;
END LOOP demo_sum; -- 循环结束
END$$
DELIMITER;
触发器特性
什么条件会触发:I、D、U
什么时候会触发:在增删改前或者后
触发频率:针对每一行执行
触发器定义在表上,附着在表上
create trigger 触发器名 before|after 触发事件
on 表名 for each row
执行语句;
create trigger 触发器名 before|after 触发事件
on 表名 for each row
begin
执行语句列表;
end;
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
SHOW TRIGGERS [FROM schema_name];
substr(String string, int start, int length);

# string:为被截取的字符串,start:为起始位置;length:为长度
substring(string, start, length)
# 是一种更加规范的写法,参数含义同上所述,for length可以不写,默认从position开始截取到最后一个字符
substring(string from start for length)

truncate作用是清空表或者说是截断表,只能作用于表,语法如下:truncate tbl_name
delete来删除 MySQL 数据表中的记录,语法如下:DELETE FROM table_name [WHERE Clause]
truncate是DDL语句,执行后无法回滚;delete是DML语句,可回滚。
truncate只能作用于表;delete可作用于表、视图等。
truncate会清空表中的所有行,但表结构及其约束、索引等保持不变;delete只删除 MySQL 数据表中的记录
truncate会重置表的自增值;delete不会
truncate不会激活与表有关的删除触发器;delete可以
truncate后会使表和索引所占用的空间会恢复到初始大小;delete操作不会减少表或索引所占用的空间
concat(str1, str2,...)


[DISTINCT] column1 [ORDER BY column2 ASC\DESC] [SEPARATOR seq])
[ ORDER BY column2 ASC\DESC] :表示将会根据column2升序或者降序连接.其中column2不一定一定要求是column1,只要保证column2在这个分组中即可.如果没有写ORDER BY句段,那么连接是没有顺序的。
[ SEPARATOR seq] : 表示各个column1将会以什么分隔符进行分隔,例如SEPARATOR '’,则表示column1将会以进行分隔。如果没有指定seq的时候,也即没有写SEPARATOR seq这个句段,那么就会默认是以,分隔的。
CONCAT函数中要连接的数据含有NULL,最后返回的是NULL,但是GROUP_CONCAT不会这样,他会忽略NULL值。