日常提交

This commit is contained in:
wu xiangkai
2022-10-12 19:40:13 +08:00
parent a12f3c0091
commit 3cf65df785

View File

@@ -1,3 +1,120 @@
- [Mysql Data Type](#mysql-data-type)
- [Mysql数字类型语法](#mysql数字类型语法)
- [整型数据类型](#整型数据类型)
- [非整型数据类型](#非整型数据类型)
- [zerofill](#zerofill)
- [unsigned](#unsigned)
- [serial](#serial)
- [BIT[(M)]](#bitm)
- [TINYINT[(M)] [UNSIGNED] [ZEROFILL]](#tinyintm-unsigned-zerofill)
- [BOOL,BOOLEAN](#boolboolean)
- [SMALLINT[(M)] [UNSIGNED] [ZEROFILL]](#smallintm-unsigned-zerofill)
- [MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]](#mediumintm-unsigned-zerofill)
- [INT[(M)] [UNSIGNED] [ZEROFILL]](#intm-unsigned-zerofill)
- [BIGINT[(M)] [UNSIGNED] [ZEROFILL]](#bigintm-unsigned-zerofill)
- [DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]](#decimalmd-unsigned-zerofill)
- [FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]](#floatmd-unsigned-zerofill)
- [DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]](#doublemd-unsigned-zerofill)
- [DECIMAL和NUMERIC](#decimal和numeric)
- [BIT](#bit)
- [mysql日期和时间类型](#mysql日期和时间类型)
- [日期和时间类型语法](#日期和时间类型语法)
- [date](#date)
- [datetimefsp](#datetimefsp)
- [timestampfsp](#timestampfsp)
- [time(fsp)](#timefsp)
- [YEAR(4)](#year4)
- [mysql中timestamp的存储](#mysql中timestamp的存储)
- [mysql中的时区](#mysql中的时区)
- [time、datetime和timestamp传入无效值时](#timedatetime和timestamp传入无效值时)
- [tmestamp转化为datetime](#tmestamp转化为datetime)
- [mysql中date部分](#mysql中date部分)
- [time类型](#time类型)
- [time类型的缩写](#time类型的缩写)
- [year类型](#year类型)
- [timestamp类型和datetime类型自动初始化和更新](#timestamp类型和datetime类型自动初始化和更新)
- [timestamp或datetime指定小数位精度](#timestamp或datetime指定小数位精度)
- [explicit_defaults_for_timestamp](#explicit_defaults_for_timestamp)
- [时间函数返回带小数位的时间](#时间函数返回带小数位的时间)
- [mysql中时间类型之间的转换](#mysql中时间类型之间的转换)
- [date类型](#date类型)
- [datetime类型和timestamp类型](#datetime类型和timestamp类型)
- [time类型](#time类型-1)
- [时间类型之间的显式转换](#时间类型之间的显式转换)
- [将时间类型转化为数值类型](#将时间类型转化为数值类型)
- [String Data Type](#string-data-type)
- [mysql中String类型的长度单位](#mysql中string类型的长度单位)
- [为字符类型String指定字符集和排序规则](#为字符类型string指定字符集和排序规则)
- [BINARY属性](#binary属性)
- [CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]](#charm-character-set-charset_name-collate-collation_name)
- [VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]](#varcharm-character-set-charset_name-collate-collation_name)
- [BINARY[(M)]](#binarym)
- [VARBINARY(M)](#varbinarym)
- [tinyblob](#tinyblob)
- [tinytext [CHARACTER SET charset_name] [COLLATE collation_name]](#tinytext-character-set-charset_name-collate-collation_name)
- [blob[(M)]](#blobm)
- [text[(M)]](#textm)
- [mediumblob](#mediumblob)
- [mediumtext [CHARACTER SET charset_name] [COLLATE collation_name]](#mediumtext-character-set-charset_name-collate-collation_name)
- [longblob](#longblob)
- [longtext [CHARACTER SET charset_name] [COLLATE collation_name]](#longtext-character-set-charset_name-collate-collation_name)
- [ENUM('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]](#enumvalue1value2-character-set-charset_name-collate-collation_name)
- [SET('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]](#setvalue1value2-character-set-charset_name-collate-collation_name)
- [char和varchar类型](#char和varchar类型)
- [varchar类型的存储](#varchar类型的存储)
- [varchar和char类型的赋值](#varchar和char类型的赋值)
- [在比较varchar类型和char类型时对后缀空格的处理](#在比较varchar类型和char类型时对后缀空格的处理)
- [binary和varbinary类型](#binary和varbinary类型)
- [binary存储值时的逻辑](#binary存储值时的逻辑)
- [varbinary存储时的逻辑](#varbinary存储时的逻辑)
- [blob类型和text类型](#blob类型和text类型)
- [关于text类型作为索引的比较逻辑](#关于text类型作为索引的比较逻辑)
- [blob/text类型与varchar/varbinary类型的区别](#blobtext类型与varcharvarbinary类型的区别)
- [blob类型和text类型的排序](#blob类型和text类型的排序)
- [enum类型](#enum类型)
- [枚举列的创建](#枚举列的创建)
- [枚举类型的值和序号](#枚举类型的值和序号)
- [枚举类型插入invalid值](#枚举类型插入invalid值)
- [枚举值的比较](#枚举值的比较)
- [枚举值的定义](#枚举值的定义)
- [set类型](#set类型)
- [set类型值的存储](#set类型值的存储)
- [set类型的值赋值即错误处理](#set类型的值赋值即错误处理)
- [set类型值中查找某set元素是否存在](#set类型值中查找某set元素是否存在)
- [Json类型](#json类型)
- [对Json值进行部分更新](#对json值进行部分更新)
- [构造Json值](#构造json值)
- [构造Json Array](#构造json-array)
- [构造Json Object](#构造json-object)
- [嵌套Json Object和Json Array](#嵌套json-object和json-array)
- [json值的插入](#json值的插入)
- [json_type函数](#json_type函数)
- [json_array函数](#json_array函数)
- [json_object函数](#json_object函数)
- [json_merge_preserve函数](#json_merge_preserve函数)
- [json_valid函数](#json_valid函数)
- [json值赋值给用户定义的变量中](#json值赋值给用户定义的变量中)
- [通过cast函数将字符串类型转化为json值](#通过cast函数将字符串类型转化为json值)
- [反斜杠转义'和"](#反斜杠转义和)
- [获取json值中属性的值](#获取json值中属性的值)
- [Json值的normalizationmerging和autowarpping](#json值的normalizationmerging和autowarpping)
- [json值的规范化](#json值的规范化)
- [merge json的值](#merge-json的值)
- [合并array](#合并array)
- [合并json object](#合并json-object)
- [autowrapping](#autowrapping)
- [当array和object进行merge](#当array和object进行merge)
- [查找和修改json值](#查找和修改json值)
- [路径表达式](#路径表达式)
- [**通配符样例](#通配符样例)
- [选中array的一个子集](#选中array的一个子集)
- [last的用法](#last的用法)
- [json_set](#json_set)
- [json_insert](#json_insert)
- [json_replace](#json_replace)
- [json_remove](#json_remove)
# Mysql Data Type
## Mysql数字类型语法
### 整型数据类型
@@ -481,5 +598,287 @@ mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
```
## Json类型
Mysql本地支持Json类型允许对Json中的数据进行高效访问。同传统的通过字符串来存储json数据的方式相比通过Json String来存储json数据具有如下优势
- 对存储的Json数据进行自动验证无效的Json数据将会产生异常
- 优化存储格式存储在json列中的json数据将会允许对json数据属性的快速读访问。以二进制格式存储在json列中的json数据如果稍后要对其进行访问该存储的值无需转化为文本表示之后再解析。***二进制结构的值使服务器能够通过key或者数组index来查找子对象或者嵌套值而不需要读取所有位于他们之前或之后的值。***
### 对Json值进行部分更新
在mysql 8.0中优化器可以对Json值执行部分更新而不是移除整个旧Json值然后写入新的Json值。
Json部分更新需要满足如下条件
1. 该部分更新的列需要是Json列
2. 该部分更新的update语句需要使用如下三个函数json_set(),json_replace(),json_remove()来更新Json列。任何对Json列的直接赋值都***不会***使用部分更新
3. 该更新语句的输入列和输出列需要是相同的列如果UPDATE mytable SET jcol1 = JSON_SET(jcol2, '$.a', 100)其中jcol2和jcol1的列不同那么更新jcol1时并不会使用部分更新的特性
> 只要输入列和输出列的值相同可以通过上诉三个函数的嵌套组合来对json列进行部分更新
4. 更新语句只是对现存对象或者array的值进行修改而不会在父对象或者array中加入新值
5. 被替换的旧值只要要和要替换的新值一样大,旧值所占空间大小不能比新值小
> 此需求可能存在例外,如果在为旧值进行部分更新时,留下的空间足够容纳更大的新值,那么在对新值进行部分更新时也不会抛出异常
### 构造Json值
#### 构造Json Array
```sql
["abc", 10, null, true, false]
```
##### 构造Json Object
```sql
{"k1": "value", "k2": 10}
```
#### 嵌套Json Object和Json Array
```sql
[99, {"id": "HK500", "cost": 75.99}, ["hot", "cold"]]
{"k1": "value", "k2": [10, 20]}
```
#### json值的插入
```sql
INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
```
#### json_type函数
该函数接受一个json值并且返回该json值的类型
```sql
# 返回结果Object
select json_type('{"name":"kazusa","age":17}');
# 返回结果Array
select json_type('[{"name":"kazusa","age":17}]');
```
#### json_array函数
json_array函数接受一系列值并且返回json array
```sql
# 返回结果 ["a", 1, "2015-07-27 09:43:47.000000"]
SELECT JSON_ARRAY('a', 1, NOW());
```
#### json_object函数
json_object函数接受一系列的键值对并且返回一个json object对象
```sql
# 返回结果 {"key1": 1, "key2": "abc"}
SELECT JSON_OBJECT('key1', 1, 'key2', 'abc');
```
#### json_merge_preserve函数
json_merge_reserve函数接受两个或更多的json值并且返回一个整合后的结果
```sql
# 返回结果是 ["a", 1, {"key": "value"}]
SELECT JSON_MERGE_PRESERVE('["a", 1]', '{"key": "value"}');
# 返回结果是 {"age": 17, "name": "kazusa", "roles": "painoist", "is_male": false}
select json_merge_preserve('{"name":"kazusa","age":17}','{"roles":"painoist","is_male":false}');
```
#### json_valid函数
json_valid函数接受一个表示json值的字符串并且返回该字符串是否是合规的json值
```sql
# 返回结果为100
select json_valid('null'),json_valid('Null'),json_valid('NULL');
```
#### json值赋值给用户定义的变量中
在mysql中可以将json值赋值给变量。***但是变量值并不支持json类型在将json值赋值给用户自定义变量时json值会被转化为字符串类型。***
> 将Json值转化为字符串类型时字符串类型具有和Json类型相同的charset和collateJson转化为的字符串其字符集为utf8mb4并且其collate为utf8mb4_bin大小写敏感
```sql
SET @j = JSON_OBJECT('key', 'value');
SELECT @j;
```
由于json值的collate是utf8mb4_bin即json值是大小写敏感的故而'null','Null','NULL'中只有'null'是有效的json值
```sql
# 返回结果为100
select json_valid('null'),json_valid('Null'),json_valid('NULL');
```
#### 通过cast函数将字符串类型转化为json值
```sql
cast('null' as json)
```
#### 反斜杠转义'和"
在json值的String表示中如果想在json值中的文本值中含有'或"符号,需要在前面加上反斜杠进行转义。
```sql
# 通过create_object插入json值只需要在前面加上一个反斜杠进行转义
mysql> INSERT INTO facts VALUES
> (JSON_OBJECT("mascot", "Our mascot is a dolphin named \"Sakila\"."));
# 通过values插入json值时需要在前面加上两个反斜杠进行转义
mysql> INSERT INTO facts VALUES
> ('{"mascot": "Our mascot is a dolphin named \\"Sakila\\"."}');
```
#### 获取json值中属性的值
```sql
# 查询json值中属性的值时用""将结果括起来并含有转义符
mysql> SELECT sentence->"$.mascot" FROM facts;
+---------------------------------------------+
| col->"$.mascot" |
+---------------------------------------------+
| "Our mascot is a dolphin named \"Sakila\"." |
+---------------------------------------------+
1 row in set (0.00 sec)
# 查询json值中属性的值时不用”“和转义符
mysql> SELECT sentence->>"$.mascot" FROM facts;
+-----------------------------------------+
| sentence->>"$.mascot" |
+-----------------------------------------+
| Our mascot is a dolphin named "Sakila". |
+-----------------------------------------+
```
### Json值的normalizationmerging和autowarpping
#### json值的规范化
当json值被验证为有效的json文本时其也会被规范化。***当从左到右对json值进行解析时如果存在重复的key那么位于靠前位置的key和value将会被抛弃***。、
```sql
# key1重复位于靠后位置的key1将会覆盖位于靠前位置的key1
mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def');
+------------------------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def') |
+------------------------------------------------------+
| {"key1": "def", "key2": "abc"} |
+------------------------------------------------------+
```
> 在向Json列的插入语句执行时规范化行为会被执行
#### merge json的值
##### 合并array
在组合多个数组的上下文中多个数组被merge为一个数组json_merge_preserve函数会将后面数组的元素串联到前一个数组的末尾。
```sql
# 返回值为[1, 2, "a", "b", "c", true, false]
JSON_MERGE_PRESERVE('[1, 2]', '["a", "b", "c"]', '[true, false]')
```
##### 合并json object
在合并多个对象时会产生一个对象若多个对象中存在相同的key
- json_merge_preserve函数会将所有对象中具有相同key的value组合到一个array中从而保证key重复时在新生成对象中的唯一性。
- json_merge_patch在合并多个对象时则会将前面哪些重复key对应的value丢弃只保存最后一个key对应的value
```sql
mysql> SELECT
-> JSON_MERGE_PRESERVE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Preserve,
-> JSON_MERGE_PATCH('{"a": 3, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Patch\G
*************************** 1. row ***************************
Preserve: {"a": [1, 4], "b": 2, "c": [3, 5], "d": 3}
Patch: {"a": 4, "b": 2, "c": 5, "d": 3}
```
#### autowrapping
当非array值被使用在需要array的上下文时非array值会被autowrap该非array值会被[和]包围将其转换为一个array。
> 故而在json_merge_preserve对array值和非array值进行merge时会将非array值autowrap成一个array然后对两个array进行merge
```sql
mysql> SELECT
-> JSON_MERGE_PRESERVE('1', '2') AS Preserve,
-> JSON_MERGE_PATCH('1', '2') AS Patch\G
*************************** 1. row ***************************
Preserve: [1, 2]
Patch: 2
```
#### 当array和object进行merge
当array和object进行merge时会将object autowrap成一个array然后再对两个array执行merge操作
```sql
mysql> SELECT
-> JSON_MERGE_PRESERVE('[10, 20]', '{"a": "x", "b": "y"}') AS Preserve,
-> JSON_MERGE_PATCH('[10, 20]', '{"a": "x", "b": "y"}') AS Patch\G
*************************** 1. row ***************************
Preserve: [10, 20, {"a": "x", "b": "y"}]
Patch: {"a": "x", "b": "y"}
```
### 查找和修改json值
json值通过json路径表达式来访问其中属性对应的值。
```sql
SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
```
#### 路径表达式
路径表达式通过$符号来代表json值的根对象后面跟着选择器代表该json对象更具体的部分。
- .keyname用来选择keyname对应的值
- .path[N]代表path选中的是一个array下标从0开始如果path选中的不是一个array那么path[0]代表的是path本身
- [M to N]代表了array的一个子集开始位置为M结束位置为N
- path可以含有*或者**通配符
- .[*]通配json object中所有的成员属性的值
- [*]通配array中所有的元素
- prefix[**]suffix通配所有以prefix开始以suffix结束的路径
- 如果path没有在object中出现过那么path对应的值为NULL
> 如果json的key名中含有空格则路径表达式中该key名必须用”“括起来
> ```sql
> {"a fish": "shark", "a bird": "sparrow"}
> $."a fish" evaluates to shark
> $."a bird" evaluates to sparrow
> ```
> 如果路径表达式中含有通配通配多个值那么多个值会作为array返回
> ```sql
> mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*');
> +---------------------------------------------------------+
> | JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*') |
> +---------------------------------------------------------+
> | [1, 2, [3, 4, 5]] |
> +---------------------------------------------------------+
> mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]');
> +------------------------------------------------------------+
> | JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]') |
> +------------------------------------------------------------+
> | [3, 4, 5] |
> +------------------------------------------------------------+
> ```
#### **通配符样例
```sql
mysql> SELECT JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b') |
+---------------------------------------------------------+
| [1, 2] |
+---------------------------------------------------------+
```
#### 选中array的一个子集
```sql
mysql> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]');
+----------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]') |
+----------------------------------------------+
| [2, 3, 4] |
+----------------------------------------------+
1 row in set (0.00 sec)
```
#### last的用法
```sql
mysql> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]');
+--------------------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]') |
+--------------------------------------------------------+
| [2, 3, 4] |
+--------------------------------------------------------+
1 row in set (0.01 sec)
```
#### json_set
json_set对于已经存在的path会替换其path对应的值对于不存在的path会对该path添加新值
```sql
mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
mysql> SELECT JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+--------------------------------------------+
| JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+--------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20, 2]] |
+--------------------------------------------+
```
#### json_insert
json_insert会插入新值但是不会替换已有的值
```sql
mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
mysql> SELECT JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+-----------------------------------------------+
| JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+-----------------------------------------------+
| ["a", {"b": [true, false]}, [10, 20, 2]] |
+-----------------------------------------------+
```
#### json_replace
json_replace会替换已有的值但是不会插入新值
```sql
mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
mysql> SELECT JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+------------------------------------------------+
| JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+------------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20]] |
+------------------------------------------------+
```
#### json_remove
json_remove会删除path对应的值
```sql
mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
mysql> SELECT JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]');
+---------------------------------------------------+
| JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]') |
+---------------------------------------------------+
| ["a", {"b": [true]}] |
+---------------------------------------------------+
```