From 3cf65df78502d55334e4c25a1e8db991cdc0f6bc Mon Sep 17 00:00:00 2001 From: wu xiangkai Date: Wed, 12 Oct 2022 19:40:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=B8=B8=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mysql/mysql文档/Data Type.md | 399 +++++++++++++++++++++++++++++++++ 1 file changed, 399 insertions(+) diff --git a/mysql/mysql文档/Data Type.md b/mysql/mysql文档/Data Type.md index 597d087..6f73fed 100644 --- a/mysql/mysql文档/Data Type.md +++ b/mysql/mysql文档/Data Type.md @@ -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) + - [datetime(fsp)](#datetimefsp) + - [timestamp(fsp)](#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值的normalization,merging和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 +# 返回结果为1,0,0 +select json_valid('null'),json_valid('Null'),json_valid('NULL'); +``` +#### json值赋值给用户定义的变量中 +在mysql中,可以将json值赋值给变量。***但是,变量值并不支持json类型,在将json值赋值给用户自定义变量时,json值会被转化为字符串类型。*** +> 将Json值转化为字符串类型时,字符串类型具有和Json类型相同的charset和collate,Json转化为的字符串其字符集为utf8mb4,并且其collate为utf8mb4_bin(大小写敏感) +```sql +SET @j = JSON_OBJECT('key', 'value'); +SELECT @j; +``` +由于json值的collate是utf8mb4_bin,即json值是大小写敏感的,故而'null','Null','NULL'中只有'null'是有效的json值 +```sql +# 返回结果为1,0,0 +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值的normalization,merging和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]}] | ++---------------------------------------------------+ +```