MySQL知識樹-支持的數據類型

来源:http://www.cnblogs.com/seker/archive/2016/11/23/6096024.html
-Advertisement-
Play Games

本篇學習筆記的主要內容: 介紹MySQL支持的各種數據類型(常用),並講解其主要特點。 MySQL支持多種數據類型,主要包括數值類型、日期和時間類型、字元串類型。 數值類型 MySQL的數值類型包括整數類型、浮點數類型、定點數類型、位類型。 整數類型 MySQL支持的整數類型有tinyint、sma ...


本篇學習筆記的主要內容:

介紹MySQL支持的各種數據類型(常用),並講解其主要特點。

 

MySQL支持多種數據類型,主要包括數值類型、日期和時間類型、字元串類型。

 

數值類型

MySQL的數值類型包括整數類型、浮點數類型、定點數類型、位類型。

 

整數類型

MySQL支持的整數類型有tinyintsmallintmediumintintbigint(範圍從小到大)。

 

zerofill

我們在定義整數類型時可以在類型名稱後面的小括弧內指定顯示寬度,例如int(5),當插入的數值寬度小於5位時,MySQL會在數值前面填充寬度。對於int類型如果不手動指定寬度,則預設為int(11)

顯示寬度一般是配合zerofill來使用,即當插入的數值位數未達到指定的顯示寬度時,缺少幾位就會在數值前填充幾個0

1

圖1我們創建表t_1,兩個欄位分別為id1id2,都是int類型。其中id2我們指定了顯示寬度為5,而id1沒有手動指定顯示寬度,因此它的顯示寬度會取預設值11

 

2

2,我們向表中插入一條數據後再將其查詢出來,雖然現在id1id2查詢出來的數值都是1,但由於id1在定義時沒有指定顯示寬度,因此在插入數值1後,其前面10位都被填充了寬度。而id2由於指定了顯示寬度,因此其面前只有4位被填充寬度。

 

3

圖4

3、圖4,為了更加直觀的看到填充寬度的效果,我們將id1id2的定義稍作修改,使用zerofill來填充寬度。

 

5

5,在使用了zerofill後,我們可以看到數值前面被0填充寬度的效果。那麼我們在進行查詢時使用100001作為條件可以得到結果嗎?

 

6

6,可以看到在使用100001作為查詢條件時,能查出id2對應的數值。但這裡要註意的是在MySQL中實際存儲的值仍然是1,而不是00001,因為00001並不是一種整數的表現形式,而是一種字元串的表現形式,下麵的圖7將證明這個問題。

 

7

圖7,我們在查詢時使用了hex()函數作為對比,可以看到使用hex()函數得到的值是1,假若hex()得到的值是3030303031(字元串116進位為31,字元串016進位為30),則可以肯定在MySQL中是以00001的字元串形式進行存儲的,但很明顯這裡並不是。

 

註:hex()函數可以將一個數字或字元串轉換為十六進位格式的字元串

 

對於指定顯示寬度的做法,聯想到一個問題,在id2定義為int(5)的情況下,如果插入超過顯示寬度的值,會怎麼樣呢?

 

8

8,向id2插入長度為6位的數值111111時,MySQL沒有報任何錯誤也沒有將111111截斷。因此說明瞭顯示寬度並不會對插入的數值長度產生限制,兩者並沒有什麼關係,除非插入的數值超過了數據類型的範圍,見圖9

 

9

 

圖9,可以看到雖然插入成功但MySQL有一個警告(當MySQLSQL Mode為嚴格模式時,該插入行為將不能夠被完成,同時MySQL會報ERROR),我們在將數據查詢出來時可以看到MySQL對原本插入的數據進行了截取,保留值為4294967295

 

註:int數據類型有符號的最小值為-2147483648,最大值為2147483647,無符號的最小值為0,最大值為4294967295

 

知識點說明:

其實對於顯示寬度來說,只有配合使用了zerofill,顯示寬度才有意義,否則就讓顯示寬度為預設值就可以了。不要以為指定顯示寬度會對整數類型的取值範圍有什麼影響,兩者之間沒有任何關係,而說到整數類型的取值範圍只有unsigned才會對其產生影響。

 

 

unsigned

當我們在定義整數類型時使用了zerofillMySQL會為我們自動對該列再添加unsigned(圖3、圖4對列添加了zerofill後,再查看表的DDL [資料庫定義語句],會發現列多了unsigned,詳見圖10)。這是因為當使用了zerofill後,插入該列的值就不可能為負數了,因此自動添加unsigned也是理所應當的,同時unsigned也會增加整數類型最大值的取值範圍。

 

10

 

 

auto_increment

整數類型還有一個屬性就是auto_increment,而且這個屬性還是整數類型特有的。auto_increment的作用就是使列值保持自動增長,auto_increment的值預設從1開始,也可以手動設置其初始值。對被設置為auto_increment的列插入null值時,實際插入的值是該列當前最大值加1null並不會影響到被設置為auto_increment列的數據插入,列會正常的進行自動增長)。

當一個列被設置為auto_increment時,通常還需要為該列設置not nullprimary key(主鍵,一般被設置為auto_increment的列會作為主鍵使用,這裡只是說一般,也有非主鍵的情況)。

另外需要提醒的是一張表中最多只能有一個欄位被設置為auto_increment

 

 

浮點數和定點數

這兩者都是用來表示小數的,浮點數包括float(單精度)double(雙精度),定點數僅為decimal。兩者在定義時都可以指定其精度和標度,精度是指一共顯示多少位數字(整數位+小數位),標度是指精確到小數點後多少位,表現形式如:decimal(15,2),這裡的精度是15(整數13位,小數2),標度是2位。

需要說明的是定點數在MySQL內部是以字元串的形式來保存的,屬於準確存儲,但表現出來的是小數,它比浮點數更精確。

 

11

圖12

13

圖11,我們創建一張表,欄位id的數據類型為decimal(5,2),如圖12在向表裡插入超過標度的值時,雖然插入成功但是插入時的數據卻被截斷了,這裡發生了四捨五入。

13我們向表裡嘗試插入超過精度的值,難道也會發生截斷並四捨五入?兩個值會分別顯示為123.12124.12嗎?從結果來看明顯不是,我們的猜測是完全錯誤的。在超過精度的情況下,雖然插入成功但插入的值卻是指定精度和標度下的最大值,例如(5,2)下的最大值為999.99

若是在SQL Mode嚴格模式下,上述這些插入操作將不能被執行成功且MySQL會報ERROR

 

額外知識點:

單精度和雙精度的區別,這兩者的區別可別理解為單精度是精確到小數點後一位,而雙精度是精確到小數點後兩位,這明顯是錯誤的。實際上由於float的有效位數是7位,double的有效位數是16位,因此單精度、雙精度其實是指代這裡的有效位數。

另外需要註意的是有效位數並不等於精確位數,縱然float可以表示到小數點後7位,但只有前6位是精確的,第7位很可能造成數據誤差。而對於double來說只有前15位是精確的,第16位也很可能造成數據誤差。

 

額外知識點:

關於floatdouble精度丟失的問題,實際上就是被擴展或截斷了,究其緣由是因為存取時標度不一致所導致的。在錄入數據時若數據的標度與定義列數據類型時設置的標度不一致,則會導致存入時以近似的值來存儲,這就造成了我們上面說到的精度丟失。

那在什麼情況下floatdouble的精度不會丟失呢?其實根據上面出問題的情況,我們可以想到當數據標度與類型標度一樣時(錄入數據的標度與定義列數據類型時設置的標度一致),就不會發生精度丟失。

鑒於此,我們常選用decimal類型,小於等於其標度的數據都能被正確錄入,不會發生精度丟失,因為其是將數據以字元串的形式來存進資料庫的,這就保證了精確性。但並不是說decimal就不會發生精度丟失,雖然它不會發生精度擴展但卻會發生精度截斷。例如當錄入數據的標度大於列數據類型設置的標度時,依然會發生四捨五入。

雖然我們說decimal將數據以字元串的形式存入資料庫,同時又會存在精度截斷的問題(四捨五入),看似兩者有文字描述上的衝突,其實不然。我們這樣來理解:decimal將發生了四捨五入的數據以字元串的形式存入了資料庫,但表現出來的是小數(一個是存儲形式,一個是表現形式),且這個小數的精度不會再發生變化,而不管是以什麼精度來獲取這個值,它都是四捨五入後以字元串形式存入時的值。

 

 

位類型

位類型指的就是BIT,它是用來存放二進位數據的,bit(1)表示存儲長度為1位的二進位數據。

14

圖15

我們對圖14的表中插入超過位數的數據,從圖15的第二個查詢結果集中可以發現數據發生了截斷,數值2的二進位是103的二進位是11,它們的第二位都被截斷了。

在圖15的第一個查詢結果集中,需要說明的是在MySQL命令行視窗中使用select * from t_bit_test是無法看到我們需要的數據的,你只能看到有兩個笑臉被顯示出來,那既然bit中存放的是二進位數據,我們就使用bin()函數以二進位的形式來顯示它們。

 

 

 

日期時間類型

 

日期時間類型的主要區別如下:

 

①如果要用來表示年月日時分秒,一般使用datetime類型;

 

②如果要用來表示年月日,一般使用date類型;

 

③如果要表示時分秒,一般使用time類型;

 

④如果只是表示年份,一般使用year類型,需要註意的是5.5.27版本之前(不包含該版本)year類型有2位和4位格式這兩種表示,在5.5.27版本之後2位格式的year已經不再被支持,year類型的值都會以YYYY的格式顯示。

 

  year(2)被棄用主要是因為兩位的顯示寬度使得該類型表示變得模糊、不明確(顯示的值僅僅是最後兩位數字),因此如果在設計資料庫時需要使用year數據類型,而MySQL的版本又是低於5.5.27版本的話,建議將year類型定義為year(4)以避免問題(從5.5.27版本開始若創建表時將year類型定義為year(2),實則MySQL會強制將其定義為year(4)。詳見圖15)。

 

  若在將低版本的MySQL升至5.5.27以後的版本時需要將這塊的數據做下處理;

 

⑤如果需要經常插入系統當前時間或將時間更新為系統當前時間,一般使用timestamp類型。

 

15

 

16

 

圖16,我們創建了一張表,列d1的數據類型為timestamp,通過查看表的定義可以看到MySQL自動將timestamp類型列的預設值設置為了current_timestamp,即系統當前時間,另外還加上了on update current_timestamp(當該行的數據發生變化時,該列的值會隨系統當前時間被更新,詳細效果見圖1718)。

 

17

圖17,我們為t_dt_test表新增列i1int類型顯示寬度為2,寬度不夠時用0填充。

 

18

 

圖18中我們先為表插入一條數據,可以看到插入的d1值為2016-10-22 15:25:31,接著我們將i1的值由1修改為2,再看d1發現原本存入的時間被更新了,此時的值為2016-10-22 15:26:27,這就是隨系統當前時間戳更新的效果。

 

 

 

---------------------未完待續---------------------


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

-Advertisement-
Play Games
更多相關文章
  • 今天碰到了一個奇怪的問題,是關於Oracle一個事務中的Insert和Update語句的執行順序的問題。 首先詳細說明下整個過程: 有三張表:A,B,C,Java代碼中有一段代碼是先在表A中插入一條數據,然後再更新表B的兩個欄位,更新的兩個欄位是特定值。並且插入和更新在一個事務中。 有個需求需要在表 ...
  • 1、導入資料庫 在命令行下輸入: 說明: username 是資料庫用戶名, test 為目標資料庫, /home/data/test.sql 是你要備份的路徑和名稱 回車,輸入資料庫密碼,就進行導入操作了! 2、導出資料庫 2.1、導出整個資料庫: 說明:username是資料庫用戶名,test源 ...
  • PageSize = 30 PageNumber = 201 方法一:(最常用的分頁代碼, top / not in) 備註: 註意前後的order by 一致 方法二:(not exists, not in 的另一種寫法而已) 備註:EXISTS用於檢查子查詢是否至少會返回一行數據,該子查詢實際上 ...
  • 版權聲明:本文發佈於http://www.cnblogs.com/yumiko/,版權由Yumiko_sunny所有,歡迎轉載。轉載時,請在文章明顯位置註明原文鏈接。若在未經作者同意的情況下,將本文內容用於商業用途,將保留追究其法律責任的權利。如果有問題,請以郵箱方式聯繫作者(793113046@q ...
  • 昨天遇到一個案例,YourSQLDba做事務日誌備份時失敗,檢查YourSQLDba輸出的錯誤信息如下: yMaint.backups backup log [gewem] to disk = 'M:\DB_BACKUP\LOG_BACKUP\xxxx_[2016-11-22_01h11m05_Tu... ...
  • 副本集 可以將MongoDB中的副本集看作一組伺服器集群由一個主節點和多個副本節點等組成,相對於之前講到的主從複製提供了故障自動轉移的功能 副本集實現數據同步的方式依賴於local資料庫中的oplog數據 oplog是存在與主節點或副本節點上的local資料庫中的一個固定集合,記錄了每一次主節點的寫... ...
  • 正文 該項目從2011年10月開始開發,知道現在已經有整整5年了。MongoDB也從一開始的大紅大紫到現在趨於平淡。 MongoCola這個工具在一開始定位的時候只是一個Windows版本的工具,期間也想改為WebPage版本,但是只是開了一個頭,也沒有繼續下去。 現在想想,可能這個決定是正確的,W ...
  • mysql簡介 1、什麼是資料庫 ? 資料庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫,它產生於距今六十多年前,隨著信息技術和市場的發展,特別是二十世紀九十年代以後,數據管理不再僅僅是存儲和管理數據,而轉變成用戶所需要的各種數據管理的方式。資料庫有很多種類型,從最簡單的存儲有各種 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...