mysql

一、mysql

1.1 numeric数据类型

整数:tinyint smallint bigint int mediumint
小数:float double decimal(p,s) numeric(p,s)
  • 数据范围
数据类型 所占字节 最小范围有符号 最大范围有符号 最小范围无符号 最大范围无符号
tinyint 1 -128 127 0 255
smallint 2 -32768 32767 0 65535
mediumint 3 -8388608 8388607 0 16777215
int 4 -2147483648 2147483647 0 4294967295
bigint 8 -2^63 2^63-1 0 2^64-1
float 4
double 8
decimal小数值,存储有效数字为m的d位小数 decimal(m,d),m>d时为m+2.否则d+2 依赖于md的值

unsigned //无符号

zerofill //填充0

单精度浮点数最多有7位十进制有效数字,如果某个数的有效数字位数超过7位,当把它定义为单精度变量时,超出的部分会自动四舍五入。

双精度浮点数可以表示十进制的15或16位有效数字,超出的部分也会自动四舍五入。

1.2 字符串类

类型 大小 用途
CHAR 0-255 bytes 定长字符串
VARCHAR 0-65535 bytes 变长字符串
TINYBLOB 0-255 bytes 不超过 255 个字符的二进制字符串
TINYTEXT 0-255 bytes 短文本字符串
BLOB 0-65 535 bytes 二进制形式的长文本数据
TEXT 0-65 535 bytes 长文本数据
MEDIUMBLOB 0-16 777 215 bytes 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215 bytes 中等长度文本数据
LONGBLOB 0-4 294 967 295 bytes 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295 bytes 极大文本数据

注意:char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。

CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。

BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 种 BLOB 类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。

有 4 种 TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际情况选择

UTF-8:一个汉字=3个字节

GBK:一个汉字=2个字节

1.3 日期和时间类型

表示时间值的日期和时间类型为DATETIME、DATE、timestamp(时间戳)、TIME和YEAR。

每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

TIMESTAMP类型有专有的自动更新特性

类型 大小 ( bytes) 范围 格式 用途
DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 ‘-838:59:59’/‘838:59:59’ HH:MM:SS 时间值或持续时间
YEAR 1 1901/2155 YYYY 年份值
DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值
TIMESTAMP 4 1970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 YYYYMMDD HHMMSS 混合日期和时间值,时间戳

​ b4 timestamp default current_timestamp on update now() --自动更新时间。

create table  ttime(
 
	 b1 date,
	 b2 time,
	 b3 datetime,
	 b5 year,
	 b4 timestamp default current_timestamp on update now() --自动更新时间。
);
drop table ttime;
insert into ttime value(now(),current_time,now(),'1998',current_timestamp);
insert into ttime value(now(),current_time,now(),'1998',current_timestamp);

select *from ttime;

1.4 enum和set和布尔类型

create table tenum(

  j1 enum('男','女') default'男',      //最多65535个选项

 j2 set ('开封','西安','洛阳','南京')      //最多64个选项

j3 bit      //0,1

);

insert into tenum  value('男','开封,洛阳','1');


1.5 json数据类型

1.5.1创建json值函数

1.JSON_ARRAY 生成json数组

SELECT JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME()); -- [1, "abc", null, true, "10:37:08.000000"]

2.JSON_OBJECT 生成json对象

-- JSON_OBJECT(key1,val1,key2,val2...)
-- 生成一个包含指定K-V对的json object。如果有key为NULL或参数个数为奇数,则抛错。
SELECT JSON_OBJECT('age', 20, 'time', now()); -- {"age": 20, "time": "2021-06-18 14:49:57.000000"}

3.JSON_QUOTE 加"号

-- JSON_QUOTE(json_val)
-- 将json_val用"号括起来。
SELECT JSON_QUOTE('[1,2,3]'); -- "[1,2,3]" 
1.5.2搜索json值函数

1.JSON_CONTAINS 指定数据是否存在

set @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
-- JSON_CONTAINS(json_doc, val[, path])
-- 查询json文档是否在指定path包含指定的数据,包含则返回1,否则返回0。如果有参数为NULL或path不存在,则返回NULL。
SELECT JSON_CONTAINS(@j, '4', '$.c.d'); -- 1

2.JSON_CONTAINS_PATH 指定路径是否存在

-- JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)
-- 查询是否存在指定路径,存在则返回1,否则返回0。如果有参数为NULL,则返回NULL。
-- one_or_all只能取值"one"或"all",one表示只要有一个存在即可;all表示所有的都存在才行。
SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e'); -- 1
SELECT JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.c.d'); -- 1

3.JSON_EXTRACT 查找所有指定数据

-- JSON_EXTRACT(json_doc, path[, path] ...)
-- 从json文档里抽取数据。如果有参数有NULL或path不存在,则返回NULL。如果抽取出多个path,则返回的数据封闭在一个json array里。
set @j2 = '[10, 20, [30, 40]]';
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]'); -- 20
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]'); -- [20, 10]
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]'); -- [30, 40]

4.JSON_KEYS 查找所有指定键值

-- JSON_KEYS(json_doc[, path])
-- 获取json文档在指定路径下的所有键值,返回一个json array。如果有参数为NULL或path不存在,则返回NULL。
SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}'); -- ["a", "b"]
SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b'); -- ["c"]
SELECT id,json_keys(info) FROM t_json;

5.SON_SEARCH 查找所有指定值的位置

-- JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])
-- 查询包含指定字符串的paths,并作为一个json array返回。如果有参数为NUL或path不存在,则返回NULL。
-- one_or_all:"one"表示查询到一个即返回;"all"表示查询所有。
-- search_str:要查询的字符串。 可以用LIKE里的'%'或‘_’匹配。
-- path:在指定path下查。
SET @j3 = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
SELECT JSON_SEARCH(@j3, 'one', 'abc'); -- "$[0]"
SELECT JSON_SEARCH(@j3, 'all', 'abc'); -- ["$[0]", "$[2].x"]
SELECT JSON_SEARCH(@j3, 'all', 'abc', NULL, '$[2]'); -- "$[2].x"
SELECT JSON_SEARCH(@j3, 'all', '10'); -- "$[1][0].k"
SELECT JSON_SEARCH(@j3, 'all', '%b%'); -- ["$[0]", "$[2].x", "$[3].y"]
SELECT JSON_SEARCH(@j3, 'all', '%b%', NULL, '$[2]'); -- "$[2].x"
1.5.3 修改json值函数

1.JSON_ARRAY_APPEND 指定位置追加数组元素

-- JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)
-- 在指定path的json array尾部追加val。如果指定path是一个json object,则将其封装成一个json array再追加。如果有参数为NULL,则返回NULL。
SET @j4 = '["a", ["b", "c"], "d"]';
-- SELECT JSON_ARRAY_APPEND(@j4, '$[1][0]', 3); -- ["a", [["b", 3], "c"], "d"]
SET @j5 = '{"a": 1, "b": [2, 3], "c": 4}';
SELECT JSON_ARRAY_APPEND(@j5, '$.b', 'x'); -- {"a": 1, "b": [2, 3, "x"], "c": 4} 
SELECT JSON_ARRAY_APPEND(@j5, '$.c', 'y'); -- {"a": 1, "b": [2, 3], "c": [4, "y"]}
SELECT JSON_ARRAY_APPEND(@j5, '$', 'z'); -- [{"a": 1, "b": [2, 3], "c": 4}, "z"]

2.JSON_ARRAY_INSERT 指定位置插入数组元素

-- JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...)
-- 在path指定的json array元素插入val,原位置及以右的元素顺次右移。如果path指定的数据非json array元素,则略过此val;如果指定的元素下标超过json array的长度,则插入尾部。
SET @j6 = '["a", {"b": [1, 2]}, [3, 4]]';
SELECT JSON_ARRAY_INSERT(@j6, '$[1]', 'x'); -- ["a", "x", {"b": [1, 2]}, [3, 4]]
SELECT JSON_ARRAY_INSERT(@j6, '$[100]', 'x'); -- ["a", {"b": [1, 2]}, [3, 4], "x"]
SELECT JSON_ARRAY_INSERT(@j6, '$[1].b[0]', 'x'); -- ["a", {"b": ["x", 1, 2]}, [3, 4]]
SELECT JSON_ARRAY_INSERT(@j6, '$[0]', 'x', '$[3][1]', 'y'); -- ["x", "a", {"b": [1, 2]}, [3, "y", 4]]

3.JSON_INSERT 指定位置插入

-- JSON_INSERT(json_doc, path, val[, path, val] ...)
-- 在指定path下插入数据,如果path已存在,则忽略此val(不存在才插入)。
SET @j7 = '{ "a": 1, "b": [2, 3]}';
SELECT JSON_INSERT(@j7, '$.a', 10, '$.c', '[true, false]'); -- {"a": 1, "b": [2, 3], "c": "[true, false]"}

4.JSON_REPLACE 指定位置替换

-- JSON_REPLACE(json_doc, path, val[, path, val] ...)
-- 替换指定路径的数据,如果某个路径不存在则略过(存在才替换)。如果有参数为NULL,则返回NULL。
SELECT JSON_REPLACE(@j7, '$.a', 10, '$.c', '[true, false]'); -- {"a": 10, "b": [2, 3]}

5.JSON_SET 指定位置设置

-- JSON_SET(json_doc, path, val[, path, val] ...)
-- 设置指定路径的数据(不管是否存在)。如果有参数为NULL,则返回NULL。
SELECT JSON_SET(@j7, '$.a', 10, '$.c', '[true, false]'); -- {"a": 10, "b": [2, 3], "c": "[true, false]"}

6.JSON_MERGE 合并

-- JSON_MERGE(json_doc, json_doc[, json_doc] ...)
-- merge多个json文档。规则如下:
-- 如果都是json array,则结果自动merge为一个json array;
-- 如果都是json object,则结果自动merge为一个json object;
-- 如果有多种类型,则将非json array的元素封装成json array再按照规则一进行mege。
SELECT JSON_MERGE('[1, 2]', '[true, false]'); -- [1, 2, true, false]
SELECT JSON_MERGE('{"name": "x"}', '{"id": 47}'); -- {"id": 47, "name": "x"}
SELECT JSON_MERGE('1', 'true'); -- [1, true]
SELECT JSON_MERGE('[1, 2]', '{"id": 47}'); -- [1, 2, {"id": 47}]

7.JSON_REMOVE 指定位置移除

-- JSON_REMOVE(json_doc, path[, path] ...)
-- 移除指定路径的数据,如果某个路径不存在则略过此路径。如果有参数为NULL,则返回NULL。
SET @j8 = '["a", ["b", "c"], "d"]';
SELECT JSON_REMOVE(@j8, '$[1]'); -- ["a", "d"]

