常見MySQL隱式型別轉換

2021-10-25 10:11:18 字數 3964 閱讀 9744

前言

今天我們繼續回到mysql系列文章中,談一談mysql中隱式型別轉換。(其實我最早知道是在慢sql優化中知道隱式型別轉換概念的),在說隱式型別轉換之前,首先我們通過乙個例項來看看是怎麼回事。

資料結構

本文中所有的操作,都是基於該資料結構(有興趣的童鞋,可以實驗):

create table t_base_user(   

oid bigint(20) not null primary key auto_increment,  

name varchar(30) null comment "name",  

email varchar(30) null comment "email",  

age int null comment "age",  

telephone varchar(30) null comment "telephone",  

status tinyint(4) null comment "0 無效 1 有效",  

created_at datetime null default now() comment "建立時間",  

updated_at datetime null default now() comment "修改時間"  )

### 新建索引alter table t_base_user add index idx_email(email);

alter table t_base_user add index idx_name(name);

alter table t_base_user add index idx_telephone(telephone);

### 新增記錄:

insert into `andyqian`.`t_base_user` (`name`, `email`, `age`, `telephone`, `status`, `created_at`, `updated_at`)

values ('111111', '[email protected]', '111', '12345678901', '1', now(),now());

引子

首先我們基於上述資料結構中,我們來看看下面這個執行計畫:

explain select * from t_base_user where telephone=12345678901;

執行計畫結果:

細心的童鞋應該已經看出來了,為什麼資料結構中已經在telephone欄位上新建了idx_telephone索引,而上述語句並沒有走索引,而是全表掃瞄。這是為什麼呢?帶著這疑問,我們來看看今天的主角------mysql隱式型別轉換

什麼是隱式型別轉換?

在mysql中:

當操作符與不同型別的運算元一起使用時,會發生型別轉換以使運算元相容。則會發生轉換隱式

也就是說,mysql會根據需要自動將數字轉換為字串,將字串轉換數字。看到這個概念之後,是不是有一種茅塞頓開的感覺。哦... 原來在資料結構中telephone欄位為字串(varchar)型別,而我們傳的手機號是數字型別。現在我們將sql修改下:

select * from t_base_user where telephone='12345678901';

再看看上述語句的執行計畫:

explain select * from t_base_user where telephone='12345678901';

結果:

從這裡看,現在語句已經走索引了。為了加深我們對隱式型別轉換的印象,我們再多看看幾個隱式型別轉換案例:

案例一: 字串轉換為數字

mysql > select 1+'1';

結果:

mysql > 2

案例二: 數字轉換為字串

mysql -> select concat(1024,' andyqian');

結果:

'1024,' andyqian';

此時concat(字元拼接)函式就將1024進行了隱式型別轉換。

如何避免隱式型別轉換?

只有當清楚的知道隱式型別轉換的規則,才能從根本上避免產生隱式型別轉換。mysql也在官網描述了進行隱式型別轉換的一些規則如下:

1. 隱式型別轉換規則:

2. 使用cast函式顯示轉換

我們可以使用cast顯示的將型別進行轉換,如下所示:

mysql> select 38.8, cast(38.8 as char);

結果:

mysql > 38.8, '38.8'

如上述中:

select * from t_base_user where telephone=cast(12345678901 as char);

檢視執行計畫,我們也可以看出 

你看,這個時候也走索引了。

3. 型別一致

這裡說的型別一致,指的是在寫sql時,引數型別一定要與資料庫中的型別一致,避免產生隱式型別轉換,就如剛才在文首時,如果多檢查,寫的sql的引數型別與資料庫中欄位型別一致,也就不會不走索引了,你說是不是?

小心隱式型別轉換

這裡再重申一次,寫sql時一定要檢查引數型別與資料庫字段型別一致,(如果引數不一致,也要使用cast函式顯示轉換成一致)否則造成隱式型別轉換,不走索引,後果簡直不堪設想, 在前面《寫會mysql索引》這篇文章中提到過,不走索引,輕則造成慢查詢,重則造成資料庫伺服器cpu100%。唉,說到這裡,不瞞你說,我就吃過不少mysql隱式型別轉換的虧 ! (如慢查詢) !

小結看到這裡,是不是有一種,資料表設計還真不是件容易的事情。需要考慮的因素太多太多了,需要考慮字段型別,索引設計,還有各種約束條件等等。也一定要謹慎謹慎再謹慎!其實換個角度就更容易理解了,大家都知道高樓大廈都是需要乙個好的地基的,在資料庫表設計中,前期的表結構設計就是這個地基,其重要性可想而知。

今天的命令是:

show full columns from table_name;

作用: 顯示指定表所有列資訊

例如:

show full columns from t_base_user;

返回結果如下圖所示:

其中:field: 欄位名

type: 該欄位型別

collation: 描述了如何對查詢出來的資料進行比較和排序

null: 是否允許為空, no: 不允許,yes 允許

key: 鍵,例如: 主鍵(pri), 唯一鍵(uni) 等

default: 該欄位預設值 extra: 附加資訊如自增主鍵上的(auto_increment)

privileges: 許可權,有select,update等

comment: 字段注釋

注意: 通過該命令顯示都是建表時的資訊,這裡著重強調一下,在資料庫建表時,在每個欄位上, 一定要加注釋,加注釋,加注釋!

mysql 隱式轉換 談談MySQL隱式型別轉換

前言今天我們繼續回到mysql系列文章中,談一談mysql中隱式型別轉換。其實我最早知道是在慢sql優化中知道隱式型別轉換概念的 在說隱式型別轉換之前,首先我們通過乙個例項來看看是怎麼回事。資料結構 本文中所有的操作,都是基於該資料結構 有興趣的童鞋,可以實驗 create table t base...

MYSQL隱式型別轉換

今天看了下團隊發的xctf高校戰疫的wp,這裡先喊一句。楊大樹師傅太強了orz 幾乎沒幫啥忙,簡單的題目都被師傅們秒了,我進度太慢,跟不上,後面難的題目基本動不了。再喊一遍,星盟的師傅tql。再接再厲,希望下次能上師傅們,幫到師傅們解題。這裡本地搭建一下環境 用的老的語句 php7比較高的環境用新的...

MYSQL隱式型別轉換

mysql隱式型別轉換 關於官方文件中的理解大致是 如果兩個引數比較,有至少乙個null,結果就是null,除了是用null null 會返回1。不做型別轉換 兩個引數都是字串,按照字串比較。不做型別轉換 兩個引數都是整數,按照整數比較。不做型別轉換 如果不與數字進行比較,則將十六進製制值視為二進位...