溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL中使用varbinary比varchar更合適嗎

發(fā)布時間:2021-11-18 15:51:35 來源:億速云 閱讀:460 作者:iii 欄目:MySQL數(shù)據(jù)庫

本篇內(nèi)容主要講解“MySQL中使用varbinary比varchar更合適嗎”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“MySQL中使用varbinary比varchar更合適嗎”吧!

一 前言
    在討論數(shù)據(jù)表字段設(shè)計的時候,有同學提出使用vabinary 代替 varchar ,部分開發(fā)不明所以,其實我也是。兩者之間具體有什么區(qū)別?使用vabinary 代替 varchar 對業(yè)務有何優(yōu)勢?
二 對比測試
2.1 測試環(huán)境
 數(shù)據(jù)庫版本 Percona Server 5.6.24-72.2-log

  1. create  table  vbinary

  2. (

  3.   id int primary key auto_increment ,

  4.   val varbinary(776) not null default ''

  5. ) engine=innodb default charset=utf8mb4;


  6. create  table  vachar

  7. (

  8.   id int primary key auto_increment ,

  9.   val varchar(12) not null default ''

  10. ) engine=innodb default charset=utf8mb4;

  11. insert into vbinary(val) values('abaa'),('aabb'),('bcdd'),('ccdd');

  12. insert into vachar(val) values('abaa'),('aabb'),('bcdd'),('ccdd')

2.2 定義
   varchar(N)   字符串類型,用于存儲變長字符串,使用表默認或者指定的校驗集合,其中N代表存儲字符的個數(shù),詳細信息請移步《淺談varchar(N)》.
   varbinary(N)二進制字符串類型,以二進制字節(jié)串存儲字符,無字符集校驗區(qū)別,均以二進制實際數(shù)值作比較。
2.3 長度定義
varchar存儲的是字符個數(shù),varbinary存儲的是字節(jié)個數(shù)。

  1. test [RW] 10:57:50 >insert into vbinary (val,name) value('2msdmlsdyo2enwlenw','disodmalsdsi');

  2. Query OK, 1 row affected, 1 warning (0.00 sec)

  3. test [RW] 10:57:55 >show  warnings;

  4. +---------+------+------------------------------------------+

  5. | Level | Code | Message |

  6. +---------+------+------------------------------------------+

  7. | Warning | 1265 | Data truncated for column 'val' at row 1 |

  8. +---------+------+------------------------------------------+

  9. 1 row in set (0.00 sec)

  10. test [RW] 10:58:11 >insert into vbinary (val,name) value('有贊是一家移動零售服務提供商','disodmalsdsi');

  11. Query OK, 1 row affected, 1 warning (0.01 sec)

  12. test [RW] 10:59:00 >show  warnings;

  13. +---------+------+------------------------------------------+

  14. | Level | Code | Message |

  15. +---------+------+------------------------------------------+

  16. | Warning | 1265 | Data truncated for column 'val' at row 1 |

  17. +---------+------+------------------------------------------+

  18. 1 row in set (0.00 sec)

  19. test [RW] 10:59:08 >select * from vbinary;

  20. +----+--------------+--------------+

  21. | id | val | name |

  22. +----+--------------+--------------+

  23. | 6 | 2msdmlsdyo2e | disodmalsdsi |

  24. | 7 | 有贊是一 | disodmalsdsi | #

  25. +----+--------------+--------------+

  26. 7 rows in set (0.00 sec)

  27. test [RW] 10:59:12 >insert into vachar(val,name) value('有贊是一家移動零售服務提供商','disodmalsdsi');

  28. Query OK, 1 row affected, 1 warning (0.00 sec)

  29. test [RW] 11:00:02 >show  warnings;

  30. +---------+------+------------------------------------------+

  31. | Level | Code | Message |

  32. +---------+------+------------------------------------------+

  33. | Warning | 1265 | Data truncated for column 'val' at row 1 |

  34. +---------+------+------------------------------------------+

  35. 1 row in set (0.00 sec)

  36. test [RW] 11:00:06 >select * from vachar;

  37. +----+--------------------------------------+--------------+

  38. | id | val | name |

  39. +----+--------------------------------------+--------------+

  40. | 4 | ccdd | yz |

  41. | 5 | 有贊是一家移動零售服務提 | disodmalsdsi |

  42. +----+--------------------------------------+--------------+

  43. 5 rows in set (0.00 sec)