8.JSON_UNQUOTE 去"号

-- JSON_UNQUOTE(val)
-- 去掉val的引号。如果val为NULL,则返回NULL。
SELECT JSON_UNQUOTE("\"123\""); -- 123
1.5.4,返回json值属性的函数

1.JSON_DEPTH 深度

-- JSON_DEPTH(json_doc)
-- 获取json文档的深度。如果参数为NULL,则返回NULL。
-- 空的json array、json object或标量的深度为1。
SELECT JSON_DEPTH('{}'), JSON_DEPTH('[]'), JSON_DEPTH('true'); -- 1 1 1
SELECT JSON_DEPTH('[10, 20]'), JSON_DEPTH('[[], {}]'); -- 2 2
SELECT JSON_DEPTH('[10, {"a": 20}]'); -- 3

2.JSON_LENGTH 长度

-- JSON_LENGTH(json_doc[, path])
-- 获取指定路径下的长度。如果参数为NULL,则返回NULL。 
-- 长度的计算规则:
-- 标量的长度为1;
-- json array的长度为元素的个数;
-- json object的长度为key的个数。
SELECT JSON_LENGTH('[1, 2, {"a": 3}]'); -- 3
SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}'); -- 2
SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b'); -- 1

3.JSON_TYPE 类型

-- JSON_TYPE(json_val)
-- 获取json文档的具体类型。如果参数为NULL,则返回NULL。
select JSON_TYPE('[1,2]'); -- ARRAY

4.JSON_VALID 是否有效json格式

-- JSON_VALID(val)
-- 判断val是否为有效的json格式,是为1,不是为0。如果参数为NUL,则返回NULL。
SELECT JSON_VALID('{"a": 1}'); -- 1
SELECT JSON_VALID('hello'), JSON_VALID('"hello"'); -- 1

附录:

JSON_ARRAY 生成json数组
JSON_OBJECT 生成json对象
JSON_QUOTE 加"号
JSON_CONTAINS 指定数据是否存在
JSON_CONTAINS_PATH 指定路径是否存在
JSON_EXTRACT 查找所有指定数据
JSON_KEYS 查找所有指定键值
JSON_SEARCH 查找所有指定值的位置
JSON_ARRAY_APPEND  指定位置追加数组元素
JSON_ARRAY_INSERT 指定位置插入数组元素
JSON_INSERT 指定位置插入
JSON_REPLACE 指定位置替换
JSON_SET 指定位置设置
JSON_MERGE 合并
JSON_REMOVE 指定位置移除
JSON_UNQUOTE 去"号
JSON_DEPTH 深度
JSON_LENGTH 长度
JSON_TYPE 类型
JSON_VALID 是否有效json格式
函数名 描述
JSON_APPEND()(废弃的5.7.9) JSON文件追加数据
JSON_ARRAY() 创建JSON数组
JSON_ARRAY_APPEND() JSON文件追加数据
JSON_ARRAY_INSERT() 插入JSON数组
-> 在评估路径返回JSON列值;相当于json_extract()。
JSON_CONTAINS() 是否包含特定对象的JSON文档路径
JSON_CONTAINS_PATH() 无论是JSON文件包含任何数据路径
JSON_DEPTH() JSON文档的最大深度
JSON_EXTRACT() 从JSON文档返回数据
->> 在评估路径和结束引语结果返回JSON列值;相当于json_unquote(json_extract())。
JSON_INSERT() 将数据插入到JSON文档
JSON_KEYS() 从JSON文件密钥数组
JSON_LENGTH() 在JSON文档中的元素数
JSON_MERGE()(废弃的5.7.22) 合并的JSON文件,保存重复键。不json_merge_preserve()的同义词
JSON_MERGE_PATCH() 合并的JSON文件,免去重复键的值
JSON_MERGE_PRESERVE() 合并的JSON文件,保存重复键
JSON_OBJECT() 创建JSON对象
JSON_PRETTY() 版画在人类可读的格式JSON文档,每个数组元素或对象成员打印在新的行中,缩进两个空格就其母。
JSON_QUOTE() 引用JSON文档
JSON_REMOVE() 从JSON文件中删除数据
JSON_REPLACE() 在JSON文件的值替换
JSON_SEARCH() 在JSON文件价值路径
JSON_SET() 将数据插入到JSON文档
JSON_STORAGE_SIZE() 用于一个JSON文件的二进制表示形式存储空间;一个JSON柱,空间时使用的文档插入到任何部分更新之前,
JSON_TYPE() JSON值类型
JSON_UNQUOTE() JSON值而言
JSON_VALID() JSON值是否是有效的

mysql官方文档:https://dev.mysql.com/doc/refman/5.7/en/json-utility-functions.html

参考:https://www.cnblogs.com/waterystone/p/5626098.html

create table `json2`(
 `id`      int ,
 `dept`   varchar(255),
 `json_value` json,
 primary key(id)
)engine = innodb charset = utf8;

insert into json2 values(1,'部门1','{"dept":"部门1","deptId":"1","deptleader":"1"}');
insert into json2 values(2,'部门2','{"dept":"部门2","deptId":"2","deptleader":"2"}');
insert into json2 values(3,'部门3','{"dept":"部门3","deptId":"3","deptleader":"3"}');
insert into json2 values(4,'部门4','{"dept":"部门4","deptId":"4","deptleader":"4"}');
insert into json2 values(5,'部门5','{"dept":"部门5","deptId":"5","deptleader":"2"}');
insert into json2 values(6,'部门2','{"dept":"部门7","deptId":"5","deptleader":"2"}');
select * from json2;

