mysql dcn_Mysql varchar(max)
設計數據庫時,不禁有這樣的疑問,varchar()最大可以設置多大呢?與什么有關呢?
字符集
為什么要有字符集?
簡單講,數據在網絡上傳輸與硬盤中儲存,都是以二進制的形式存在的。我們熟知的文字、圖片以及視頻想要存儲與傳輸,必然需要一套規則,使其成為可以被儲存和傳輸的二進制數據,而字符集則是文字編解碼的規則。
詳情可參考字符編碼的歷史演變。
在數據的儲存上,mysql提供了不同的字符集支持。
查看mysql支持的字符集:
mysql> show character set;
+----------+---------------------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+---------------------------------+---------------------+--------+
| armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 |
| ascii | US ASCII | ascii_general_ci | 1 |
...
| gb18030 | China National Standard GB18030 | gb18030_chinese_ci | 4 |
| gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 |
| gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 |
| utf16 | UTF-16 Unicode | utf16_general_ci | 4 |
| utf16le | UTF-16LE Unicode | utf16le_general_ci | 4 |
| utf32 | UTF-32 Unicode | utf32_general_ci | 4 |
| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_0900_ai_ci | 4 |
+----------+---------------------------------+---------------------+--------+
41 rows in set (0.01 sec)
Mysql 提供了server、database、table、column級字符集設置。
字符集規則是可以繼承的,也就是說:
column 沒有設置則繼承 table 的字符集設置。
table 沒有設置則繼承 database 的字符集設置。
database 沒有設置則繼承 server 的字符集設置。
查看全局字符集設置:
mysql> show global variables like'%character_set%';
+--------------------------+--------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
8 rows in set (0.01 sec)
note:字符集設置不當會出現漢字亂碼。
char與varchar
char:固定長度類型,char(n)則表示只能儲存n字節數據,不足n則在末尾填充空格,最大存儲255字符。占用儲存空間n × 字符集最大占用字節。
varchar:可變長度類型,varchar(n)則表示可存儲char_length(n)長度的字符,儲存空間占用(字符集最大占用 × n + 1 or 2長度字節),字節數 > 255 時用2字節表示長度。
length() 與 char_length()
char_length():返回字符長度,與空間占用大小無關
mysql> select char_length('a'),char_length('1'),char_length('hello world'),char_length('你好');
+------------------+------------------+----------------------------+-----------------------+
| char_length('a') | char_length('1') | char_length('hello world') | char_length('你好') |
+------------------+------------------+----------------------------+-----------------------+
| 1 | 1 | 11 | 2 |
+------------------+------------------+----------------------------+-----------------------+
1 row in set (0.00 sec)
length(): 返回占用字節數
mysql> select length('a'),length('1'),length('hello world'),length('我'),length("你好"),length('🤤');
+-------------+-------------+-----------------------+---------------+------------------+-------------+
| length('a') | length('1') | length('hello world') | length('我') | length("你好") | length('?') |
+-------------+-------------+-----------------------+---------------+------------------+-------------+
| 1 | 1 | 11 | 3 | 6 | 4 |
+-------------+-------------+-----------------------+---------------+------------------+-------------+
1 row in set (0.00 sec)
utf8mb4是mysql在5.5之后新增的字符集編碼mb4就是most bytes 4的意思,可編碼4字節字符。所以utf8不支持emoji在utf8mb4解決了。
不同的字符集的空間占用。
創建一個字符集為utf8mb4的表
mysql> create table test_utf8mb4 (cu varchar(10), dcu varchar(10),cn varchar(10),dcn varchar(10),smy varchar(10)) charset=utf8mb4;
Query OK, 0 rows affected (0.02 sec)
// 插入一條數據
mysql> insert into test_utf8mb4 (`cu`,`dcu`,`cn`,`dcn`,`smy`) values ('a','hello','你',"你好",'🤤');
Query OK, 1 row affected (0.00 sec)
mysql> select length(cu),length(dcu),length(cn),length(dcn),length(smy) from test_utf8mb4;
+------------+-------------+------------+-------------+-------------+
| length(cu) | length(dcu) | length(cn) | length(dcn) | length(smy) |
+------------+-------------+------------+-------------+-------------+
| 1 | 5 | 3 | 6 | 4 |
+------------+-------------+------------+-------------+-------------+
1 row in set (0.00 sec)
在utf8mb4字符集中,英文數字占1個字節,中文占用3個字節,emoji占用4字節。
創建一個字符集為gbk的表
mysql> create table test_gbk (cu varchar(10), dcu varchar(10),cn varchar(10),dcn varchar(10),smy varchar(10)) charset=gbk;
Query OK, 0 rows affected (0.02 sec)
// 插入一條數據
mysql> insert into test_gbk (`cu`,`dcu`,`cn`,`dcn`,`smy`) values ('a','hello','你',"你好",'🤤');
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\xA4\xA4' for column 'smy' at row 1
// emoji是一個不正確的值,可以看到smy是一個4字節字符。
mysql> insert into test_gbk (`cu`,`dcu`,`cn`,`dcn`) values ('a','hello','你',"你好");
Query OK, 1 row affected (0.00 sec)
mysql> select length(cu),length(dcu),length(cn),length(dcn),length(smy) from test_gbk;
+------------+-------------+------------+-------------+-------------+
| length(cu) | length(dcu) | length(cn) | length(dcn) | length(smy) |
+------------+-------------+------------+-------------+-------------+
| 1 | 5 | 2 | 4 | NULL |
+------------+-------------+------------+-------------+-------------+
1 row in set (0.00 sec)
gbk的字符集中,英文數字占1字節,中文占2字節,且只能保存2字節及以下字符。
在mysql中,char(n) or varchar(n)中的n代表的是可插入的字符長度,非字節空間。
既然n指的是字符長度,char(n)最大255,那么varchar(n)最大可以設置為多少呢?
行大小限制
在mysql中,mysql有65535字節的最大行大小限制。也就是說,所有字段占用的空間都被包含在65535字節中。
新建一個varchar(65535)的表
mysql> create table long_var (v varchar(65535) not null);
ERROR 1074 (42000): Column length too big for column 'v' (max = 16383); use BLOB or TEXT instead
// 報錯,提示最大值為16383
16383 * 4 = 65532,還有3字節空間呢?
這樣看起來并不直觀,utf8mb4占用4字節空間,不如用latin1代替,latin1只占用一字節。
mysql> create table long_var (v varchar(65535)) charset=latin1;
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
// 失敗,提示最大行大小為65535。
// 對了,varchar()還有2個字節的長度標識位。
mysql> create table long_var (v varchar(65533)) charset=latin1;
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
// 65533 還報錯?
mysql> create table long_var (v varchar(65533) not null) charset=latin1;
Query OK, 0 rows affected (0.02 sec)
// 同樣65533成功了,接下來就是找不同的時間了。
第二條語句多了一條not null 的語句,在mysql中行大小除了數據列長度,還包括可空標識,即NULL標識。
如果有一個列允許為空,則需要1 bit來標識,每8 bits的標識會組成一個字段,該字段會存放在每行最開始的位置??煽毡硎臼切袃裙蚕淼摹?/p>
那么,新建一個可空列的表,字段長讀應設置為65535 - 2字節長度 - 1字節null標識 = 65532;
mysql> create table long_var_32 (v varchar(65532)) charset=latin1;
Query OK, 0 rows affected (0.02 sec)
varchar()的最大長度,受字符集限制,且行內共65535字節的大小,也就是說varchar(65532)只能有一個。
總結
以上是生活随笔為你收集整理的mysql dcn_Mysql varchar(max)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 惠威SWAN AW-75怎么样 惠威真无
- 下一篇: 铁路12306app怎么看退票记录? 铁