分析:
varbinary(N)中長度N指的是字節(jié)串的長度,一個數(shù)字/英文字母占用1個字節(jié),一個漢字占用3個字節(jié)(默認utf8、utf8mb4字符集),指定N 則可以存儲 N 個數(shù)字或者字母,N/3個漢字。
varchar(N)中長度N指的是字符串的長度,一個數(shù)字/英文字母/漢字占用一個字符,指定N 可以存儲N個字符。
注意兩種存儲類型支持的字段長度計算方式的不同,會給開發(fā)帶來一定的困擾,使用varbinary的開發(fā)需要深入了解該字段的存儲單位,設(shè)計字段的時候還要根據(jù)業(yè)務邏輯計算好N的值是多少。否則可能會被截斷 ,在sql_mode為嚴格模式時則會報錯。
2.4 索引功能
分別對name字段創(chuàng)建索引

  1. test [RW] 10:47:01 >alter table  vbinary add name varbinary(255) not null default 'yz';

  2. Query OK, 0 rows affected (0.02 sec)

  3. Records: 0  Duplicates: 0  Warnings: 0

  4. test [RW] 10:47:24 >alter table  vbinary add key idx_name(name);

  5. Query OK, 0 rows affected (0.01 sec)

  6. Records: 0  Duplicates: 0  Warnings: 0

  7. test [RW] 10:48:25 >rename table  vchar  to vachar;

  8. Query OK, 0 rows affected (0.01 sec)

  9. test [RW] 10:49:00 >alter  table vachar add name varchar(255) not null default 'yz';

  10. Query OK, 0 rows affected (0.02 sec)

  11. Records: 0  Duplicates: 0  Warnings: 0

  12. test [RW] 10:49:31 >alter table vachar add key idx_name(name);

  13. Query OK, 0 rows affected, 1 warning (0.02 sec)

  14. Records: 0  Duplicates: 0  Warnings: 1

  15. test [RW] 10:49:53 >show  Warnings;

  16. +---------+------+---------------------------------------------------------+

  17. | Level | Code | Message |

  18. +---------+------+---------------------------------------------------------+

  19. | Warning | 1071 | Specified key was too long; max key length is 767 bytes |

  20. +---------+------+---------------------------------------------------------+

  21. 1 row in set (0.00 sec)

  22. test [RW] 10:50:06 >show create table vachar   \G

  23. *************************** 1. row ***************************

  24.        Table: vachar

  25. Create Table: CREATE TABLE `vachar` (

  26.   `id` int(11) NOT NULL AUTO_INCREMENT,

  27.   `val` varchar(12) NOT NULL DEFAULT '',

  28.   `name` varchar(255) NOT NULL DEFAULT 'yz',

  29.   PRIMARY KEY (`id`),

  30.   KEY `idx_name` (`name`(191))

  31. ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4

  32. 1 row in set (0.00 sec)

  33. test [RW] 10:50:19 >show create table vbinary  \G

  34. *************************** 1. row ***************************

  35.        Table: vbinary

  36. Create Table: CREATE TABLE `vbinary` (

  37.   `id` int(11) NOT NULL AUTO_INCREMENT,

  38.   `val` varbinary(12) NOT NULL DEFAULT '',

  39.   `name` varbinary(255) NOT NULL DEFAULT 'yz',

  40.   PRIMARY KEY (`id`),

  41.   KEY `idx_name` (`name`)

  42. ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4

  43. 1 row in set (0.00 sec)

  44. test [RW] 11:53:08 >create  table  vbinary1

  45.     -> (

  46.     -> id int primary key auto_increment ,

  47.     -> val varbinary(776) not null default ''

  48.     -> ) engine=innodb default charset=utf8mb4;

  49. Query OK, 0 rows affected (0.01 sec)

  50. test [RW] 11:53:09 >alter table vbinary1 add key idx_val(val);

  51. Query OK, 0 rows affected, 1 warning (0.02 sec)

  52. Records: 0  Duplicates: 0  Warnings: 1

  53. test [RW] 11:53:37 >show  Warnings;

  54. +---------+------+---------------------------------------------------------+

  55. | Level | Code | Message |

  56. +---------+------+---------------------------------------------------------+

  57. | Warning | 1071 | Specified key was too long; max key length is 767 bytes |

  58. +---------+------+---------------------------------------------------------+

  59. 1 row in set (0.00 sec)

  60. test [RW] 11:53:44 >show create table vbinary1  \G

  61. *************************** 1. row ***************************

  62.        Table: vbinary1

  63. Create Table: CREATE TABLE `vbinary1` (

  64.   `id` int(11) NOT NULL AUTO_INCREMENT,

  65.   `val` varbinary(776) NOT NULL DEFAULT '',

  66.   PRIMARY KEY (`id`),

  67.   KEY `idx_val` (`val`(767)) ## 被修改為 767 ,索引支持的最大字節(jié)數(shù)。

  68. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

  69. 1 row in set (0.00 sec)

分析:
  基于 varbinary和 varchar 存儲字符的長度定義不同,varchar 可以存儲字符串前191個字符的索引,varbinary 字段的索引則最多可以存儲767字節(jié)。如果是英文字母則可以存儲更長的字符串。
2.5 校驗方面

  1. test [RW] 12:15:06 >select * from vachar where val='ABAA';

  2. +----+------+------+

  3. | id | val | name |

  4. +----+------+------+

  5. | 1 | abaa | yz |

  6. +----+------+------+

  7. 1 row in set (0.00 sec)

  8. test [RW] 12:14:31 >select * from vbinary where val='ABAA';

  9. Empty set (0.00 sec)

  10. test [RW] 12:15:11 >select * from vbinary  where  val='abaa';

  11. +----+------+------+

  12. | id | val | name |

  13. +----+------+------+

  14. | 1 | abaa | yz |

  15. +----+------+------+

  16. 1 row in set (0.00 sec)

分析:
varbinary存儲的是二進制字節(jié)串而不是字符串,這意味著它沒有字符集校驗的概念,排序和比較都是基于字節(jié)中的實際數(shù)值大小進行的。varchar類型存儲的列在比較的時候是通過字符集的方式進行的,varchar 中'ABAA'和'abaa'是一致的.
2.6 性能測試
使用mysqlslap 進行10個并發(fā)100w次查詢做對比

  1. [root@rac4 00:31:35 ~]

  2. # time mysqlslap --no-defaults -uroot --create-schema=test -S /srv/my3306/run/mysql.sock --number-of-queries=1000000 --concurrency=10 --query="select * from vbinary where  val='abaa';"

  3. Benchmark

  4.   Average number of seconds to run all queries: 30.569 seconds

  5.   Minimum number of seconds to run all queries: 30.569 seconds

  6.   Maximum number of seconds to run all queries: 30.569 seconds

  7.   Number of clients running queries: 10

  8.   Average number of queries per client: 100000

  9. real  0m30.574s

  10. user  0m8.124s

  11. sys 0m6.286s

  12. [root@rac4 00:32:18 ~]

  13. # time mysqlslap --no-defaults -uroot --create-schema=test -S /srv/my3306/run/mysql.sock --number-of-queries=1000000 --concurrency=10 --query="select * from vachar where  val='abaa';"

  14. Benchmark

  15.   Average number of seconds to run all queries: 31.986 seconds

  16.   Minimum number of seconds to run all queries: 31.986 seconds

  17.   Maximum number of seconds to run all queries: 31.986 seconds

  18.   Number of clients running queries: 10

  19.   Average number of queries per client: 100000

  20. real  0m31.991s

  21. user  0m8.351s

  22. sys   0m6.407s

分析
簡單的select查詢對比來看
varbinary  30.569s
varchar    31.986s
varbinary 相對性能有 1.4s 約4%的性能提升,在壓測環(huán)境下每秒幾乎3wqps,如果是普通的業(yè)務場景1000-2000左右的qps,varbinary帶來的性能可以忽略不計.

到此,相信大家對“MySQL中使用varbinary比varchar更合適嗎”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI