<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          因為一個空格引發(fā)的編程“慘案“

          共 2675字,需瀏覽 6分鐘

           ·

          2020-08-28 13:19

          轉自:互聯(lián)網(wǎng)全棧架構


          “案情”回顧(情景模擬):

          小張是一名軟件工程師,工作兢兢業(yè)業(yè)、一絲不茍且精益求精,天性樂觀的他每天愉快地做著增刪改查的工作,對于這些看似簡單的CRUD,小張從來不會掉以輕心,他也篤定地堅信,自己向數(shù)據(jù)庫里插入了什么數(shù)據(jù),就能按條件把這些數(shù)據(jù)查詢出來,畢竟,像MySQL這樣的數(shù)據(jù)庫,在全世界廣為流行,大行其道,不可能不嚴謹。


          然而,意想不到的悲劇還是發(fā)生了。

          小張做的項目與語言處理有點關系,他們把處理的結果也就是字符串保存到在數(shù)據(jù)庫里面,后續(xù)需要按照條件把這些數(shù)據(jù)查詢出來,但需要對這些字符串做嚴格的區(qū)分,也就是說,如果查詢A字符串,不能把B字符串查詢出來,哪怕這兩個字符串只有一個空格的差異。對于這樣的需求,小張覺得太天經(jīng)地義了,根本無需多言,像MySQL這樣的數(shù)據(jù)庫天生就是干這樣的事,所以當時就自信滿滿地拍著胸脯保證一定如期開發(fā)完成。

          隨著工作的推進,小張猛然發(fā)現(xiàn)MySQL對于字符串的處理貌似不那么嚴謹,特別是對于空格字符,比如這兩個字符串:"Tom"和"Tom ",后面的字符串多了一個空格,然而,MySQL竟然把它們當成了相同的字符串。


          我們來測試一下,看看具體的情況,先創(chuàng)建一個表:

          CREATE?TABLE?`white_space`(
          `id`?bigint(20)unsigned?NOT?NULL?AUTO_INCREMENT,
          `name`varchar(128)?NOT?NULL?DEFAULT?'',
          PRIMARY?KEY?(`id`)
          )?ENGINE=InnoDBDEFAULT?CHARSET=utf8


          然后向表里插入兩條數(shù)據(jù):

          INSERT?INTO?white_space(name)?VALUES('Tom');
          INSERT?INTO?white_space(name)?VALUES('Tom?');
          ?
          注意,后面那條記錄在最后多了一個空格。假設我們需要查詢名字為Tom的記錄(沒有空格),SQL很簡單:

          SELECT?*?FROM?white_space?WHERE?name?=?'Tom';

          ?然而,讓小張大跌眼鏡的是,上面的SQL竟然返回兩條數(shù)據(jù),也就是說,本來查找"Tom"(沒有空格),卻把"Tom "(有空格)也查詢出來了:



          這也太不嚴謹了,空格也是字符啊,為什么就生生的把它忽略了呢?這樣的話,就滿足不了項目的需求了,而且,小張還發(fā)現(xiàn),不管后面有多少個空格,都會被忽略。我們再插入一條記錄,名字是"Tom ?? ? ? ? ",后面一共有10個空格:

          INSERT?INTO?white_space(name)?VALUES('Tom??????????');

          再執(zhí)行上面的查詢語句,這時仍然還是返回了三條記錄:

          SELECT?*?FROM?white_space?WHERE?name?=?'Tom';


          這簡直太不可理喻了!感覺MySQL在這里完全無視空格的存在,但空格也是一個正正經(jīng)經(jīng)的字符啊,而且是一個非常常見的字符,咋就這么沒有存在感呢。

          當然,如果是前置空格,或者空格在中間是不會有這個問題的,比如數(shù)據(jù)庫里保存的名字為" Tom"(最前面是一個空格),或者是"To m",再按"Tom"(沒有空格)去查詢的話,是找不到這條記錄的。

          這就麻煩了,當初可是拍著胸脯保證可以如期完成的,現(xiàn)在碰到這樣的問題,小張可真是有點慌了神,不知道該如何來解決,而且這也是非常不可思議的事情,強悍如斯、威武如斯、名聲震天響的MySQL竟然如此不嚴謹。幸虧空格不會說話,要不然它還不得罵街啊,作為一個名正言順的字符,就這樣生生地被忽略了,這也太不尊重人了。

          事已至此,小張只能去尋找問題的解決方法,抱怨是沒有用的,經(jīng)過一番辛勤探索和研究,小張終于找到了辦法,也就是加上BINARY關鍵字,像下面這樣:

          SELECT?*?FROM?white_space?WHERE?BINARY?name?=?'Tom';

          這時候就會嚴格地進行匹配,只返回了一條記錄,如果要查詢包含空格的記錄,比如"Tom "(有空格),就會只返回有空格的這條記錄:

          SELECT?*?FROM?white_space?WHERE?BINARY?name?=?'Tom?';


          完美!項目就是需要這樣的效果,字符串要進行嚴格的匹配與區(qū)分,現(xiàn)在加上BINARY關鍵字就徹底地解決了這個問題,小張不禁有些沾沾自喜,他也覺得MySQL確實太強大了,不管什么樣的問題貌似都有辦法解決,怪不得它會風靡全世界,成為了萬千企業(yè)的首選。

          然而,小張還沒有高興沒多久,新的問題就又出現(xiàn)了。BINARY是MySQL獨有的關鍵字,Oracle數(shù)據(jù)庫并不認識什么BINARY,而項目需要適配不同的數(shù)據(jù)庫,主要包括MySQL和Oracle。公司有一套ORM來做這樣的適配,開發(fā)人員只要按照標準來寫SQL就可以了,但是,如果在SQL語句中加上BINARY,切換到Oracle數(shù)據(jù)庫就會出錯,這可怎么辦?當然,也可以判斷數(shù)據(jù)庫的類型,如果是MySQL數(shù)據(jù)庫,就加上BINARY關鍵字,否則就不加(Oracle數(shù)據(jù)庫可以嚴格區(qū)分后置空格),但是,這樣的改動也太大了,因為MySQL中的語句都完全忽略了后置空格的存在,比如GROUP BY:

          SELECT?name,COUNT(*)?FROM?white_space?GROUP?BY?name


          返回這樣的結果:



          也是完全忽略了后置空格,當然,加上BINARY也是可以解決問題的。


          這樣看來,只要涉及到需要嚴格區(qū)分字符串的地方,都需要做這樣的改動,而這樣的字段還有好幾個,改動實在太大了!

          事到如今,小張依然還沒有找到完善的解決方案,開發(fā)的工期也一拖再拖,可以說是一樁不折不扣的“慘案”了。

          你有什么好的解決方案嗎?歡迎后臺留言討論。

          -End-

          更多精彩:

          SpringSecurity + JWT 權限系統(tǒng)

          非常強悍的 RabbitMQ 總結,寫得真好!

          這個IDEA插件,專門解決Maven依賴沖突

          RabbitMQ+WebSocket實現(xiàn)大屏幕消息推送

          這7 款 MySQL 客戶端工具,用了都說好!

          Spring 和 Spring Boot 最核心的 3 大區(qū)別

          關注公眾號,查看更多優(yōu)質文章

          明天見(??ω??)??

          瀏覽 69
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品 熟女 国产 探花 AV | 欧美亚洲视频 | 久久艹免费视频 | 亚洲性爱AV网站 | 淫欲5月网 |