mysql中新建数据库create table的COLLATE是什么?
在mysql中执行show create table <tablename>
指令,可以看到一张表的建表语句,example如下:
CREATE TABLE `table1` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,`field1` text COLLATE utf8_unicode_ci NOT NULL COMMENT '字段1',`field2` varchar(128) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '字段2',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8_unicode_ci;
大部分字段我们都能看懂,但是今天要讨论的是COLLATE关键字。这个值后面对应的utf8_unicode_ci
是什么意思呢?面试的时候用这个题目考一考DBA,应该可以难倒一大部分人。
COLLATE是用来做什么的?
使用phpmyadmin的开发可能会非常眼熟,因为其中的中文表头已经给出了答案:
phpmyadmin截图
所谓utf8_unicode_ci
,其实是用来排序的规则。对于mysql中那些字符类型的列,如VARCHAR
,CHAR
,TEXT
类型的列,都需要有一个COLLATE
类型来告知mysql如何对该列进行排序和比较。简而言之,COLLATE会影响到ORDER BY语句的顺序,会影响到WHERE条件中大于小于号筛选出来的结果,会影响**DISTINCT**
、**GROUP BY**
、**HAVING**
语句的查询结果。另外,mysql建索引的时候,如果索引列是字符类型,也会影响索引创建,只不过这种影响我们感知不到。总之,凡是涉及到字符类型比较或排序的地方,都会和COLLATE有关。
各种COLLATE的区别
COLLATE
通常是和数据编码(CHARSET
)相关的,一般来说每种CHARSET
都有多种它所支持的COLLATE
,并且每种CHARSET
都指定一种COLLATE
为默认值。例如Latin1
编码的默认COLLATE
为latin1_swedish_ci
,GBK
编码的默认COLLATE
为gbk_chinese_ci
,utf8mb4
编码的默认值为utf8mb4_general_ci
。
这里顺便讲个题外话,mysql中有utf8
和utf8mb4
两种编码,在mysql中请大家忘记**utf8**
,永远使用**utf8mb4**
。这是mysql的一个遗留问题,mysql中的utf8
最多只能支持3bytes长度的字符编码,对于一些需要占据4bytes的文字,mysql的utf8
就不支持了,要使用utf8mb4
才行。
很多COLLATE
都带有_ci
字样,这是Case Insensitive的缩写,即大小写无关,也就是说"A"和"a"在排序和比较的时候是一视同仁的。selection * from table1 where field1="a"
同样可以把field1为"A"的值选出来。与此同时,对于那些_cs
后缀的COLLATE
,则是Case Sensitive,即大小写敏感的。
在mysql中使用show collation
指令可以查看到mysql所支持的所有COLLATE
。以utf8mb4
为例,该编码所支持的所有COLLATE
如下图所示。
mysql中和utf8mb4相关的所有COLLATE
图中我们能看到很多国家的语言自己的排序规则。在国内比较常用的是utf8mb4_general_ci
(默认)、utf8mb4_unicode_ci
、utf8mb4_bin
这三个。我们来探究一下这三个的区别:
首先utf8mb4_bin
的比较方法其实就是直接将所有字符看作二进制串,然后从最高位往最低位比对。所以很显然它是区分大小写的。
而utf8mb4_unicode_ci
和utf8mb4_general_ci
对于中文和英文来说,其实是没有任何区别的。对于我们开发的国内使用的系统来说,随便选哪个都行。只是对于某些西方国家的字母来说,utf8mb4_unicode_ci
会比utf8mb4_general_ci
更符合他们的语言习惯一些,general
是mysql一个比较老的标准了。例如,德语字母“ß”
,在utf8mb4_unicode_ci
中是等价于"ss"
两个字母的(这是符合德国人习惯的做法),而在utf8mb4_general_ci
中,它却和字母“s”
等价。不过,这两种编码的那些微小的区别,对于正常的开发来说,很难感知到。本身我们也很少直接用文字字段去排序,退一步说,即使这个字母排错了一两个,真的能给系统带来灾难性后果么?从网上找的各种帖子讨论来说,更多人推荐使用utf8mb4_unicode_ci
,但是对于使用了默认值的系统,也并没有非常排斥,并不认为有什么大问题。结论:推荐使用utf8mb4_unicode_ci
,对于已经用了utf8mb4_general_ci
的系统,也没有必要花时间改造。
另外需要注意的一点是,从mysql 8.0开始,mysql默认的
CHARSET
已经不再是Latin1
了,改为了utf8mb4
(参考链接),并且默认的COLLATE也改为了utf8mb4_0900_ai_ci
。utf8mb4_0900_ai_ci
大体上就是unicode
的进一步细分,0900
指代unicode比较算法的编号( Unicode Collation Algorithm version),ai
表示accent insensitive(发音无关),例如e, è, é, ê 和 ë是一视同仁的。相关参考链接1,相关参考链接2
COLLATE设置级别及其优先级
设置COLLATE
可以在示例级别、库级别、表级别、列级别、以及SQL指定。实例级别的COLLATE
设置就是mysql配置文件或启动指令中的collation_connection
系统变量。
库级别设置COLLATE
的语句如下:
CREATE DATABASE <db_name> DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
如果库级别没有设置
CHARSET
和COLLATE
,则库级别默认的CHARSET
和COLLATE
使用实例级别的设置。
在mysql8.0以下版本中,你如果什么都不修改,默认的CHARSET
是Latin1
,默认的COLLATE
是latin1_swedish_ci
。
从mysql8.0开始,默认的CHARSET
已经改为了utf8mb4
,默认的COLLATE
改为了utf8mb4_0900_ai_ci
。
表级别的COLLATE
设置,则是在CREATE TABLE
的时候加上相关设置语句,例如:
CREATE TABLE (……) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
如果表级别没有设置CHARSET
和COLLATE
,则表级别会继承库级别的CHARSET
与COLLATE
。
列级别的设置,则在CREATE TABLE
中声明列的时候指定,例如
CREATE TABLE (`field1` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',……) ……
如果列级别没有设置CHARSET
和COLATE
,则列级别会继承表级别的CHARSET
与COLLATE
。
最后,你也可以在写SQL查询的时候显示声明COLLATE
来覆盖任何库表列的COLLATE
设置,不太常用,了解即可:
SELECT DISTINCT field1 COLLATE utf8mb4_general_ci FROM table1;SELECT field1, field2 FROM table1 ORDER BY field1 COLLATE utf8mb4_unicode_ci;
如果全都显示设置了,那么优先级顺序是 SQL语句 > 列级别设置 > 表级别设置 > 库级别设置 > 实例级别设置。也就是说列上所指定的COLLATE
可以覆盖表上指定的COLLATE
,表上指定的COLLATE
可以覆盖库级别的COLLATE
。如果没有指定,则继承下一级的设置。即列上面没有指定COLLATE
,则该列的COLLATE
和表上设置的一样。
以上就是关于mysql的COLLATE
相关知识。不过,在系统设计中,我们还是要尽量避免让系统严重依赖中文字段的排序结果,在mysql的查询中也应该尽量避免使用中文做查询条件。
https://www.cnblogs.com/qcloud1001/p/10033364.html
mysql中新建数据库create table的COLLATE是什么?相关推荐
- 使用mybatis操作MySQL中的数据库表1---读取数据
1)MySQL中创建表 create table student ( id int(11) not null, name varchar(255) default null, email varcha ...
- Mysql 中创建数据库并插入数据
运行数据库 sudo service mysql startmysql -u root 新建数据库 create database mydatabse_test; 使用数据库 use mydataba ...
- oracle repeatable read,Oracle和Mysql中的数据库事务有关问题:Mysql Read-Repeatable有有关问题...
Oracle和Mysql中的数据库事务问题:Mysql Read-Repeatable有问题 今天不知不觉想到数据库的乐观锁和悲观锁,遂想写个程序测测,却发现了另一个问题,Mysql InnoDB的R ...
- Oracle中,使 CREATE TABLE AS SELECT 支持ORDER BY
Oracle中,使 CREATE TABLE AS SELECT 支持ORDER BY 文章发表:kehui 发表日期:2002-01-21 阅读次数:1103 大家都知道,"CREA ...
- mysql中影响数据库性能的因素讲解
mysql中影响数据库性能的因素讲解 在本篇文章中我们给大家讲述了mysql中影响性能的因素以及相关知识点内容,有兴趣的朋友参考下 关于数据库性能的故事 面试时多多少少会讲到数据库上的事情," ...
- MySQL中新建用户,新建数据库,用户授权,删除用户,修改密码的相关操作
测试环境:WIN32 mysql5.0.45 注:本操作是在WIN命令提示符下,phpMyAdmin同样适用. 用户:phplamp 用户数据库:phplampDB 1.新建用户. //登录MYSQ ...
- MySQL中删除数据库的基本语法格式为_《MySQL数据库》SQL简介、语法格式
原标题:<MySQL数据库>SQL简介.语法格式 一.SQL的简介 结构化查询语言(Structured Query Language),简称SQL.它是专门用来访问数据库的标准编程语言. ...
- mysql建表auto_increment_mysql create table auto_increment
当插入记录时,没有为AUTO_INCREMENT明确指定值,则等同插入NULL值 把0插入AUTO_INCREMENT数据列的效果与插入NULL值一样.但不建议这样做,还是以插入NULL值为好. 如果 ...
- MySQL中查看数据库
查看当前使用的数据库,可使用如下命令 mysql> select database(); #使用函数database() mysql> show tables; #列头信息中可看出当前使用 ...
最新文章
- 点击一百万次(详解)——bugku
- android:parentActivityName
- SAP Fiori pageSet请求的处理原理
- 【Leetcode | 47】 222. 完全二叉树的节点个数
- 【Spring Bean的生命周期】
- .exe已停止工作_Windows 10累积更新KB4565503和KB4565483已发布
- JCheckBox 默认选择_了解GoldWave使用习惯的一些默认设置
- 提问的智慧(学习笔记)
- 都能看懂的嵌入式linux/android alsa_aplay alsa_amixer命令行使用方法
- 给初学Python的小伙伴一些建议
- 【设计鉴赏】精选字体设计鉴赏(三)
- 没有他的帅气,也要像他那般努力!(转载)
- 论文--Learning to Predict Bus Arrival Time From Heterogeneous Measurements via Recurrent Neural Networ
- 服务器硬件规格常用查看命令——CPU相关命令
- vue项目中画出优雅的线条(虚线、直线、折线、带箭头、流动效果等)
- 【CAR笔记1】标定的标准——ASAP和ASAM
- 独立开发变现周刊(第44期):12岁的小男孩在9个小时内NFT卖了40万美元!
- 低调,中国的FPGA到底有多强?
- uniapp实现音视频通讯
- 2018年度最优秀mac软件及游戏推荐,个个万里挑一
热门文章
- 二本Java小菜鸟4面字节跳动被秒成渣渣,深度集成!
- 处理VUE移动端输入法遮挡input输入框的问题
- 数据结构入门1(认识数据结构)
- 为应对618大促期间快递压力 达达上线“苍穹”大数据平台
- ssh推送Warning: Permanently added 'gitee.com,120.55.226.24' (ECDSA) to the list of known ho
- visual studio code无法生成可执行文件
- 陶哲轩career advice 翻译
- 双camera景深计算
- RK3399平台开发系列讲解(以太网)5.11、PHY工作的代码流程
- 网页小游戏源码丨FC模拟器网页版源码