摘要:不會進行全表掃描函數是一種查詢匹配字符串出現次數的函數執行語句執行結果經過相關資料的學習最終認為的效率與的效率是無法對比誰快誰慢,相關文章推薦閱讀查詢結果中文亂碼原因主要是的編碼字符集與數據庫的字符集不一致導致的。
前言
身為一名前端工程師, 對于 SQL了解程度并不是很深刻, 盤點一些個人工作遇到的問題,給大家普及下知識, 以及記錄自己如何解決這些問題的.導航
SELECT 語句不區分大小寫?
SELECT IN 語句順序不符合傳入時要求?
SELECT 存儲查詢生僻漢字, 結果亂碼?
SELECT LOCATE 與 LIKE 區別使用
SELECT 查詢結果中文亂碼?
SHOW 查詢表字段的詳細描述?
SELECT 查詢語句不區分字母大小寫?相信這是一個非常常見的問題了, 而這個問題的原因主要還是表字符集引起的.
假設存在config表結構:
Field | Type | Allow Null | Default Value |
---|---|---|---|
key | varchar(255) | No | |
value | varchar(255) | No | |
id | int(11) | No |
表內數據如下:
key | value | id |
---|---|---|
VERSION | 1.0.1 | 1 |
version | 2.0.1 | 2 |
執行語句為:
SELECT `key`,`value` FROM config WHERE `key` = "version" LIMIT 1;
期待結果:
key | value |
---|---|
version | 2.0.1 |
執行結果:
key | value |
---|---|
VERSION | 1.0.1 |
為什么會有這種現象?
mysql 默認對字符匹配排序大小寫不敏感, 字段包括 varchar, char, text 內容. 如果要確實要區分大小寫, 則在建表或者查表的時候使用 BINARY 屬性. 二進制的 A 與 a 還是有區別的 ~~
解決方案1 : 修改sql語句
SELECT `key`,`value` FROM config WHERE `key` = binary("version") LIMIT 1; 或者 SELECT `key`,`value` FROM config WHERE binary `key` = "version" LIMIT 1;
解決方案2 : 修改表結構
建表語句
CREATE TABLE `config` ( `key` BINARY varchar(255) NOT NULL, `value` BINARY varchar(255) DEFAULT NULL, `id` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
修改表語句
ALTER TABLE `config` MODIFY COLUMN `key` varchar(255) BINARY NOT NULL;SELECT IN 語句順序不符合傳入時要求?
以config表為例, 表內數據:
key | value | id |
---|---|---|
295697141@qq.com | 1 | |
username | 我 | 2 |
SQL語句:
SELECT `key`, `value` FROM `config` WHERE `key` IN ("username", "email");
執行結果:
key | value |
---|---|
295697141@qq.com | |
username | 我 |
明明是username 優先于 email, 結果卻是 email優先于 username. 原因在于 IN 查詢只負責查詢, 不負責排序, 而默認排序是用 id asc, 所以得到了一個不符合IN查詢的結果
解決方案
使用 ORDER BY FIELD()
使用 ORDER BY FIND_IN_SET()
SELECT `key`, `value` FROM `config` WHERE `key` IN ("username", "email") ORDER BY FIELD("key","username", "email"); 或者 SELECT `key`, `value` FROM `config` WHERE `key` IN ("username", "email") ORDER BY FIND_IN_SET(`key`,"username,email");
最終執行結果:
key | value |
---|---|
username | 我 |
295697141@qq.com |
注意: FIND_IN_SET 第二個參數 strlist 逗號之間不需要空格
SELECT 存儲查詢生僻漢字, 結果亂碼 ?前提,數據庫和表都是采用的是utf8字符集.
生僻字比如: ?
INSERT INTO `config` (`key`,`value`,`id`) VALUES ("word", "?", 7);
查詢SQL:
SELECT * FROM `config` WHERE `key` = "word" LIMIT 1;
執行結果:
value | key | id |
---|---|---|
word | ???? | 7 |
出現了???? 這種情況,難道說 utf8字符集沒有記錄這個生僻字么?
mysql 支持的 utf8 編碼最大字符長度為 3 字節,如果遇到 4 字節的寬字符就會插入異常了。三個字節的 UTF-8 最大能編碼的 Unicode 字符是 0xffff,也就是 Unicode 中的基本多文種平面(BMP)。也就是說,任何不在基本多文本平面的 Unicode字符,都無法使用 Mysql 的 utf8 字符集存儲。包括 Emoji 表情(Emoji 是一種特殊的 Unicode 編碼,常見于 ios 和 android 手機上),和很多不常用的漢字,以及任何新增的 Unicode 字符等等。
引用一段 關于 MySQL UTF8 編碼下生僻字符插入失敗/假死問題的分析 內容
解決方案:
修改字符集
--修改數據庫字符集 ALTER DATABASE test CHARACTER SET = utf8mb4; --修改表字符集 alter table `config` convert to character set utf8mb4; --修改字符字符集 ALTER TABLE `config` CHANGE COLUMN `value` `value` varchar(12) CHARACTER SET utf8mb4;
最終執行sql
- 設置連接 socket 使用字符集 SET NAMES utf8mb4; - 修改表字段字符集 ALTER TABLE `config` CHANGE COLUMN `value` `value` varchar(12) CHARACTER SET utf8mb4; - 更新值 UPDATE `config` SET `value` = "?" WHERE `key` = "word"; - 查詢 SELECT * FROM `config` WHERE `key` = "word";
執行結果
key | value | id |
---|---|---|
word | ? | 7 |
同樣再使用config表舉一個例子, 假如有以下的行數據:
key | value | id |
---|---|---|
app.version | 1.0.0 | 8 |
h5.version | 1.0.1 | 9 |
app.email | test@gmail.com | 10 |
h5.email | test@outlook.com | 11 |
如果我們想要查詢以app 或 h5 開頭的命名空間的所有配置項, 可以使用LIKE語句
SELECT `key`, `value` FROM `config` WHERE `key` LIKE "h5.%";
執行結果:
key | value |
---|---|
h5.version | 1.0.1 |
h5.email | test@outlook.com |
如果想去掉h5命名空間前綴, 可以使用 substring 函數
SELECT substring(`key`, length("h5.") + 1), `value` FROM `config` WHERE `key` LIKE "h5.%";
執行結果:
key | value |
---|---|
version | 1.0.1 |
test@outlook.com |
LIKE 在字符串全匹配,以及前置查詢如 h5.%的時候, 如果存在索引會有一定的優化作用。不會進行全表掃描
LOCATE 函數LOCATE是一種查詢匹配字符串出現次數的函數
執行語句:
SELECT `key`, `value` FROM `config` WHERE LOCATE("app",`key`) > 0;
執行結果:
key | value |
---|---|
app.version | 1.0.0 |
app.email | test@gmail.com |
經過相關資料的學習, 最終認為LIKE的效率與LOCATE的效率是無法對比誰快誰慢,相關文章推薦閱讀 MySQL LIKE vs LOCATE
SELECT 查詢結果中文亂碼?原因:主要是 mysql client 的編碼字符集與數據庫的字符集不一致導致的。
查看字符集方式
mysql> show variables like "%char%"; +--------------------------+----------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/charsets/ | +--------------------------+----------------------------------+
解決方案
1. 修改字符集
mysql> set charset utf8; mysql> show variables like "%char%"; +--------------------------+----------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/charsets/ | +--------------------------+----------------------------------+
2. 直接在client連接時指定字符集
mysql --default-character-set=utf8-h 127.0.0.1 -uroot -p123456 -P3306 -D test查詢表字段的詳細描述?
查看表的字段描述主要有以下兩種方式
desc table_name;
show full columns/fields from table_name;
1.查看簡單的表字段描述
mysql> desc table_name; +-----------------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------------------+------------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | +-----------------------+------------------+------+-----+---------+----------------+
2.查看具體的表字段信息
mysql> show full fields from table_name; +-----------------------+------------------+--------------------+------+-----+---------+----------------+----------------------+------------------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +-----------------------+------------------+--------------------+------+-----+---------+----------------+----------------------+------------------+ | id | bigint(20) | NULL | NO | PRI | NULL | auto_increment | select,insert,update | 自增主鍵 | +-----------------------+------------------+--------------------+------+-----+---------+----------------+----------------------+------------------+總結
mysql, sql 里面的知識確實讓人感覺深奧. 此時此刻我只是解決了我遇到問題, 一會也會遇到更多不一樣的問題, 而這也是學習sql, 計算機的魅力. 以后遇到更多的關于SQL的問題, 會不斷更新...
歡迎大家收藏和點贊!??!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/17652.html
摘要:用戶態不能干擾內核態所以指令就有兩種特權指令和非特權指令不同的狀態對應不同的指令。非特權指令所有程序均可直接使用。用戶態常態目態執行非特權指令。 這是我今年從三月份開始,主要的大廠面試經過,有些企業面試的還沒來得及整理,可能有些沒有帶答案就發出來了,還請各位先思考如果是你怎么回答面試官?這篇文章會持續更新,請各位持續關注,希望對你有所幫助! 面試清單 平安產險 飛豬 上汽大通 浩鯨科...
閱讀 2774·2021-11-23 09:51
閱讀 3533·2021-10-08 10:17
閱讀 1264·2021-10-08 10:05
閱讀 1317·2021-09-28 09:36
閱讀 1836·2021-09-13 10:30
閱讀 2182·2021-08-17 10:12
閱讀 1674·2019-08-30 15:54
閱讀 2007·2019-08-30 15:53