Mysql字符类型比较
一、 binary和char比较:
- binary 字节为单位,char字符为单位,字符占几个字节取决于字符集
- binary 比较规则基于字节值,char基于字符,即使是_bin的比较规则
- 范围都0-255字节,char对于不同字符集,可以存取的字节数不同
- 排序和比较规则都会根据字符码值,而不是词典顺序,如果采用binary那么是区分大小写的,和我们常用的utf8_general_ci相冲突
相同特性,摘自官方文档:
Specifying the CHARACTER SET binary attribute for a character data type causes the column
to be created as the corresponding binary data type: CHAR becomes BINARY, VARCHAR becomes VARBINARY , and TEXT becomes BLOB . For the ENUM and SET data types, this does not occur;
以下两种表定义是等义的:
CREATE TABLE t
(
c1 VARCHAR(10) CHARACTER SET binary,
c2 TEXT CHARACTER SET binary,
c3 ENUM('a','b','c') CHARACTER SET binary
);
CREATE TABLE t
(
c1 VARBINARY(10),
c2 BLOB,
c3 ENUM('a','b','c') CHARACTER SET binary
);
占用空间比较,测试uuid在不同字符集下的占用空间,主要是考虑到uuid是否适合业务主键的问题
创建4个表,第一个表是utf8字符集比较规则是utf8_bin
mysql> create table tc1(synid char(36) character set utf8 collate utf8_bin);
Query OK, 0 rows affected (0.07 sec)
mysql> create table tc2(synid char(36) character set utf8 collate utf8_general_ci);
Query OK, 0 rows affected (0.08 sec)
mysql> create table tc3(synid char(36) character set binary);
Query OK, 0 rows affected (0.06 sec)
mysql> create table tc4(synid binary(36));
Query OK, 0 rows affected (0.11 sec)
插入相同的数据1000条数据,表大小相同:
mysql> SELECT table_name,SUM(data_length) AS data_length
-> FROM information_schema.TABLES WHERE
-> table_name IN ('tc1','tc2','tc3','tc4')
-> GROUP BY table_name;
+------------+----------------+
| table_name | data_length |
+------------+----------------+
| tc1 | 1589248 |
| tc2 | 1589248 |
| tc3 | 1589248 |
| tc4 | 1589248 |
+------------+----------------+
4 rows in set (0.00 sec)
对于相同的原因主要有两方面:
- Basic Latin letters, digits, and punctuation signs use one byte,mysql支持的utf8编码对于基本的拉丁字母、数字、标点符号用一个字节
- A UUID is a 128-bit number represented by a utf8 string of five hexadecimal numbers in aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee format。利用uuid函数生成的uuid是32个十六进制数表示的字符串(由0-9和a-f组成),中间有4个横线分隔,总共有36个字符。
当时测试以上问题主要是为了讨论uuid适不适合做业务主键,以下是我的一些总结:
- 我们物理主键采用int自增,但是业务主键采用uuid
- 这样虽然不够友好,但是可以屏蔽从自增id上获取的业务量。
- 存储上虽然比int要多32个字节,但是现在存储很廉价。我们可以通过去掉无意义的'-'分隔符(32字节),或者采用uuid_short()(20字节)获取全局唯一标识
- 效率依赖于业务,如果是拿uuid查询,那么说明区分度很高了,建立索引效率不成问题。uuid做索引会比主键索引大很多,但在合理内存范围内就不会产生多余IO
- 和SQLServer保持兼容,如果合并停车记录两张表,显然会冲突,用uuid则不会。为了保证兼容sqlserver的Chinese_PRC_CI_AS,建议采用字符集是utf8,比较规则是utf8_general_ci
- 需要注意的是does not work with statement-based replication,主从复制时,基于语句级别的binlog不支持uuid()函数
二、 char和varchar
- 允许创建char(0)类型字段,用于某个字段存在,但是并不用它的值,只存储两个值:null和''
- 范围是0-65535字节,可以存储多少个字符由字符集决定。当字段类型小于255字节时,前缀会存储1个字节;当字段长度大于255时,前缀会存储2个字节
- 当char被存储时,会自动在尾部填充空格到设置的长度。varchar会保留空格。当char被检索时,会移除尾部空格,除非设置了PAD_CHAR_TO_FULL_LENGTH

- 当char被检索时,会移除尾部空格,除非设置了PAD_CHAR_TO_FULL_LENGTH;varchar在检索时会保留尾部空格

- 在严格的SQL mode下,char和varchar类型字段超过最大长度会截断并产生警告,如果截断的是非空字符,那么会阻止插入并报错,在任何SQL mode下,varchar会截断超出长度的空格,char则会截断尾部所有空格
- char和varchar的比较都是忽略尾部空格的,但是除了将尾部空格作为like匹配条件的

