MySQL如何通过sql查询数据的区间分布情况?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 173 次浏览 • 2020-09-07 10:42 • 来自相关话题

MySQL中char、varchar和text三种字段类型的区别和选择

zkbhj 发表了文章 • 0 个评论 • 236 次浏览 • 2020-05-26 10:57 • 来自相关话题

在MySQL中,char、varchar和text类型的字段都可以用来存储字符类型的数据,char、varchar都可以指定最大的字符长度,但text不可以。

它们的存储方式和数据的检索方式也都不一样。

数据的检索效率是:char > varchar > text

具体说明:

char:存储定长数据很方便,CHAR字段上的索引效率级高,必须在括号里定义长度,可以有默认值,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间(自动用空格填充),且在检索的时候后面的空格会隐藏掉,所以检索出来的数据需要记得用什么trim之类的函数去过滤空格。

varchar:存储变长数据,但存储效率没有CHAR高,必须在括号里定义长度,可以有默认值。保存数据的时候,不进行空格自动填充,而且如果数据存在空格时,当值保存和检索时尾部的空格仍会保留。另外,varchar类型的实际长度是它的值的实际长度+1,这一个字节用于保存实际使用了多大的长度。

text:存储可变长度的非Unicode数据,最大长度为2^31-1个字符。text列不能有默认值,存储或检索过程中,不存在大小写转换,后面如果指定长度,不会报错误,但是这个长度是不起作用的,意思就是你插入数据的时候,超过你指定的长度还是可以正常插入。

关于存储空间:

在使用UTF8字符集的时候,MySQL手册上是这样描述的:

基本拉丁字母、数字和标点符号使用一个字节;
大多数的欧洲和中东手写字母适合两个字节序列:扩展的拉丁字母(包括发音符号、长音符号、重音符号、低音符号和其它音符)、西里尔字母、希腊语、亚美尼亚语、希伯来语、阿拉伯语、叙利亚语和其它语言;
韩语、中文和日本象形文字使用三个字节序列。

结论:

1、经常变化的字段用varchar;

2、知道固定长度的用char;

3、超过255字节的只能用varchar或者text;

4、能用varchar的地方不用text;

5、能够用数字类型的字段尽量选择数字类型而不用字符串类型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了;

6、同一张表出现多个大字段,能合并时尽量合并,不能合并时考虑分表 查看全部
在MySQL中,char、varchar和text类型的字段都可以用来存储字符类型的数据,char、varchar都可以指定最大的字符长度,但text不可以。

它们的存储方式和数据的检索方式也都不一样。

数据的检索效率是:char > varchar > text

具体说明:

char:存储定长数据很方便,CHAR字段上的索引效率级高,必须在括号里定义长度,可以有默认值,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间(自动用空格填充),且在检索的时候后面的空格会隐藏掉,所以检索出来的数据需要记得用什么trim之类的函数去过滤空格

varchar:存储变长数据,但存储效率没有CHAR高,必须在括号里定义长度,可以有默认值。保存数据的时候,不进行空格自动填充,而且如果数据存在空格时,当值保存和检索时尾部的空格仍会保留。另外,varchar类型的实际长度是它的值的实际长度+1,这一个字节用于保存实际使用了多大的长度。

text:存储可变长度的非Unicode数据,最大长度为2^31-1个字符。text列不能有默认值,存储或检索过程中,不存在大小写转换,后面如果指定长度,不会报错误,但是这个长度是不起作用的,意思就是你插入数据的时候,超过你指定的长度还是可以正常插入。

关于存储空间:

在使用UTF8字符集的时候,MySQL手册上是这样描述的:

基本拉丁字母、数字和标点符号使用一个字节;
大多数的欧洲和中东手写字母适合两个字节序列:扩展的拉丁字母(包括发音符号、长音符号、重音符号、低音符号和其它音符)、西里尔字母、希腊语、亚美尼亚语、希伯来语、阿拉伯语、叙利亚语和其它语言;
韩语、中文和日本象形文字使用三个字节序列。

结论:

1、经常变化的字段用varchar;

2、知道固定长度的用char;

3、超过255字节的只能用varchar或者text;

4、能用varchar的地方不用text;

5、能够用数字类型的字段尽量选择数字类型而不用字符串类型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了;

6、同一张表出现多个大字段,能合并时尽量合并,不能合并时考虑分表

MySQL数据库中指定字段值用特殊字符分割如何处理?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 521 次浏览 • 2020-02-05 18:26 • 来自相关话题

MySQL 文本类型,存储大小分别是多少?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 794 次浏览 • 2019-11-20 14:48 • 来自相关话题

MySQL中的聚簇索引和非聚簇索引

zkbhj 发表了文章 • 0 个评论 • 396 次浏览 • 2019-10-30 20:12 • 来自相关话题

聚簇索引

数据库表的索引从数据存储方式上可以分为聚簇索引和非聚簇索引(又叫二级索引)两种。Innodb的聚簇索引在同一个B-Tree中保存了索引列和具体的数据,在聚簇索引中,实际的数据保存在叶子页中,中间的节点页保存指向下一层页面的指针。“聚簇”的意思是数据行被按照一定顺序一个个紧密地排列在一起存储。一个表只能有一个聚簇索引,因为在一个表中数据的存放方式只有一种。

一般来说,将通过主键作为聚簇索引的索引列,也就是通过主键聚集数据。下图展示了Innodb中聚簇索引的结构(图片来自《高性能MySQL(第三版)》):





 
这里要特别注意页的概念,一个页可以理解为一块具有一定大小的连续的存储区域。相同页内的数据行在物理上是相邻的,因此逻辑上键值相邻的页在物理上可能相隔很远。

在中间的某个节点页中,主键<11的叶子页和11<主键<21的叶子页分别被两个指针所指向,且主键<11的叶子页也有一个指针指向了11<主键<21的叶子页,其余页之间的关系也是一样。

聚簇索引的优点

聚簇索引将索引和数据行保存在同一个B-Tree中,查询通过聚簇索引可以直接获取数据,相比非聚簇索引需要第二次查询(非覆盖索引的情况下)效率要高。
聚簇索引对于范围查询的效率很高,因为其数据是按照大小排列的,


聚簇索引的缺点

聚簇索引的更新代价比较高,如果更新了行的聚簇索引列,就需要将数据移动到相应的位置。这可能因为要插入的页已满而导致“页分裂”。
插入速度严重依赖于插入顺序,按照主键进行插入的速度是加载数据到Innodb中的最快方式。如果不是按照主键插入,最好在加载完成后使用OPTIMIZE TABLE命令重新组织一下表。
聚簇索引在插入新行和更新主键时,可能导致“页分裂”问题。
聚簇索引可能导致全表扫描速度变慢,因为可能需要加载物理上相隔较远的页到内存中(需要耗时的磁盘寻道操作)。


非聚簇索引

非聚簇索引,又叫二级索引。二级索引的叶子节点中保存的不是指向行的物理指针,而是行的主键值。当通过二级索引查找行,存储引擎需要在二级索引中找到相应的叶子节点,获得行的主键值,然后使用主键去聚簇索引中查找数据行,这需要两次B-Tree查找。

总结

