MySQL中的数据类型binary和varbinary详解

前言

BINARY和VARBINARY与 CHAR和VARCHAR类型有点类似,不同的是BINARY和VARBINARY存储的是二进制的字符串,而非字符型字符串。也就是说,BINARY和VARBINARY没有字符集的概念,对其排序和比较都是按照二进制值进行对比。

BINARY(N)VARBINARY(N)中的N指的是字节长度,而CHAR(N)VARCHAR(N)中N指的是的字符长度。对于BINARY(10) ,其可存储的字节固定为10,而对于CHAR(10) ,其可存储的字节视字符集的情况而定。

我们来看下面的例子。

mysql> CREATE TABLE t (
 -> a BINARY(1)
 -> )ENGINE=InnoDB CHARSET=GBK;
Query OK, 0 rows affected (0.02 sec)
mysql> SET NAMES GBK;
Query OK, 0 rows affected (0.00 sec)
MySQL> INSERT INTO t SELECT '我';
Query OK, 1 row affected, 1 warning (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> SHOW WARNINGS\G;
*************************** 1. row ***************************
 Level: Warning
 Code: 1265
Message: Data truncated for column 'a' at row 1
1 row in set (0.00 sec)
mysql> SELECT a,HEX(a) FROM t\G;
*************************** 1. row ***************************
 a:
HEX(a): CE

表t包含一个类型为BINARY(1)的列,因为BINARY(N)中N代表字节,而gbk字符集中的中文字符“我”需要占用2字节,所以在插入时给出警告,提示字符被截断。如果SQL_MODE为严格模式,则会直接报错。查看表t的内容,则可发现a中只存储了字符“我”的前一个字节,后一个字节被截断了。如果表t的a列中字符的类型为CHAR类型,则完全不会有上述问题,例如:

mysql> CREATE TABLE t (
 -> a CHAR(1)
 -> )ENGINE=InnoDB CHARSET=GBK;
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO t SELECT '我';
Query OK, 1 row affected, 1 warning (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT a,HEX(a) FROM t\G;
*************************** 1. row ***************************
 a: 我
HEX(a): CED2
1 row in set (0.00 sec)

BINARY和VARBINARY对比CHAR和VARCHAR,第一个不同之处就是BINARY(N)VARBINARY(N)中的N值代表的是字节数,而非字符长度;第二个不同点是,CHAR和VARCHAR在进行字符比较时,比较的只是字符本身存储的字符,忽略字符后的填充字符,而对于BINARY和VARBINARY来说,由于是按照二进制值来进行比较的,因此结果会非常不同,例如:

mysql> SELECT
 -> HEX('a'),
 -> HEX('a '),
 -> 'a'='a '\G;
*************************** 1. row ***************************
HEX('a'): 61
HEX('a '): 612020
'a'='a ': 1
1 row in set (0.00 sec)
mysql> SELECT
 -> HEX(BINARY('a')),
 -> HEX(BINARY('a ')),
 -> BINARY('a')= BINARY('a ')\G;
*************************** 1. row ***************************
  HEX(BINARY('a')): 61
 HEX(BINARY('a ')): 612020
BINARY('a')= BINARY('a '): 0
1 row in set (0.00 sec)

对于CHAR和VARCHAR来说,比较的是字符值,因此第一个比较的返回值是1。对于BINARY和VARBINARY来说,比较的是二进制的值,“a”的十六进制为61,“a  ”的十六进制为612020,显然不同,因此第二个比较的返回值为0。

第三个不同的是,对于BINARY字符串,其填充字符是0x00,而CHAR的填充字符为0x20。可能是因为BINARY的比较需要,0x00显然是比较的最小字符,示例如下:

mysql> CREATE TABLE t ( a BINARY(3));
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t SELECT 'a';
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT a,HEX(a) FROM t\G;
*************************** 1. row ***************************
 a: a
HEX(a): 610000
1 row in set (0.00 sec)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 详解MySQL数据类型DECIMAL(N,M)中N和M分别表示的含义

    同事问MySQL数据类型DECIMAL(N,M)中N和M分别表示什么含义,M不用说,显然是小数点后的小数位数,但这个N究竟是小数点之前的最大位数,还是加上小数部分后的最大位数?这个还真记不清了.于是乎,创建测试表验证了一番,结果如下: 测试表,seller_cost字段定义为decimal(14,2) CREATE TABLE `test_decimal` ( `id` int(11) NOT NULL, `seller_cost` decimal(14,2) DEFAULT NULL ) EN

  • 设置MySQL中的数据类型来优化运行速度的实例

    今天看了一个优化案例觉的挺有代表性,这里记录下来做一个标记,来纪念一下随便的字段定义的问题. 回忆一下,在表的设计中很多人习惯的把表的结构设计成Varchar(64),Varchar(255)之类的,虽然大多数情况只存了5-15个字节.那么我看一下下面这个案例. 查询语句: SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = 1301 GROUP BY client_

  • MySQL中的数据类型binary和varbinary详解

    前言 BINARY和VARBINARY与 CHAR和VARCHAR类型有点类似,不同的是BINARY和VARBINARY存储的是二进制的字符串,而非字符型字符串.也就是说,BINARY和VARBINARY没有字符集的概念,对其排序和比较都是按照二进制值进行对比. BINARY(N)和VARBINARY(N)中的N指的是字节长度,而CHAR(N)和VARCHAR(N)中N指的是的字符长度.对于BINARY(10) ,其可存储的字节固定为10,而对于CHAR(10) ,其可存储的字节视字符集的情况而

  • mysql中decimal数据类型小数位填充问题详解

    前言 在开发过程中,我们往往会用到decimal数据类型.因为decimal是MySQL中存在的精准数据类型. MySQL中的数据类型有:float,double等非精准数据类型和decimal这种精准. 区别:float,double等非精准类型,在DB中保存的是近似值. Decimal则以字符串的形式保存精确的原始数值. decimal介绍: decimal(a,b) 其中:a指定指定小数点左边和右边可以存储的十进制数字的最大个数,最大精度38.b指定小数点右边可以存储的十进制数字的最大个数

  • MySQL中replace into与replace区别详解

    目录 0.故事的背景 1.replace into 的使用方法 2.有唯一索引时—replace into & 与replace 效果 3.没有唯一索引时—replace into 与 replace 1).replace函数的具体情况 2).replace into 函数的具体情况 4.replace的用法 本篇为抛砖引玉篇,之前没关注过replace into 与replace 的区别.经过多个场景测试,居然没找到在插入数据的时候两者有什么本质的区别?如果了解详情的伙伴们,请告知留言告知一二

  • MySQL中replace into语句的用法详解

    在向表中插入数据的时候,经常遇到这样的情况: 1.首先判断数据是否存在: 2.如果不存在,则插入: 3.如果存在,则更新.   在 SQL Server 中可以这样写: 复制代码 代码如下: if not exists (select 1 from table where id = 1) insert into table(id, update_time) values(1, getdate()) else update table set update_time = getdate() whe

  • MySQL中的唯一性约束与NULL详解

    前言 之前做的一个需求,简化描述下就是接受其他组的 MQ 的消息,然后在数据库里插入一条记录.为了防止他们重复发消息,插入多条重复记录,所以在表中的几个列上加了个唯一性索引. CREATE UNIQUE INDEX IDX_UN_LOAN_PLAN_APP ON testTable (A, B, C); 这时 A,B,C 三列都是不允许 NULL 值的,唯一性约束也是 work 的. 后来由于需求的变化,修改了以前的唯一性约束,又多加了一列.(至于为什么加就不赘述了). ALTER TABLE

  • MySQL中的行级锁定示例详解

    前言 锁是在执行多线程时用于强行限定资源访问的同步机制,数据库锁根据锁的粒度可分为行级锁,表级锁和页级锁 行级锁 行级锁是mysql中粒度最细的一种锁机制,表示只对当前所操作的行进行加锁,行级锁发生冲突的概率很低,其粒度最小,但是加锁的代价最大.行级锁分为共享锁和排他锁. 特点: 开销大,加锁慢,会出现死锁:锁定粒度最小,发生锁冲突的概率最大,并发性也高: 实现原理: InnoDB行锁是通过给索引项加锁来实现的,这一点mysql和oracle不同,后者是通过在数据库中对相应的数据行加锁来实现的,

  • Mysql中事务ACID的实现原理详解

    引言 照例,我们先来一个场景~ 面试官:"知道事务的四大特性么?" 你:"懂,ACID嘛,原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability)!" 面试官:"你们是用mysql数据库吧,能简单说说innodb中怎么实现这四大特性的么?" 你:"我只知道隔离性是怎么做的balabala~~" 面试官:"还是回去等通知吧~" OK,回到正题

  • 关于MySQL中的查询开销查看方法详解

    MySQL逻辑架构 如果能在头脑中构建一幅MySQL各组件之间如何协同工作的架构图,有助于深入理解MySQL服务器.下图展示了MySQL的逻辑架构图. MySQL逻辑架构,来自:高性能MySQL MySQL逻辑架构整体分为三层,最上层为客户端层,并非MySQL所独有,诸如:连接处理.授权认证.安全等功能均在这一层处理. MySQL大多数核心服务均在中间这一层,包括查询解析.分析.优化.缓存.内置函数(比如:时间.数学.加密等函数).所有的跨存储引擎的功能也在这一层实现:存储过程.触发器.视图等.

  • MySQL中日期型单行函数代码详解

    MySQL中日期型单行函数: CURDATE()或CURRENT_DATE() 返回当前日期(精确到日) 参考代码如下: SELECT CURDATE() FROM DUAL; SELECT CURRENT_DATE() FROM DUAL; -----------------------------------(分割线)------------------------------------ CURTIME() 或CURRENT_TIME() 返回当前时间(精确到秒) 参考代码如下: SELE

  • 关于Mysql中ON与Where区别问题详解

    今天工作的时候编写了一个SQL,大家一起来看一下 SELECT * FROM user user LEFT JOIN user_message msg ON user.id = msg.user_id AND user.name = '张三' 我们有一张user表 我们还有一张user_message表 我们执行上面的SQL后,查询结果如下 并不如我们所想的,只出现张三的结果,这是为什么呢? 经过我的整理发现查询是如下原因 关联的时候ON条件是在合并两张表形成临时表前进行的条件筛选,所以在使用

随机推荐