【MYSQL】業務上碰到的SQL問題整理集合

前言

身爲一名前端工程師, 對於 SQL瞭解程度並非很深入, 盤點一些我的工做遇到的問題,給你們普及下知識, 以及記錄本身如何解決這些問題的.

導航

SELECT 查詢語句不區分字母大小寫?

相信這是一個很是常見的問題了, 而這個問題的緣由主要仍是表字符集引發的.html

假設存在config表結構:前端

Field Type Allow Null Default Value
key varchar(255) No
value varchar(255) No
id int(11) No

表內數據以下:mysql

key value id
VERSION 1.0.1 1
version 2.0.1 2

執行語句爲:android

SELECT `key`,`value` FROM config WHERE `key` = 'version' LIMIT 1;

期待結果:ios

key value
version 2.0.1

執行結果:sql

key value
VERSION 1.0.1

爲何會有這種現象?
mysql 默認對字符匹配排序大小寫不敏感, 字段包括 varchar, char, text 內容. 若是要確實要區分大小寫, 則在建表或者查表的時候使用 BINARY 屬性. 二進制的 Aa 仍是有區別的 ~~數據庫

解決方案1 : 修改sql語句bash

SELECT `key`,`value` FROM config WHERE `key` = binary('version') LIMIT 1;

或者

SELECT `key`,`value` FROM config WHERE binary `key` = 'version' LIMIT 1;

解決方案2 : 修改表結構前端工程師

建表語句app

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
email 295697141@qq.com 1
username 2

SQL語句:

SELECT `key`, `value` FROM `config` WHERE `key` IN ('username', 'email');

執行結果:

key value
email 295697141@qq.com
username

明明是username 優先於 email, 結果倒是 email優先於 username. 緣由在於 IN 查詢只負責查詢, 不負責排序, 而默認排序是用 id asc, 因此獲得了一個不符合IN查詢的結果

解決方案

  1. 使用 ORDER BY FIELD()
  2. 使用 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
email 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

SELECT LOCATE 與 LIKE 區別使用

一樣再使用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

LIKE語句

若是咱們想要查詢以apph5 開頭的命名空間的全部配置項, 可使用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
email 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的問題, 會不斷更新...

歡迎你們收藏和點贊!!!

相關文章
相關標籤/搜索