>> "我爱Ruby".size
>> "I Love Ruby!".size
从MySQL中查询出来的结果,对比
mysql> select * from str_test;
+------------+--------------+
| name_chn | name_en |
+------------+--------------+
| 我爱Ruby | I Love Ruby! |
+------------+--------------+
1 row in set (0.02 sec)
mysql> select length(name_chn) from str_test;
+------------------+
| length(name_chn) |
+------------------+
| 10 |
+------------------+
1 row in set (0.01 sec)
3[一个汉字三字节] * 2 + 1[一个英文一字节] * 4 = 10
mysql> select length(name_en) from str_test;
+-----------------+
| length(name_en) |
+-----------------+
| 12 |
+-----------------+
1 row in set (0.00 sec)
10[一个英文一字节] * 1 + 2[空格一字节] * whitespace = 12
2、使用 GBK
做测试
CREATE TABLE `str_test` (
`name_chn` varchar(20) NOT NULL,
`name_en` varchar(20) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
插入数据,并且测试
mysql> insert into str_test values ('我爱Ruby', 'I Love Ruby!');
Query OK, 1 row affected (0.00 sec)
mysql> select * from str_test;
+------------+--------------+
| name_chn | name_en |
+------------+--------------+
| 我爱Ruby | I Love Ruby! |
+------------+--------------+
1 row in set (0.01 sec)
GBK
中文是两个字节,英文是一个字节。
mysql> select length(name_chn) from str_test;
+------------------+
| length(name_chn) |
+------------------+
| 8 |
+------------------+
1 row in set (0.00 sec)
2[中文两个字节] * 2 + 4[英文一个字节] * 1 = 8
mysql> select length(name_en) from str_test;
+-----------------+
| length(name_en) |
+-----------------+
| 12 |
+-----------------+
1 row in set (0.00 sec)
10[英文一个字节] * 1 + 2[空格一个字节] * whitespace = 12
六、关于varchar 最多能存多少值
-
mysql的记录行长度是有限制的,不是无限长的,这个长度是64K
,即65535
个字节,对所有的表都是一样的。
-
MySQL对于变长类型的字段会有1-2个字节来保存字符长度。
-
当字符数小于等于255时,MySQL只用1个字节来记录,因为2的8次方减1只能存到255。
-
当字符数多余255时,就得用2个字节来存长度了。
-
在utf-8
状态下的varchar,最大只能到 (65535 - 2) / 3 = 21844 余 1。
-
在gbk
状态下的varchar, 最大只能到 (65535 - 2) / 2 = 32766 余 1
使用 utf-8
创建
mysql> CREATE TABLE `str_test` (
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(21845) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=utf8
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
mysql> CREATE TABLE `str_test` (
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(21844) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=utf8
Query OK, 0 rows affected (0.06 sec)
使用gbk
创建
当存储长度为 32768 失败~
mysql> CREATE TABLE `str_test` (
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(32768) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
ERROR 1074 (42000): Column length too big for column 'name_chn' (max = 32767); use BLOB or TEXT instead
当存储长度为 32767 失败~
mysql> CREATE TABLE `str_test` ( -> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(32767) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
当存储长度为 32766 成功~
mysql> CREATE TABLE `str_test` (
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(32766) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
Query OK, 0 rows affected (0.03 sec)
smallint 用两个字节存储,所以
2[smallint] + 32766 * 2[varchar存储长度] + 2[2个字节来存长度] > 65535
所以失败~
mysql> CREATE TABLE `str_test` (
-> `id` smallint(1) NOT NULL,
-> `name_chn` varchar(32766) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
#####七、数值类型所占的字节
类型 | 所占字节 |
---|
int | 4 字节 |
smallint | 2 字节 |
tinyint | 1 字节 |
decimal | 变长 |
官方关于decimal
的描述如下
Values for DECIMAL (and NUMERIC) columns are represented using a binary format that packs nine decimal (base 10) digits into four bytes.
Storage for the integer and fractional parts of each value are determined separately.
Each multiple of nine digits requires four bytes, and the “leftover” digits require some fraction of four bytes.
The storage required for excess digits is given by the following table.
翻译为中文
使用二进制格式将9个十进制(基于10)数压缩为4个字节来表示DECIMAL列值。
每个值的整数和分数部分的存储分别确定。
每个9位数的倍数需要4个字节,并且“剩余的”位需要4个字节的一部分。
下表给出了超出位数的存储需求:
Leftover Digits | Number Of Bytes |
---|
0 | 0 |
1 | 1 |
2 | 1 |
3 | 2 |
4 | 2 |
5 | 3 |
6 | 3 |
7 | 4 |
8 | 4 |
那:decimal(10,2)占几个字节?
1、首先 10 指的是整数与小数部分的总长度, 2指的是小数部分的长度。那么整数部分就只有 10 - 2 = 8 位
2、因为整数与小数的存储市各自独立确定的,所以他们各自所占用空间的综合就是所占的总空间了。
3、对表可知,整数部分8位占了4个字节,小数部分2位占了1个字节,所以decimal(10,2)总共占了 4 + 1 = 5 个字节。
4、decimal(6,2) 整数部分(6 - 2 = 4) 位占2字节,小数部分2位占1字节,总共占3字节。
varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度(长度超过255时需要2个字节),因此最大长度不能超过65535。
- UTF-8:一个汉字 = 3个字节,英文是一个字节
- GBK: 一个汉字 = 2个字节,英文是一个字节
在utf-8
状态下,汉字最多可以存 21844个字符串, 英文也为 21844个字符串。
在gbk
状态下,汉字最多可以存 32766个字符串,英文也为 32766个字符串。
秋招面试某公司的时候,面试官突然发难,问起了Unicode的相关知识,使我手足无措,今天抽出时间来专门学习整理一下相关知识
一、Unicode是什么?
Unicode,中文又称万国码、国际码、统一码、单一码,是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。
二、Unicode.
mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+-------...
mysql4.0版本以下,varchar(50), 指的是50字节,如果存放utf8汉字时,只能存放16个(每个汉字3字节)
mysql 5.0版本以上,varchar(50), 指的是50字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放50个。
drop table test_map_1;
create table test_map_1 as
select 1 as uid, map("key1", "value1","key2", "value2") as map1 union all
select 2 as uid, map("key3", "value3","key4", "value4") as map1;
--查看当前测试表结构是否是map<string,string>类型
hive> desc .
不是,MySQL中的varchar(200)中的200并不表示字节。它表示该字段可以存储的最大字符数。
在MySQL中,varchar类型是变长字符串类型,它可以存储0到最大指定长度的字符。因此,varchar(200)表示该字段可以存储最多200个字符,而不是200个字节。
需要注意的是,如果使用的字符集是多字节字符集(例如UTF-8),则实际存储的字节数可能会超过200字节,因为某些字符可能占用多个字节。因此,在选择varchar的长度时,需要根据存储的字符集和实际需求来确定合适的长度。