欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

談?wù)凪ySQL中的隱式轉(zhuǎn)換

 更新時(shí)間:2020年10月27日 14:42:13   作者:yangyidba  
這篇文章主要介紹了MySQL中的隱式轉(zhuǎn)換的相關(guān)資料,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫(kù),感興趣的朋友可以了解下

工作過(guò)程中會(huì)遇到比較多關(guān)于隱式轉(zhuǎn)換的案例,隱式轉(zhuǎn)換除了會(huì)導(dǎo)致慢查詢(xún),還會(huì)導(dǎo)致數(shù)據(jù)不準(zhǔn)。本文通過(guò)幾個(gè)生產(chǎn)中遇到的案例來(lái)。

基礎(chǔ)知識(shí)

關(guān)于比較運(yùn)算的原則,MySQL官方文檔的描述: https://dev.mysql.com/doc/refman/5.6/en/type-conversion.html

如果 判斷符號(hào)左右兩邊有一個(gè)為NULL,結(jié)果就是null,除非使用安全的等值判斷 <=> 

(none) 05:17:16 >select  null = null;
+-------------+
| null = null |
+-------------+
|        NULL |
+-------------+
1 row in set (0.00 sec)

(none) 05:34:59 >select  null <=> null;
+---------------+
| null <=> null |
+---------------+
|             1 |
+---------------+
1 row in set (0.00 sec)

(none) 05:35:51 >select  null != 1;
+-----------+
| null != 1 |
+-----------+
|      NULL |
+-----------+
1 row in set (0.00 sec)

如何判斷左右兩邊都是相同類(lèi)型的,比如都是字符串,則以字符串進(jìn)行對(duì)比。如果是數(shù)字,則以數(shù)字進(jìn)行比較。

注意 對(duì)于比較常見(jiàn)的 字符串與數(shù)字類(lèi)型的比較的情況,如果字符串字段是索引字段,那么MySQL 無(wú)法通過(guò)索引進(jìn)行查找數(shù)據(jù),比如以下例子:

(none) 05:39:42 >select  1='1';
+-------+
| 1='1' |
+-------+
|     1 |
+-------+
1 row in set (0.00 sec)

(none) 05:39:44 >select  1='1A';
+--------+
| 1='1A' |
+--------+
|      1 |
+--------+
1 row in set, 1 warning (0.00 sec)

(none) 05:39:47 >select  1='1 '; ##1后有空格
+--------+
| 1='1 ' |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

MySQL 認(rèn)為數(shù)字1 與'1','1_','1A' 相等,故無(wú)法通過(guò)索引二分查找準(zhǔn)確定位到具體的值。

Hexadecimal(十六進(jìn)制)以二進(jìn)制字符串的方式進(jìn)行比較。

如何判斷符號(hào)左邊是 timestamp 或者datetime類(lèi)型的,右邊是常量,在比較之前,常量會(huì)被轉(zhuǎn)換為時(shí)間類(lèi)型。

隱式轉(zhuǎn)換

字段類(lèi)型不一樣

In all other cases, the arguments are compared as floating-point (real) numbers.

除了以上的其他類(lèi)型的比較,系統(tǒng)將字段和參數(shù)轉(zhuǎn)換為浮點(diǎn)型進(jìn)行比較。使用浮點(diǎn)數(shù)(或轉(zhuǎn)換為浮點(diǎn)數(shù)的值)的比較是近似的,因?yàn)檫@樣的數(shù)字是不精確的??聪旅?個(gè)例子

>select '190325171202362933' = 190325171202362931;
+-------------------------------------------+
| '190325171202362933' = 190325171202362931 |
+-------------------------------------------+
|                                         1 |
+-------------------------------------------+
1 row in set (0.00 sec)

>select '190325171202362936' = 190325171202362931;
+-------------------------------------------+
| '190325171202362936' = 190325171202362931 |
+-------------------------------------------+
|                                         1 |
+-------------------------------------------+
1 row in set (0.00 sec)