注意:需要注意的是,varchar显示是不截断尾部空格的,但在比较的时候忽略空格的,此外varchar存储时会去掉尾部空格,如果该字段被定义成唯一建或主键,去除结尾空格后相同的字符串会违反唯一性约束
三、 binary和vbinary
- binary和vbinary在超过最大设置长度时,在非strict SQL mode下,那么会自动截断并警告;在strict SQL mode下,会阻止插入,并报错。
- binary存储时自动填充值\0(0x00),满足指定长度,例如,char(3),'a '插入变成'a \0','a'变成'a\0\0'。在检索的时候,并不去掉结尾的填充值。
- varbinary,存储时不会填补\0,检索时不会去掉结尾\0
- binary和varbinary在比较时,包括order by和distinct,所有的字节都是有意义的。注0x00<space,不相等
注意:同样,vbinary在需要注意在存储时去掉尾部\0,如果该字段被定义成唯一建或主键,去除结尾\0后相同的字符串会违反唯一性约束
Mysql字符类型比较的更多相关文章
- mysql字符类型大小写敏感的讨论
mysql字符类型默认是不区分大小写的,即select * from t where name='AAA'与='aaa'没区别,以下是测试的例子 (root)); (root,,,,'BbB'); ( ...
- MySQL字符类型datetime与timestamp
这片博客来详细分区一下这哥俩! 首先来说明这两个字符类型: DATETIME 8 1000-01-01 00:00:00 ~9999~12-31 23:59:59 0000-00-00 00:00:0 ...
- mysql string types ---- mysql 字符类型详解
一.mysql 中包涵的字符类型: [national] char [(m)] [character set charset_name] [collate collation_name] [natio ...
- mysql字符类型
字符类型 #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html #注意:char和varchar括号内的参数指的都是字符的长度 #char类型:定 ...
- MySQL字符类型学习笔记
目录 一.字符集和字符编码 1.1.字符集 1.2.字符编码 二.字符集排序规则 2.1.排序规则定义 2.2 .排序规则特征 三.CHAR和VARCHAR 3.1.CHAR类型 3.2.VARCHA ...
- MySQL 字符类型
字符类型 MySQL提供了多种关于字符存储的类型,但是在大多数情况下我们只使用char和varchar即可 类型 大小 用途 CHAR 0-255字节 定长字符串 VARCHAR 0-65535 字节 ...
- MYSQL字符类型数值排序
今天遇到MySQL数字排序问题,我的排序字段是经过计算后的,而计算后的字段直接拿来排序就会按照字符一个个排序,所以这里找到简单的方法, ORDER BY 排序字段* 或者 ORDER BY 排序字段+ ...
- mysql字符类型总结及常用字符函数
常用字符串函数: concat(s1,s2,s3..) 连接s1,s2,...sn为一个字符串 INSERT(str,x,y,instr)将字符串str从x位置开始,y个字符串替换为字符串 ...
- mysql数值类型总结及常用函数
最近在学习下,总结一下mysql数值类型: mysql字符类型分: 1.整数类型: 字节 值范围 INTERGER 1 ...
随机推荐
- JTree使用
package JTree; import java.awt.Component; import javax.swing.Icon; import javax.swing.JTree; import ...
- Eclipse中web项目部署至Tomcat步骤
Eclipse的web工程至Tomcat默认的部署目录是在工程空间下,本文旨在将部署目录改为Tomcat安装目录,并解决依赖包输出问题. 1.在Eclipse中添加Tomcat服务器. 2.将web工 ...
- etcd第一集
网站:https://github.com/coreos/etcd 一些观点:https://yq.aliyun.com/articles/11035 1.etcd是键值存储仓库,配置共享和服务发现2 ...
- JAVA课程体系
文件流 单点登录 maven.maven私服 jenkins 小程序 支付 webservice/webapi redis 工作流 权限:shiro 高并发 springBoot dubbo 消息推送 ...
- haoop 断电后导致block文件损坏
hbase将dfs作为存储,公司测试环境断电后,hadoop集群会因此而损坏一些block文件,这个时候,客户端在读取文件时会报一些错: DataXceiver error processing RE ...
- sql查询单个银行账号重复
非一单位多银行账号. 今天成都公司熊娇付款时候单位名称在弹出的网银补录变成1,从开户银行看都是正常的,只是在分子公司集团这边点击修改开户银行保存就提示错误“银行账号不能重复” select * fro ...
- mysql:忘记root密码
1:修改/etc/my.cnf 2:重启服务 3:进入mysql 4:修改密码 5:刷新权限 注意:修改完成后,别忘了修改/etc/my.cnf,删除skip-grant-tables,否则重启服务后 ...
- PHP如何通过CURL上传文件
PHP使用CURL上传文件只需发送一个POST请求就可以了,在请求中设置某个字段为需要上传的文件全路径,并且以“@”开头,然后使用CURL把该变量以POST方式发送到服务器,在服务端即可以从超级全局变 ...
- [Maven]修改Maven的本地仓库路径
安装Maven后我们会在用户目录下发现.m2 文件夹.默认情况下,该文件夹下放置了Maven本地仓库.m2/repository.所有的Maven构件(artifact)都被存储到该仓库中,以方便重用 ...
- sklearn学习笔记1
Image recognition with Support Vector Machines #our dataset is provided within scikit-learn #let's s ...