select json_extract(json_value,'$.dept') from json2 where json_value ->'$.deptleader'='2' and dept='部门2';
select json_extract(json_value,'$.dept') from json2 order by json_value->"$.dept" desc ;
update json2 set json_value=json_set('{"dept":"部门7","deptId":"5","deptleader":"2"}','$.dept','新增部门','$.deptId','新增id')where id = 6;




1、函数 json_extract():从json中返回想要的字段
用法:json_extract(字段名,$.json字段名)
事例:

select id,json_extract(json_value,'$.deptName') as deptName from dept;
:


2、函数JSON_CONTAINS():JSON格式数据是否在字段中包含特定对象
用法: JSON_CONTAINS(target, candidate[, path])
事例:如果我们想查询包含deptName=部门5的对象

select * from dept WHERE JSON_CONTAINS(json_value, JSON_OBJECT("deptName","部门5"))


3、函数JSON_OBJECT():将一个键值对列表转换成json对象
比如我们想查询某个对象里面的值等于多少

比如我们添加这么一组数据到dept表中:

insert into dept VALUES(6,'部门9','{"deptName": {"dept":"de","depp":"dd"}, "deptId": "5", "deptLeaderId": "5"}');
1
我们可以看到deptName中还有一个对象,里面还有dept和depp两个属性字段,那么我们应该怎么查询depp=dd的员工呢。

用法:JSON_OBJECT([key, val[, key, val] …])
事例:

SELECT * from (
SELECT *,json_value->'$.deptName' as deptName FROM dept
) t WHERE JSON_CONTAINS(deptName,JSON_OBJECT("depp","dd"));
1
2
3
结果:


4、函数JSON_ARRAY():创建JSON数组
比如我们添加这么一组数据到dept表中:

insert into dept VALUES(7,'部门9','{"deptName": ["1","2","3"], "deptId": "5", "deptLeaderId": "5"}');
insert into dept VALUES(7,'部门9','{"deptName": ["5","6","7"], "deptId": "5", "deptLeaderId": "5"}');
1
2
用法:JSON_ARRAY([val[, val] …])

事例:我们要查询deptName包含1的数据

SELECT * from dept WHERE JSON_CONTAINS(json_value->'$.deptName',JSON_ARRAY("1"))
1
结果:


5、函数JSON_TYPE():查询某个json字段属性类型
用法:JSON_TYPE(json_val)
事例:比如我们想查询deptName的字段属性是什么

SELECT json_value->'$.deptName' ,JSON_TYPE(json_value->'$.deptName') as type from dept 

1
2
结果:


我们可以看到deptName对应的字段属性分别是什么

6、函数JSON_EXTRACT() :从JSON文档返回数据
这也是我们开发中会经常用到的一个函数
用法:

事例一:比如我们要查询deptName like ‘部门‘ 的数据
SELECT * FROM dept WHERE JSON_EXTRACT(json_value,'$.deptName') like '%部门%';

1
2
结果:


7、函数JSON_KEYS() :JSON文档中的键数组
用法:JSON_KEYS(json_value)

事例:比如我们想查询json格式数据中的所有key

SELECT JSON_KEYS(json_value) FROM dept 
1
结果:


接下来的3种函数都是新增数据类型的:
JSON_SET(json_doc, path, val[, path, val] …)
JSON_INSERT(json_doc, path, val[, path, val] …)
JSON_REPLACE(json_doc, path, val[, path, val] …)

8、函数JSON_SET() :将数据插入JSON格式中,有key则替换,无key则新增
这也是我们开发过程中经常会用到的一个函数

用法:JSON_SET(json_doc, path, val[, path, val] …)

事例:比如我们想针对id=2的数据新增一组:newData:新增的数据,修改deptName为新增的部门1
sql语句如下:

update dept set json_value=JSON_SET('{"deptName": "部门2", "deptId": "2", "deptLeaderId": "4"}','$.deptName','新增的部门1','$.newData','新增的数据') WHERE id=2;

select * from dept WHERE id =2
1
2
3
结果:

注意:json_doc如果不带这个单元格之前的值,之前的值是会新值被覆盖的,比如我们如果更新的语句换成:

update dept set json_value=JSON_SET('{"a":"1","b":"2"}','$.deptName','新增的部门1','$.newData','新增的数据') WHERE id=2
1
我们可以看到这里json_doc是{“a”:“1”,“b”:“2”},这样的话会把之前的单元格值覆盖后再新增/覆盖这个单元格字段

结果:


9、函数JSON_INSERT():插入值(往json中插入新值,但不替换已经存在的旧值)
用法:JSON_INSERT(json_doc, path, val[, path, val] …)

事例:

UPDATE dept set json_value=JSON_INSERT('{"a": "1", "b": "2"}', '$.deptName', '新增的部门2','$.newData2','新增的数据2') 
WHERE id=2
1
2
结果:

我们可以看到由于json_doc变化将之前的值覆盖了,新增了deptName和newData2.
如果我们再执行以下刚才的那个sql,只是换了value,我们会看到里面的key值不会发生变化。
因为这个函数只负责往json中插入新值,但不替换已经存在的旧值。

10、函数JSON_REPLACE():
用法:JSON_REPLACE(json_doc, path, val[, path, val] …)

用例:
如果我们要更新id=2数据中newData2的值为:更新的数据2