下面是Innodb聚簇索引和非聚簇索引的示意图(图片来自《高性能MySQL(第三版)》:




  查看全部
聚簇索引

数据库表的索引从数据存储方式上可以分为聚簇索引和非聚簇索引(又叫二级索引)两种。Innodb的聚簇索引在同一个B-Tree中保存了索引列和具体的数据,在聚簇索引中,实际的数据保存在叶子页中,中间的节点页保存指向下一层页面的指针。“聚簇”的意思是数据行被按照一定顺序一个个紧密地排列在一起存储。一个表只能有一个聚簇索引,因为在一个表中数据的存放方式只有一种。

一般来说,将通过主键作为聚簇索引的索引列,也就是通过主键聚集数据。下图展示了Innodb中聚簇索引的结构(图片来自《高性能MySQL(第三版)》):

mysql_index_2.png

 
这里要特别注意页的概念,一个页可以理解为一块具有一定大小的连续的存储区域。相同页内的数据行在物理上是相邻的,因此逻辑上键值相邻的页在物理上可能相隔很远。

在中间的某个节点页中,主键<11的叶子页和11<主键<21的叶子页分别被两个指针所指向,且主键<11的叶子页也有一个指针指向了11<主键<21的叶子页,其余页之间的关系也是一样。

聚簇索引的优点


聚簇索引将索引和数据行保存在同一个B-Tree中,查询通过聚簇索引可以直接获取数据,相比非聚簇索引需要第二次查询(非覆盖索引的情况下)效率要高。
聚簇索引对于范围查询的效率很高,因为其数据是按照大小排列的,



聚簇索引的缺点


聚簇索引的更新代价比较高,如果更新了行的聚簇索引列,就需要将数据移动到相应的位置。这可能因为要插入的页已满而导致“页分裂”。
插入速度严重依赖于插入顺序,按照主键进行插入的速度是加载数据到Innodb中的最快方式。如果不是按照主键插入,最好在加载完成后使用OPTIMIZE TABLE命令重新组织一下表。
聚簇索引在插入新行和更新主键时,可能导致“页分裂”问题。
聚簇索引可能导致全表扫描速度变慢,因为可能需要加载物理上相隔较远的页到内存中(需要耗时的磁盘寻道操作)。



非聚簇索引

非聚簇索引,又叫二级索引。二级索引的叶子节点中保存的不是指向行的物理指针,而是行的主键值。当通过二级索引查找行,存储引擎需要在二级索引中找到相应的叶子节点,获得行的主键值,然后使用主键去聚簇索引中查找数据行,这需要两次B-Tree查找。

总结

下面是Innodb聚簇索引和非聚簇索引的示意图(图片来自《高性能MySQL(第三版)》:
mysql_index_3.png

 

MySQL中如何获取13位的时间戳?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 826 次浏览 • 2019-09-26 09:59 • 来自相关话题

如何在MySQL中快速筛除前缀相同的表?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 792 次浏览 • 2019-09-25 11:35 • 来自相关话题

如何查看MySQL的版本?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 906 次浏览 • 2019-09-11 14:34 • 来自相关话题

MySQL数据类型详解之JSON

zkbhj 发表了文章 • 0 个评论 • 525 次浏览 • 2019-09-11 13:57 • 来自相关话题

1、引入版本:5.7.8。

As of MySQL 5.7.8, MySQL supports a native JSON data type defined by RFC 7159 that enables efficient access to data in JSON (JavaScript Object Notation) documents. The JSON data type provides these advantages over storing JSON-format strings in a string column:

2、关于MySQL的JSON类型

JSON估计大家伙都熟悉了,我就不再介绍这方面内容。在5.7这个版本之前如果想在表中保存JSON格式类型的数据,则需要依靠varchar或者text之类的数据类型,如果在低于5.7版本的数据库中使用了JSON类型来建表,显然是不会成功的。
 3、JSON数据类型意义

其实,没有JSON数据类型的支持,我们一样可以通过varchar类型或者text等类型来保存这一格式的数据,但是,为什么还要专门增加这一数据格式的支持呢?其中肯定有较varchar或者text来存储此类型更优越的地方。
保证了JSON数据类型的强校验,JSON数据列会自动校验存入此列的内容是否符合JSON格式,非正常格式则报错,而varchar类型和text等类型本身是不存在这种机制的。MySQL同时提供了一组操作JSON类型数据的内置函数。更优化的存储格式,存储在JSON列中的JSON数据会被转成内部特定的存储格式,允许快速读取。可以基于JSON格式的特征支持修改特定的键值。(即不需要把整条内容拿出来放到程序中遍历然后寻找替换再塞回去,MySQL内置的函数允许你通过一条SQL语句就能搞定)
3、如何使用JSON类型

建表

在MySQL中创建具有JSON数据列的表,其实和数据类型没有太大区别,具体举例如下CREATE TABLE tab_base_info (
id BIGINT NOT NULL PRIMARY KEY auto_increment,
content json
);新增数据

插入一条语句,注意看JSON数据列的内容:
INSERT INTO tab_base_info (content)
VALUES
(
'{"author": "zkbhj", "blog": "https://www.zkbhj.com/"}'
);这里需要提醒的是:
JSON列存储的数据要么是NULL,要么必须是JSON格式数据,否则会报错。JSON数据类型是没有默认值的(声明时"DEFAULT NULL")。
 
5、MySQL关于JSON的内置函数

MySQL关于JSON数据格式的操作提供了很多高效率的内置函数,我们可以从MySQL官网上找到很详细的介绍和使用说明。 
从JSON功能介绍的主页也可以看到,这些内置函数支持我们创建、查找、替换和返回值等相关的操作,像我们替换指定内容的操作就可以使用JSON_REPLACE()这个函数,不过最后实现通过纯SQL语句执行最终的内容替换,你还需要通过执行UPDATE语句,比如:
UPDATE tab_base_info
SET content = json_replace(content, '$.author', "tom")
WHERE id = 1;
 其中“$.***”表示找到JSON内容中匹配的修改字段。

更多关于这些内置函数的用法,大家都可以到官网(链接请查看本文参考资料)的文档上去查阅,写的十分详细而且还有举例。 
官方文档:https://dev.mysql.com/doc/refman/5.7/en/json.html
  查看全部
1、引入版本:5.7.8。


As of MySQL 5.7.8, MySQL supports a native JSON data type defined by RFC 7159 that enables efficient access to data in JSON (JavaScript Object Notation) documents. The JSON data type provides these advantages over storing JSON-format strings in a string column:


2、关于MySQL的JSON类型

JSON估计大家伙都熟悉了,我就不再介绍这方面内容。在5.7这个版本之前如果想在表中保存JSON格式类型的数据,则需要依靠varchar或者text之类的数据类型,如果在低于5.7版本的数据库中使用了JSON类型来建表,显然是不会成功的。
 3、JSON数据类型意义

其实,没有JSON数据类型的支持,我们一样可以通过varchar类型或者text等类型来保存这一格式的数据,但是,为什么还要专门增加这一数据格式的支持呢?其中肯定有较varchar或者text来存储此类型更优越的地方。
  • 保证了JSON数据类型的强校验,JSON数据列会自动校验存入此列的内容是否符合JSON格式,非正常格式则报错,而varchar类型和text等类型本身是不存在这种机制的。
  • MySQL同时提供了一组操作JSON类型数据的内置函数。
  • 更优化的存储格式,存储在JSON列中的JSON数据会被转成内部特定的存储格式,允许快速读取。
  • 可以基于JSON格式的特征支持修改特定的键值。(即不需要把整条内容拿出来放到程序中遍历然后寻找替换再塞回去,MySQL内置的函数允许你通过一条SQL语句就能搞定)

3、如何使用JSON类型

建表

在MySQL中创建具有JSON数据列的表,其实和数据类型没有太大区别,具体举例如下
CREATE TABLE tab_base_info (
id BIGINT NOT NULL PRIMARY KEY auto_increment,
content json
);
新增数据

插入一条语句,注意看JSON数据列的内容:
INSERT INTO tab_base_info (content)
VALUES
(
'{"author": "zkbhj", "blog": "https://www.zkbhj.com/"}'
);
这里需要提醒的是:
  • JSON列存储的数据要么是NULL,要么必须是JSON格式数据,否则会报错。
  • JSON数据类型是没有默认值的(声明时"DEFAULT NULL")。

 
5、MySQL关于JSON的内置函数

MySQL关于JSON数据格式的操作提供了很多高效率的内置函数,我们可以从MySQL官网上找到很详细的介绍和使用说明。 
从JSON功能介绍的主页也可以看到,这些内置函数支持我们创建、查找、替换和返回值等相关的操作,像我们替换指定内容的操作就可以使用JSON_REPLACE()这个函数,不过最后实现通过纯SQL语句执行最终的内容替换,你还需要通过执行UPDATE语句,比如:
UPDATE tab_base_info 
SET content = json_replace(content, '$.author', "tom")
WHERE id = 1;

 其中“$.***”表示找到JSON内容中匹配的修改字段。

更多关于这些内置函数的用法,大家都可以到官网(链接请查看本文参考资料)的文档上去查阅,写的十分详细而且还有举例。 
官方文档:https://dev.mysql.com/doc/refman/5.7/en/json.html
 

MySQL如何判断字符串或时间戳最后两个字符?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 910 次浏览 • 2019-08-21 10:46 • 来自相关话题