直觀上不相等的值,做等值判斷之后竟然返回為1。這樣帶來(lái)2個(gè)問(wèn)題不能利用索引且結(jié)果數(shù)據(jù)不準(zhǔn)

>select '190325171202362931'+0.0;
+--------------------------+
| '190325171202362931'+0.0 |
+--------------------------+
|    1.9032517120236294e17 |
+--------------------------+
1 row in set (0.00 sec)

>select '190325171202362936'+0.0;
+--------------------------+
| '190325171202362936'+0.0 |
+--------------------------+
|    1.9032517120236294e17 |
+--------------------------+
1 row in set (0.00 sec)

將上面的值轉(zhuǎn)換為浮點(diǎn)數(shù),都是 1.9032517120236294e17,所以判斷相等時(shí)為真,返回True。

in 參數(shù)包含多個(gè)類(lèi)型

具體的案例參考之前的一篇文章MySQL優(yōu)化案例一則 ,where 條件 in 集合里面的數(shù)據(jù)類(lèi)型不一樣,執(zhí)行計(jì)劃未利用到索引

淘寶MySQL月報(bào)(http://mysql.taobao.org/monthly/2017/12/06/ )里面有一篇正好和這個(gè)一樣的案例,推薦給大家 簡(jiǎn)單說(shuō),就是在IN的入口有一個(gè)判斷, 如果in中的字段類(lèi)型不兼容, 則認(rèn)為不可使用索引. 

而這個(gè)arg_types_compatible 的賦值邏輯是:

if (type_cnt == 1) 
    arg_types_compatible = TRUE; 

也就是說(shuō),當(dāng)IN列表中出現(xiàn)超過(guò)一個(gè)字段類(lèi)型時(shí), 就認(rèn)為類(lèi)型不兼容,從而不能利用索引。

字符集類(lèi)型不一致

環(huán)境準(zhǔn)備:

CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` varchar(20) DEFAULT NULL,
`c2` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_c1` (`c1`),
KEY `idx_c2` (`c2`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` varchar(20) DEFAULT NULL,
`c2` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_c1` (`c1`),
KEY `idx_c2` (`c2`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;


insert into t1(c1,c2) values('a','a'),('b','b'),('c','c'),
('d','d'),('e','e');
insert into t2(c1,c2) values('a','a'),('b','b'),('c','c'),
('d','d'),('e','e');

測(cè)試結(jié)果

小結(jié)

希望通過(guò)以上案例,基礎(chǔ)知識(shí)介紹,開(kāi)發(fā)同學(xué)能少走彎路,在開(kāi)發(fā)編寫(xiě)sql的階段一定要明確字段的類(lèi)型,尤其是看起來(lái)像數(shù)字類(lèi)型的id,xxxid,xxxno 這類(lèi)字段,實(shí)際上可能是字符類(lèi)型。

以上就是談?wù)凪ySQL中的隱式轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于MySQL 隱式轉(zhuǎn)換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 一文詳解MySQL的并發(fā)控制

    一文詳解MySQL的并發(fā)控制

    無(wú)論何時(shí)只要有多個(gè)查詢(xún)需要在同一時(shí)刻修改數(shù)據(jù),都會(huì)產(chǎn)生并發(fā)控制問(wèn)題,MySQL可以在兩個(gè)層面進(jìn)行并發(fā)控制,服務(wù)器層和存儲(chǔ)引擎層,下面這篇文章主要給大家介紹了關(guān)于MySQL并發(fā)控制的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • 簡(jiǎn)單了解mysql方言dialect

    簡(jiǎn)單了解mysql方言dialect

    這篇文章主要介紹了簡(jiǎn)單了解數(shù)據(jù)庫(kù)方言dialect,數(shù)據(jù)庫(kù)方言也是如此,MySQL 是一種方言,Oracle 也是一種方言,MSSQL 也是一種方言,他們之間在遵循 SQL 規(guī)范的前提下,都有各自的擴(kuò)展特性,需要的朋友可以參考下
    2019-07-07
  • 解決MYSQL出現(xiàn)Can''t create/write to file ''/tmp/#sql_5c0_0.MYD''的問(wèn)題

    解決MYSQL出現(xiàn)Can''t create/write to file ''/tmp/#sql_5c0_0.MYD''

    今天在配置服務(wù)器的時(shí)候提示這個(gè)問(wèn)題Can't create/write to file,原來(lái)是php.ini中設(shè)置的tmp目錄不存在
    2013-07-07
  • MAC下MySQL初始密碼忘記怎么辦

    MAC下MySQL初始密碼忘記怎么辦

    MySQL初始密碼忘記如何解決,這篇文章主要介紹了MAC下MySQL忘記初始密碼的解決辦法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • 基于mysql實(shí)現(xiàn)group by取各分組最新一條數(shù)據(jù)

    基于mysql實(shí)現(xiàn)group by取各分組最新一條數(shù)據(jù)

    這篇文章主要介紹了基于mysql實(shí)現(xiàn)group by取各分組最新一條數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 系統(tǒng)高吞吐量下的數(shù)據(jù)庫(kù)重復(fù)寫(xiě)入問(wèn)題分析解決

    系統(tǒng)高吞吐量下的數(shù)據(jù)庫(kù)重復(fù)寫(xiě)入問(wèn)題分析解決

    這篇文章主要介紹了系統(tǒng)高吞吐量下的數(shù)據(jù)庫(kù)重復(fù)寫(xiě)入問(wèn)題分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 在ubuntu中重置mysql服務(wù)器root密碼的方法

    在ubuntu中重置mysql服務(wù)器root密碼的方法

    在ubuntu下安裝了mysql 5 server,結(jié)果不知道什么原因,安裝時(shí)輸入的root帳號(hào)密碼在使用時(shí)無(wú)論如何都不能通過(guò)數(shù)據(jù)庫(kù)服務(wù)器的驗(yàn)證。無(wú)奈只有重置mysql的root帳號(hào)密碼。查了一下,用了以下方法成功的重置了root帳號(hào)密碼
    2012-10-10
  • MySQL 5.7忘記root密碼后修改的詳細(xì)教程

    MySQL 5.7忘記root密碼后修改的詳細(xì)教程

    因?yàn)殚L(zhǎng)時(shí)間不操作mysql而忘記root密碼的朋友估計(jì)不在少數(shù),最近發(fā)現(xiàn)在MySQL 5.7版本下用之前的方法修改密碼不能成功了,所以只能重新想辦法解決,下面這篇文章主要給大家介紹了MySQL 5.7忘記root密碼后修改的詳細(xì)教程,需要的朋友可以參考。
    2017-05-05
  • CentOS系統(tǒng)中MySQL5.1升級(jí)至5.5.36

    CentOS系統(tǒng)中MySQL5.1升級(jí)至5.5.36

    有相關(guān)測(cè)試數(shù)據(jù)說(shuō)明從5.1到5.5+,MySQL性能會(huì)有明顯的提升,具體的需要自己建立測(cè)試環(huán)境去實(shí)踐下,今天我們就來(lái)操作下,并記錄下來(lái)升級(jí)的具體步驟
    2017-07-07
  • MySQL對(duì)小數(shù)進(jìn)行四舍五入的操作實(shí)現(xiàn)

    MySQL對(duì)小數(shù)進(jìn)行四舍五入的操作實(shí)現(xiàn)

    數(shù)學(xué)函數(shù)是MySQL中常用的一類(lèi)函數(shù),其主要用于處理數(shù)字,包括整型和浮點(diǎn)數(shù)等等,本文主要介紹了MySQL對(duì)小數(shù)進(jìn)行四舍五入的操作實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08

最新評(píng)論