sql语句如下:

UPDATE dept set json_value=JSON_REPLACE('{"a": "1", "b": "2", "deptName": "新增的部门2", "newData2": "新增的数据2"}', '$.newData2', '更新的数据2') WHERE id =2;

select * from dept WHERE id =2
1
2
3
结果:



11、函数JSON_REMOVE() :从JSON文档中删除数据
用法:JSON_REMOVE(json_doc, path[, path] …)

举例:删除key为a的字段。

UPDATE dept set json_value=JSON_REMOVE('{"a": "1", "b": "2", "deptName": "新增的部门2", "newData2": "更新的数据2"}','$.a') WHERE id =2;
1
结果:


12、函数JSON_SEARCH() :用于在json格式中查询并返回符合条件的节点


二、表操作

2.1 generated always生成列

create table tt(
  
  c1 int unsigned primary key auto_increment,
  c2 varchar(19),
  c3 varchar(11) generated always as(str_to_date(mid(c2,'7,'8'),'%Y%m&d'))
)engine = innodb charset = utf8 auto_increment = 20200000 comment = '生日表';
insert into tt(c2) values('410221199803045617');

2.2 修改表 重命名表名 显示建表语句…

as可以作为连接语句的操作符
----修改表
alter table jj1 rename j1;
rename table j1 to jj1;
--查看表详细信息
desc  jj1;
describe jj1;
--查看建表语句
show create table jj1;
--增加一个属性在i1之后
alter table jj1 add jname1 varchar(30) after i1;
--删除一个属性
alter table jj1 drop jname; 
--修改一个属性(字段名)
alter table jj1 rename column jname1 to jname;
--修改一个属性的类型 tinyint换成int
alter table jj1 change jname jname1 date after i2;
alter table jj1 change jname1 jname datetime after i1;
--修改属性及位置
alter table jj1 modify jname date first;
--复制表结构建立一个空表jj11
create table jj11 like jj1;
--复制表结构指定字段
create table j1 as select i1,i2,i3 from j2;

uuid primay key

create table goods(
  id char(36) default (uuid()) primary key,
   jname varchar(50) not null,
    price decimal(10,1)
)engine = innodb charset = utf8;

insert into goods(jname,price) values('笔记本',10000);

–唯一约束

create table tyueshu(
sno char(6) primary key,
    sname varchar(11) not null,
    sphone char(11) unique,
    sage tinyint unsigned defauly 18,
    saddr varchar(255),
    key(sname)
)engine = innodb charset = utf8 auto_increment=20200000;
insert into tyueshu values('202201','李四',13683781337,18,'河南开封');

2.3 外键

create table tearch(
    tid int unsigned not null auto_increment,
		tname varchar(10),
	  primary key(tid)
  

)engine = innodb charset = utf8;
select * from tearch;
drop table tearch;
insert into tearch values(null,'张老师');
insert into tearch values(null,'王老师');
insert into tearch values(null,'刘老师');
insert into tearch values(null,'李老师');

create table student(
    sid int unsigned auto_increment ,
    sname varchar(10) ,
	  stid int unsigned,
	  primary key(sid)
)engine = innodb charset = utf8;
drop table student;
select * from student;
insert into student values(null,'贾同学','2');
insert into student values(null,'贾同学1','1');
insert into student values(null,'贾同学2','3');
insert into student values(null,'贾同学3','4');
insert into student values(null,'贾同学4','2');
insert into student(sid,sname) values(null,'贾同学4');
--查询学生所属老师
select stu.`sid` 学号, stu.`sname` 姓名, ifnull(tc.`tname`,'') 老师 from student stu left join tearch tc on stu.stid = tc.tid;
--增加外键
alter table student add constraint sft foreign key(stid) references tearch(tid) on update cascade on delete cascade;

2.4 CRUD

2.4.1 insert和replace
-- replace基本上和insert一样,
-- 不一样的是:insert 如果指定主键存在或者唯一约束,则报错. replace 则修改
CREATE TABLE stu(
  id int unsigned auto_increment primary key,
  sname varchar(15),
	age tinyint unsigned default 18,
	gender enum('男','女') default '男',
	iphone int unsigned unique,
	address varchar(255) not null
	
)engine = innodb charset = utf8;
select * from stu;
alter table stu modify iphone int(11) unique;
desc stu;
replace into stu values(0,'家属名',22,'男',1368378133,'河南');
--INSERT into stu values(0,'家属名',22,'男',1368378133,'河南');
truncate table stu;

truncate //重置id自增

  load data infile   into table


create table foot(
 id int unsigned  auto_increment primary key,
 name varchar(20) ,
 age int unsigned ,
 adder varchar(255)
)engine = innodb charset = utf8;

--csv文件
load data local infile 'd:\\j.csv'
into table foot
fields terminated by ','
enclosed by '"'
lines terminated by '\r\n'
ignore 1 lines
(id,name,age,adder)

--excel 复制的文件 excel
load data local infile 'D:\\j.txt'
into table foot
fields terminated by '\t'
lines terminated by '\n'
ignore 1 lines 
(id,name,age,adder);

/*文件j.txt
1,jsm,\N,21,河南
2,jsm1,\N,22,洛阳
3,jsm3,\N,23,开封*/
load data local infile 'd:\\j.txt'
into table foot character set utf8 
fields terminated by ','
(id,name,age,adder)


select *from foot;
drop table foot;
 like  between and  is ifnull regexp
 
select  * from student where no ssore between 80 and 90;
select * from student where ssore <80 and ssore >90;
select * from student where sscore between 80 adn 90;
--查找null值
select * from student where stid is null;
--时间范围
set @j = curdate();
set @j = '1998-03-04 9:34:34';
select dete_add(@j,interval -day(@j)+1 day);
select day(@j) +1 day;
--21天前
select ADDDATE(@j,-21);
--字符串转日期
select @j between '1998-02-02' and '1998-05-05';
--模糊查询 like _代表一个字符 %代表0或多个字符
select * from student where like '%$%%' escape '$' --查询含有通配符的
--正则表达式
select '13683781227' regexp '^1[3,5,8]\\d{9}$';
select * from student where sname regexp '[a-z]';--包含英文的
select * from student where sname regexp '\\d'; --包含数字的
select * from student where sname regexp '^[a-z]+$';--全英文
select 8 from student where sname regexp '^[\u4e00]'
select  @j;

in常用于where表达式中,其作用是查询某个范围内的数据。

2.4.2 分组

在数据统计时,GROUP BY 关键字经常和聚合函数一起使用。

聚合函数包括 COUNT(),SUM(),AVG(),MAX() 和 MIN()。其中,COUNT() 用来统计记录的条数;SUM() 用来计算字段值的总和;AVG() 用来计算字段值的平均值;MAX() 用来查询字段的最大值;MIN() 用来查询字段的最小值。

WITH POLLUP 关键字用来在所有记录的最后加上一条记录,这条记录是上面所有记录的总和,即统计记录数量。

--统计由多少个专业
select count(distnct(dept)) from student;
--统计由多少人, 最高分,最低,平均分
select count(1) ,max(score),min(score),avg(score),sum(score) from student;
--分组group by 
select sc.leavel 等级, cout(*) 人数 from 
(
select id,sname,score,if(score>=90,'优秀',if(score>=80,'中等',if(score>60,'及格','补考')))
from ss
) group by ss.leavel;

create table student1 (
id int unsigned primary key auto_increment,
sname varchar(11),
score int unsigned 
)engine = innodb charset = utf8;
insert student1 set sname = 'jsm',score = 80;
insert student1 set sname = 'jsm1',score = 90;
insert student1 set sname = 'jsm2',score = 60;
insert student1 set sname = 'jsm3',score = 40;

select student1.leavel 等级,count(*) 人数 from (
select id, sname,score, if(score>=90,'优秀',if(score>=80,'中等',if(score>=60,'及格','补考'))) leavel  from student1
) student1  group by student1.leavel;
--使用 WITH ROLLUP 显示记录的总和
select score,GROUP_CONCAT(sname) from student1
group by score with rollup;
2.4.3 多表查询
--排号
select row_number() over() 序号, id, sname from student1;
--排名
select rank() over(order by score desc) 序号,id,sname,score from student1;
select dense_rank() over(order by score desc) 名次,id,sname,score from student1 ;

select id, sname,score,
case
when score>=90 then '优秀'
when score>=80 then '及格'
else '补考' end level 
from student1;
 --显示第三名
 select id,sname, score from 
(select rank() over(order by score desc) lev,id,sname,score from student1) sc
where sc.lev = 4;

--多表查询
select * from (select 1,2,3) as t1,(select 3,5,6) as t2;
--笛卡尔积
select *from student1 a,student1 b;
-- inner JOIN 内连接查询等值查询。inner可以省略
select * from  student s  join tearch t on s.stid=t.tid ;
--left join 两张表的等值加上左边剩下的表的字段
select * from  student s left join tearch t on s.stid=t.tid ;
--外连接outer JOIN外连接就是求两个集合的并集。从笛卡尔积的角度讲就是从笛卡尔积中挑出ON子句条件成立的记录,然后加上左表中剩余的记录,最后加上右表中剩余的记录。另外MySQL不支持OUTER JOIN,但是我们可以对左连接和右连接的结果做UNION操作来实现。

三、视图和索引,存储过程

3.1 视图

--视图是查询结果也是一张表
--创建视图
create view v_mu as select * from jsm;
select * from v_mu;
--删除视图
deop view v_mu;
--设置视图访问权限
create user username identified by 'password';
grant select(id,name) on jsm.v_mu to username;
grant select on jsm.v_mu to username;
--查看视图
select `table_name`
from `information_schema`.`tables`
where `table_schema` = 'jsm' and `table_type` = 'view';

3.2 索引

--创建索引
create index indexname on jsm(sname);
--创建唯一索引 意味着两个行不能拥有相同的索引值
create unique index indexname on jsm(sname); 
--以降序索引某个列中的值,您可以在列名称之后添加保留字 DESC
create index indexjsm on jsm(sname desc);
--索引不止一个列,您可以在括号中列出这些列的名称,用逗号隔开:
create index indexjsm on jsm(sname,jname);
--删除索引 MySQL语句
ALTER TABLE table_name DROP INDEX index_name

3.4 存储过程

--创建存储过程
delimiter $
create procedure jsm() 
begin 
 show databases;
 end $
delimiter;
--调用存储过程
call.jsm();

3.5触发器

触发器的特性:

1、有begin end体,begin end;之间的语句可以写的简单或者复杂

2、什么条件会触发:I、D、U

3、什么时候触发:在增删改前或者后

4、触发频率:针对每一行执行

5、触发器定义在表上,附着在表上。

!!尽量少使用触发器,不建议使用。

假设触发器触发每次执行1s,insert table 500条数据,那么就需要触发500次触发器,光是触发器执行的时间就花费了500s,而insert 500条数据一共是1s,那么这个insert的效率就非常低了。因此我们特别需要注意的一点是触发器的begin end;之间的语句的执行效率一定要高,资源消耗要小。

触发器尽量少的使用,因为不管如何,它还是很消耗资源,如果使用的话要谨慎的使用,确定它是非常高效的:触发器是针对每一行的;对增删改非常频繁的表上切记不要使用触发器,因为它会非常消耗资源。

> BEFORE和AFTER参数指定了触发执行的时间,在事件之前或是之后。

> FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器,也就是说触发器的触发频率是针对每一行数据触发一次。

> tigger_event详解:

--简单的说,就是一张表发生了某件事(插入、删除、更新操作),然后自动触发了预先编写好的若干条SQL语句的执行;
--建立触发器 uuid主键
create table t_good(
id char(36) default (uuid()) primary key,
name varchar(100) not null,
price decimal(8,1)
)engine = innodb default charset = utf8 ;
--建立触发器
delimiter $
create trigger t_t1
before 
insert on t_good for each row 
begin 
if new.id is null then
set new.id = uuid();
end if;
.
end $
delimiter;

 insert t_good value(uuid(),'32g',80);
 insert t_good set name = '001' ,price = 110;
 select * from t_good;
--案例
delimiter $
create trigger t_t1 after update on s1 for each row 
BEGIN
if new.score <60 then 
replace into s2 value(new.id,new.name,new.score,new.dept);
else 
delete from s2 where id = new.id;
end if;
end $ 
delimiter;
--在s1表上建立触发器,成绩小于60分的同学会加入到s2表中,修改某一位同学的成绩s2表也会改变。

3.6主从

#mysql.ini
[mysqld]
port=3300
server-id=1
read-only=0
log-bin=mysql-bin
super_read_only=0

#log-bin:同步的日志路径及文件名
#binlog-do-db:要同步的数据库名
#还可以显示 设置不同步的数据库:
#binlog-ignore-db=mysql 不同步mysql库和test库
#binlog-ignore-db=test

#init.bat
start ./bin/mysqld.exe --initialize-insecure
net start 3300


#登录主服务器执行如下命令
mysql>create user repl identified with by mysql_native_password 'repl';
mysql>grant replication slave on *.* to repl;
mysql>flush privileges;

-- 查看主服务器
show master status;
show master status \G

/*From MySQL 8.0.23, use CHANGE REPLICATION SOURCE TO in place of CHANGE MASTER TO, 
which is deprecated from that release. In releases before MySQL 8.0.23, 
use CHANGE MASTER TO.*/
#登录从服务器执行下命令开始
CHANGE REPLICATION SOURCE TO SOURCE_HOST='127.0.0.1',
SOURCE_USER='repl',
SOURCE_PASSWORD='repl',
SOURCE_PORT=3300,
SOURCE_LOG_FILE='',
SOURCE_LOG_POS='';

CHANGE MASTER TO MASTER_HOST='',
MASTER_USER='repl',
MASTER_PASSWORD='repl',
MASTER_PORT=3300,
MASTER_LOG_FILE='',
MASTER_LOG_POS=33

start slave;
show slave status\G

-- 8.0.22以后
start replica;
show replica status \G

停止主从并清除信息

mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> reset slave all;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status;
Empty set (0.00 sec)
mysql> show slave status\G
Empty set (0.00 sec)
mysql>

四、docker

使用官方安装脚本自动安装

--安装
curl -fsSl https://get.docker.com | bash -s docker --mirror Aliyun

--查看docker服务状态
|sudo service --status-all

--也可以使用国内daocloud一键安装命令
curl -sSl https://get.daocloud.io/docker | sh
--卸载旧版本被称为docker,docker.io或docker-engine.
|sudo apt-get remove docker docker-engine docker.io containerd runc

--将当前账号加入docker组
|sudo adduser jsm docker
    
--配置docker镜像加速Ubuntu16.04+、Debian8+、CentOS7对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)
{"registry-mirrors":["https://reg-mirror.qiniu.com/","https://docker.mirrors.ustc.edu.cn/"]}

|sudo service docker restart

--重启服务
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

--查看是否生效加速器
$ docker info
Registry Mirrors:
    https://reg-mirror.qiniu.com

docker安装mysql最新版

--下载mysql
|docker pull mysql

--查看版本信息 系统信息
lsb_release -a

--查看镜像mysql,没有就下载
|docker images

--删除所有镜像
docker rmi $(docker images -aq)

--建立容器contains
docker ps -aq   //查看容器是否有
docker run -itdP -e MYSQL_ROOT_PASSWORD=root mysql //开启一个mysql服务器端口号随机P 小写p为自定义

--停止容器
|docker stop 容器号

--删除容器
|docker rm -f $(docker ps -aq)

--指定mysql端口号以及时区
docker run -itd -p 3300:3306 --name mysql8 -e MYSQL_ROOT_PASSWORD=123456 -e TZ='Asia/Shanghai' mysql

--电脑开机容器会自动启动,一次性容器
|docker run -it --rm mysql:latest mysql -h192.168.21.68 -uroot -P3300 -p123456     //--rm运行完自动删除,d是后台进程
|--restart always

--进入容器里面
|docker exec -it 容器号  

|docker exec -it 49 mysql -hlocalhost -uroot -P3300 -p    //进入容器里面的mysql

--docker拷贝
|docker cp 容器里面的路径 linux路径      //拷贝

五、函数和事件

--自定义函数
delimiter $
create function f_pf(i int)
returns int 
BEGIN

declare t int default 3;
return i*i*t;

END $	
delimiter ;
--调用函数
select f_pf(2);
-- 13683781337 1368****033
delimiter $
create function f_mast(tel char(11))
returns char(11)
BEGIN
  return insert(tel,5,4,'****');
END $
delimiter;
--查看定义了哪些函数
show function status where db='emp';
字符
--length() 字节 char_length() 字符个数 一个汉字三个字节
--转换大小写
select upper('hello'),lower('HELLO');
--比较字符串,区分大小写
select 'a' = 'a','a'='A',binary 'a' = 'A'
--截取字符
select reverse('hello'),left('hello',2),right('java',1),mid('mysql',3,3);
--返回位置
select instr('hello','o');
--插入,在2位置用c替换两个字符
select insert('abc',2,2,'c');
--格式化字符串 format 保留两位小数
select format(rand(),2),format(pi(),2),format(rand(),2);
--找字符返回位置
select FIND_IN_SET('java','php,java');
--密文
select sha('1'),length(sha('1'));  --40
select sha1('1'),length(sha1('1'));  --40
select md5('1'),length(md5('1'));    --32
--分组截取
select substring_index('www.mysql.com.jsm','.',1);
select substring_index('www.mysql.com.jsm','.',-1);
select substring_index('www.mysql.com.jsm','.',-2);
--替换
select replace('www.mysql.com.jsm','.','');
--数字转地址
select inet_ntoa(978559132),inet_aton('192.168.1.1');
--ascii()
select ASCII('贾');                                                                
--elt 返回2位置bb
SELECT elt(2,'aa','bb','cc');

事件

优点

一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能。 可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用了。

缺点

定时触发,不可以调用。

create table j1 (
id bigint ungined primary key,
    ename varchar(30) not null,
    dt  datetime
)engine = memory;

--一分钟开启执行事件
create event e1 on schedule at current_timestamp + interval 1 minute do insert j1 set id = uuid_short(),ename = 'jsm',dt = now();
--一分钟开启事件1秒执行一次
create event e1 on schedule every 1 second start current_timestamp + interval 1 minute do insert j1 set id = uuid_short(),ename = 'jsm',dt  = now();
--10 秒删除一次
create event e1 on schedule every 10 second start current_timestamp do truncate j1;
30分钟开启一次
create table t_login(

     id bigint unsigned , 
     account varchar(36) not null unique,
		 logtime timestamp default current_timestamp on update current_timestamp

)engine = memory;

insert into t_login(id,account) value(uuid_short(),'admin');
insert into t_login(id,account) value(uuid_short(),'root');

select * from t_login;

create event e_login on schedule every 1 second
   do delete from t_login where logtime < adddate(now(),interval -3 second);
	 show variables like '%event_schedulert%';
	 drop event e_login;

六、事务和锁

select @@transaction_isolation,@@version;
select variables like '%transaction_isolation%';
--设置隔离级别 读未提交
set session transcation isolation level read uncommitted;
--加锁 全局读锁
flush tables with read lock;
--解锁 退出服务器会自动解锁
unlock tables;
--表锁
lock tables t_jsm read;
lock tables t_jsm write;

七、权限管理

--查看当前系统所有账号信息
select host,user,plugin,authentication_string from mysql.user;
--建立账号
create user user1;
drop user user1;
--%任意主机都能访问  localhost只有本机可以访问
create user user1@'%' identified with caching_sha2_password by '123';
--修改密码
set password = '123'; --当前用户
set password for user1 = '123'; --指定用户
alter user user1 identified by '123';
--mysql 8 修改加密插件
alter user user1 identified with cachin_sha2_password;
--设置密码过期
create user user1 identified with caching_sha2_password by '123' password expir interval 128 day;
--用户加锁
alter user user1 account lock/unlock;
--使用root账号登陆授权用户d3数据库的管理员
grant all on d3.* to user1;
--查看权限
show grants for testuser;

八、导出

--导出
mysqldump -hlocalhost -p -P3305 db --tables >c:/db.sql;--都要
mysqldump -hlocalhost -p -P3305 db --tables >c:/db.sql -d;--只要结构
mysqldump -hlocalhost -p -P3305 db --tables >c:/db.sql -t;--只要数据

--导入 将本机的3306数据库db导出到本机的3305 数据库中
mysqldump -hlocalhost -u -p -P3306 --default-characher-set=utf8 --databases db | mysql -P3305;xxxxxxxxxx9 1mysqldump -hlosthos--导出2mysqldump -hlocalhost -p -P3305 db --tables >c:/db.sql;--都要3mysqldump -hlocalhost -p -P3305 db --tables >c:/db.sql -d;--只要结构4mysqldump -hlocalhost -p -P3305 db --tables >c:/db.sql -t;--只要数据56--导入 将本机的3306数据库db导出到本机的3305 数据库中7mysqldump -hlocalhost -u -p -P3306 --default-characher-set=utf8 --databases db | mysql -P3305;8t -p -P3305 db --tables > c:/db.sql9mysqldump -hlosthost -u -p -P3306 default-character-set = utf8 --databases db | mysql -P3305; 

你可能感兴趣的:(MySQL,mysql)