首頁  >  問答  >  主體

mysql 数据库中varchar的长度与字节,字符串的关系

经常看到别人设置varchar的长度是255,它可以存储多少个汉字。在phpmyadmin中看到varchar的定义是变长(0-65535),它的最大长度到底是255还是65535,是不是可以设置成varchar(60000)?还有长度和字节的关系,如上设置,它的长度就是60000,可以存储60000个字节,这样理解对吗?

伊谢尔伦伊谢尔伦2743 天前787

全部回覆(4)我來回復

  • 黄舟

    黄舟2017-04-17 13:10:17

    CREATE TABLE `test` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `content` varchar(5) NOT NULL DEFAULT '',
        PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
    INSERT INTO `test`(`content`) VALUES ('123456');
    INSERT INTO `test`(`content`) VALUES ('中国人民银行');
    SELECT * FROM `test`;
    返回:
    id  content
    1   12345
    2   中国人民银
    

    可見,varchar(5)能儲存5個字元,不管是數字,字母,還是漢字.

    CREATE TABLE `test2` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `content` varchar(21842) NOT NULL DEFAULT '',
        PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
    

    該表中varchar類型的字段能容納的最大字元數21842是怎麼得來的?
    21842 = (65535-1-2-4)/3
    MySQL要求一個行的定義長度不能超過65535(包含多個欄位),所以有65535.
    varchar的最大有效長度取決於最大行大小.
    減1的原因是實際行的儲存從第2個位元組開始.
    減2的原因是varchar頭部的2個位元組表示長度.
    減4的原因是字段id的int型別佔用4個位元組.
    除以3的原因是一個utf8字元佔用3個位元組.

    如果你在test2表裡把varchar(21842)改為varchar(21844),那麼就會報以下錯誤:
    1118 - 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中char,varchar與text類型的選用:
    知道固定長度的用char,例如MD5串固定是32位.
    經常變化的欄位用varchar.
    超過255字符的只能用varchar或text,不能用char.
    能用varchar的地方不用text.

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 13:10:17

    MySQL 的字元大小和字元集有關,如果字元集是 ascii,則保存不了中文(會顯示成亂碼),如果是 UTF8,每個字元是1-3個位元組。

    用事實說話

    試驗用的 MySQL 5.6

    先檢查資料庫字元集

    sqlshow variables like '%char%';
    

    結果:UTF8

    Variable_name Value
    character_set_client utf8mb4
    character_set_connection utf8mb4
    character_set_database utf8
    character_set_filesystem binary
    character_set_results utf8mb4
    character_set_server utf8
    character_set_system utf8
    character_sets_dir D:Program FilesMySQLMySQL Server 5.6sharecharsets

    建立表格(注意:varchar(10)

    sqlCREATE TABLE `test_char` (
        `s` VARCHAR(10) NULL DEFAULT NULL
    )
    

    插入資料

    十字ASCII字符,正確執行

    sqlinsert into test_char
    (s)
    values
    ('0123456789')
    ;
    

    十個中文字符,正確執行

    sqlinsert into test_char
    (s)
    values
    ('一二三四五六七八九十')
    ;
    

    但是十一個ASCII或中文都是報錯,說資料太長。

    結論

    長度是目前字元集的字元長度,而不是位元組長度!

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 13:10:17

    varchar(6000)是可以儲存6000個字節,如果字元集採用UTF-8的話,由於UTF-8是一種“可變長編碼”,英文字母被編成一個字節,漢字通常是3個字節,只有極其生僻的字才會被編碼成4-6個位元組。因此可認為編碼是UTF-8時varchar(6000)裡可以儲存2000個漢字

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 13:10:17

    varchar和char的長度並不是指字節長度,而是當前字符集下,最多多少個字符,比如,varchar 100,存ascii字符,最多存儲100個,存中文也是最多存100個,而不是33個。

    回覆
    0
  • 取消回覆