Mysql字符類型比較

1、 binary和char比較:mysql

  • binary 字節爲單位,char字符爲單位,字符佔幾個字節取決於字符集
  • binary  比較規則基於字節值,char基於字符,即便是_bin的比較規則
  • 範圍都0-255字節,char對於不一樣字符集,能夠存取的字節數不一樣
  • 排序和比較規則都會根據字符碼值,而不是詞典順序,若是採用binary那麼是區分大小寫的,和咱們經常使用的utf8_general_ci相沖突

相同特性,摘自官方文檔:git

Specifying the CHARACTER SET binary attribute for a character data type causes the columnsql

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;函數

如下兩種表定義是等義的:sqlserver

CREATE TABLE t測試

(ui

c1 VARCHAR(10) CHARACTER SET binary,this

c2 TEXT CHARACTER SET binary,編碼

c3 ENUM('a','b','c') CHARACTER SET binaryspa

);

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-9a-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()函數

2、 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存儲時會去掉尾部空格,若是該字段被定義成惟一建或主鍵,去除結尾空格後相同的字符串會違反惟一性約束

3、 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後相同的字符串會違反惟一性約束

相關文章
相關標籤/搜索