MySQL入門(三)

来源:http://www.cnblogs.com/wingsless/archive/2016/03/11/5267452.html
-Advertisement-
Play Games

寫了兩篇《MySQL入門》以後我發現,寫書的人還是都挺有本事的,起碼人家知道怎麼編排自己想講的知識點,我實在是不知道該先說那裡後說哪裡,那我就想到什麼講什麼吧。 一 寫SQL 其實我是不想寫有關SQL的部分的,因為這個部分其實很簡單,基本上大學只要好好聽聽資料庫概論這門課基本上都能寫滿足功能的SQL


     寫了兩篇《MySQL入門》以後我發現,寫書的人還是都挺有本事的,起碼人家知道怎麼編排自己想講的知識點,我實在是不知道該先說那裡後說哪裡,那我就想到什麼講什麼吧。

  一 寫SQL

    其實我是不想寫有關SQL的部分的,因為這個部分其實很簡單,基本上大學只要好好聽聽資料庫概論這門課基本上都能寫滿足功能的SQL,但是後來想想,SQL其實是人和資料庫交互的一種介面,不會SQL確實是不可以的,寫的不好感覺不出資料庫有多麼的強大,甚至有可能會讓人產生出資料庫慢的壞印象。

     MySQL作為most popular的開源資料庫,其實在SQL支持這裡做的不是那麼完美,比如5.6為止還是不支持全外連接(5.7沒試過是不是支持)。如果有人說全外連接這東西不支持就不支持了,沒什麼,但是我想說的是既然RDBMS是基於Codd的理論,那麼全外連接作為關係代數的一部分,不實現是有點說不過去的。相反,Berkeley出身的PostgreSQL就做的很好了,畢竟人家是most advanced開源資料庫。

     閑話少敘。其實平時很多程式員寫的最多的SQL是這樣子的:

     

select t1.a, t1.b, t2.c, t2.d from table1 t1, table2 t2 where t1.m = t2.m and t1.k = ?;

     這個寫法一點問題都沒有,特別的自然,翻譯成漢語是這樣的:

     我需要從table1和table2中取一些數據出來,這兩張表通過m列關聯起來取交集,其中table1要卡k條件。

     這個SQL按下不表,繼續說些技術性的東西。

     基礎語法的東西就不說了,說一下連接。使用頻率最高的就是內連接和外連接兩種了。連接在我看來就是一種集合運算,比如內連接就是很自然的取交集運算,以兩張表的內連接說,就是A和B兩個集合做了A∩B運算。

     內連接,翻譯成英文就是inner join;外連接,翻譯成英文就是outer join。所以說SQL是很好理解的,甚至接近了自然的語言。

     寫一個內連接:

     

select t1.a, t1.b, t2.c, t2.d from table1 t1 inner join table2 t2 on t1.m = t2.m where t1.k = ?;

     這個SQL就是上面那個SQL的等價形式,只不過這是ANSI SQL92寫法,上面那種是ANSI SQL89寫法,SQL是一種語言,更是一種標準,新的標準更好理解,顯然的讓我們知道了這個SQL採用了內連接的形式。

     至於連接具體怎麼寫,我很早以前寫了一篇筆記:《Oracle的連接》。我就不重覆發明輪子了,雖然當時採用的是Oracle,但是我說過了,SQL是一種標準,因此放到任何一個RDBMS里,這些都是通用的。

     我本來就沒有打算把這個寫成什麼正式的東西,我沒有寫書的夢想,所以基本上都是扯淡,扯淡的中途講點知識。

  二 數據類型

    SQL也是一種編程語言!SQL也是一種編程語言!SQL也是一種編程語言!

    我要把這個強調三遍,因為很多很多,多入牛毛的同行都會覺得寫SQL是個很簡單的事情,SQL就是增刪改查數據,學一個小時就會的東西,是個很low的東西。我見過的很多人都問我SQL到底有什麼寫的,不就些破命令麽?我真的不知道怎麼回答他們。

    SQL真的可以做很多事情,而寫好SQL並不太容易,當然,更不難。

    MySQL支持的數據類型大致分為:數字類型,時間日期類型,字元型。

    以前玩兒Oracle的時候,數字類型通通是number型,好用到沒朋友。但是MySQL不是這樣搞的,MySQL的數字類型分為tinyint, smallint, mediumint, int, bigint。每種類型都會有“有符號”和“無符號”的屬性,他們的範圍如下表:

類型 占用空間(位元組) 最小值 最大值
tinyint 1 -128 127
tinyint(unsigned) 1 0 255
smallint 2 -32768 32767
smallint(unsigned) 2 0 65535
mediumint 3 -8388608 8388607
mediumint(unsigned) 3 0 16777215
int 4 -2147483648 2147483647
int(unsigned) 4 0 4294967295
bigint 8 -9223372036854775808 9223372036854775807
bigint(unsigned) 8 0 18446744073709551615

    很難記,但是其實不是很難,占用空間這裡呢,我們都知道1Byte等於8bit,那麼tinyint的取值範圍就應該是[-2^(8-1), 2^(8-1)-1]。如果是無符號類型的取值範圍就能推導出來了,有基本數學知識都能理解。

    我第一次玩兒MySQL的時候,發現列類型經常是int(4)這樣的,這個4是什麼呢?從上面的表中明顯可以看出數字型占用的空間總是一定的,那這裡的4就不是char(4)裡面那種意思了,這其實是填充格式用的,要和ZEROFILL屬性一起用的,這樣就能讓欄位被填充滿,不過不影響取值,感覺像是語法糖之類的東西。

    後來我覺得MySQL的varchar型有意思,有意思就在於varchar括弧內的長度不是位元組數,而是字元數,與漢字英文無關,就是字元數,這個感覺又是一個語法糖之類的東西,我在設計表的時候就不需要考慮什麼字元集了,直接告訴程式員我給你了一個列,這個列最多存100個字元,你們自己控制。

    但是這裡還是有個陷阱。很多書上和網上的資料都會說,InnoDB表的所有varchar欄位長度的總和不得超過65535,就說到了這裡就不說了。實際上不能忽略一個前提,就是字元集應該選擇latin1,而且絕對不是65535,是65532,還有些別的開銷。如果換成UTF8字元集呢?這個理論總和限制就會變成21845,這個數字其實就是65535/3,實際上的限制是21844。所以我說這個是個語法糖,其實還是字元集相關的,只是不再讓上層的程式員去考慮了,而是由DB自己保證。

    時間和日期類型MySQL也是很豐富的,而且特別簡單,'2015-12-12 12:31:20'這樣就可以,Oracle的話還得寫個什麼函數去把字元串轉成date型。當然時間和日期類型也是有空間占用的,很多資料上都會說用TIMESTAMP類型取代DATETIME類型,這樣節省空間,確實沒有問題,TIMESTAMP占用的空間僅有DATETIME的一半,但是要註意,TIMESTAMP的範圍不大,1970年到2038年,節省空間是對的,但是要註意應用場景。

    當然還有很討厭的BLOB和TEXT這樣的大數據類型(huge size data type),這可不是現在特別火的big data。這部分數據嘛,我覺得能不用就別用了,他們的存儲都是在單獨的地方,效率上我個人覺得堪憂。不過還是那句話,設計的時候要註意應用場景,給恰當的數據類型。

    今天就扯到這裡吧。

 




您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ReactNative官方中文文檔0.21,ReactNative官方中文文檔0.21.chm
  • interactivePopGestureRecognizer是iOS7推出的解決VeiwController滑動後退的新功能,雖然很實用,但是坑也很多啊,用過的同學肯定知道問題在哪裡,所以具體問題我就不描述了,這裡只給出如何完美解決interactivePopGestureRecognizer卡住
  • 這篇是關於網路請求的,結合公司的實際情況編寫,如果有不同意見歡迎留言共同討論。 iOS在9.0之後徹底放棄了NSURLConnection,現在已經改用了NSURLSession進行網路請求。一般現在網路請求也都是使用AFNetworking。下麵就把我自己關於afn和系統的api使用寫下來。 一.
  • 經測試發現,如果EditText預先有內容,游標自然會在文字的末尾 。 但是如果預先內容為空,然後設置好內容,這種情況下游標自然會在文字的開頭,所以這種情況下可以這樣做讓游標位於末尾:editText.setText("0");editText.requestFocus(); //這是關鍵
  • 前言:23種軟體設計模式中的觀察者模式,也是在軟體開發中,挺常用的一種設計模式。而在蘋果開發中,蘋果Cocoa框架已經給我們實現了這個設 計模式,那就是通知和KVO(Key-Value Observing),本篇博文將會先講解通知和KVO的常用方法和使用示例,然後講解觀察者模式以及對觀察者模式的實現
  • 問題 處理表單的時候,一定會碰到的就是輸入控制項被鍵盤遮住的問題,如圖: 實例 左邊是普通表單,中間是2B表單,右邊是文藝表單. 分析 處理這種問題無非就是2個步驟: 鍵盤彈出時,縮小UITableView的frame 滾動UITableView,讓當前輸入的控制項可見 代碼寫出來就是這幾步 捕獲鍵盤事
  • JSON text did not start with array or object and option to allow fragments not set. === AFN使用報錯: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text
  • UITableView可以算是使用頻率最高的組件之一的,在開發過程中經常需要展示一些簡單的信息列表常見列表佈局 如圖,很多頁面其實就是這種展示結果,通常需要imageView,textLabel,detailTextlabel,而UITableViewCell本身提供了方便的自動佈局(當有圖片和沒圖
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...