程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> Mysql 數據類型使用說明,mysql數據類型

Mysql 數據類型使用說明,mysql數據類型

編輯:MySQL綜合教程

Mysql 數據類型使用說明,mysql數據類型


  FLOAT 和DOUBLE 類型支持使用標准的浮點運算進行近似計算。

  DECIMAL類型用於存儲精確的小數。

  因為cpu不支持對DECIMAL的直接計算,所以在Mysql5.0及更高的版本中,MYSQL服務器自身實現了DECIMAL的高精度計算。相對而言,cpu直接支持原生浮點計算,所以浮點運算冥想更快。

  浮點和DECIMAL類型都可以指定精度。對於DECIMAL列,可以指定小數點前後允許的最大位數。這會影響到列的空間消耗。Mysql5.0和更高將數字打包保存到一個二進制字符串中(每4個字節存儲9個數字)。例如DECIMAL(18,9)小數點兩邊各存儲9個數字,一共使用9個字節:小數點簽的數字用4個字節,小數點後的數字用4個字節,小數點本身占一個字節。

  MYSQL 5.0 和更高的版本中的decimal類型允許最多65個數字。而早期的Mysql版本中這個限制是254個數字,並且保存為未壓縮的字符串(每個數字一個字節)。然而這些(早期)版本實際上並不能在計算中使用這麼大的數字,因為DECIMAL只是一種存儲格式,在計算中DECIMAL會轉化成DOUBLE類型。

  浮點類型在存儲同樣范圍的值時,通常比DECIMAL使用更少的空間。FLOAT使用4個字節存儲。DOUBLE占用8個字節,相比FLOAT有更高的精度和更大的范圍。和證書類型一樣,能選擇的只是存儲類型;Mysql使用DOUBLE作為內部浮點計算的類型。

  因為需要額外的空間和計算開銷,所以應該盡量只在對小數進行精確計算時才使用DECIMAL——例如存儲財務數據。但數據量比較大的時候,可以考慮使用BIGINT帶鐵DECIMAL,將需要存儲的貨幣單位根據小叔點的位數乘以相應的倍數即可。假設要存儲財務數據精確到萬分之一分,則可以把所有金額乘以100W,然後將結果存儲在BIGINT裡,這樣可以同時避免浮點存儲計算不精確和DECIMAL精確計算代價高的問題。

  字符串類型

  VARCHAR和CHAR類型

  VARCHAR和CHAR是兩種主要的字符串類型。不幸的是,很汗精確的解釋這些值是怎麼存儲在磁盤和內存中的,因為這跟存儲引擎的具體實現有關。

  VARCHAR

  VARCHAR 類型用於存儲可變長字符串,是最常見的字符串數據類型。它比定長類型更省空間,因為它僅使用必要的空間。有一種情況例外:如果MYSQL表使用ROW_FORMAT=FIXED創建的話,每一行都會使用定長存儲,這很浪費空間。

  VARCHAR需要使用1-2個額外字節記錄字符串的長度:如果勒的最大長度小於或等於255,則只需一個字節表示,否則使用2個字節。假設使用latin1字符集,一個varchar(10)的列需要11個字節存儲空間。VARCHAR(1000)則需要1002個字節,因為需要2個字節存儲長度信息。

  VARCHAR節省了存儲空間,所以對性能也有幫助。但是,由於行是變長的,在UPDATE時可能使行變得比原來更長,這就導致需要做額外的工作。如果一個行占用的空間增長,並且在頁內沒有更多的存儲空間可以存儲,在這種情況下,不同的存儲引擎醋栗方式是不一樣的。例如MYISAM 會將行拆成不同的片段存儲,INNODB則需要分裂頁來使行可以放進頁內。

  下面這些情況使用VARCHAR是合適的:字符串列的最大長度比平均長度大很多;列更新的很少,所以碎片不是問題;使用了像utf-8這樣復雜的字符集,每個字符都使用不同的字節數進行存儲。

  在5.0或者更高的版本,Mysql在存儲和檢索時會保留末尾空格。但在4.1或更老的版本,mysql會提出末尾空格。

  INNODB則更靈活,它可以把過長的varchar存儲為blob,我們稍後討論這個問題。

  CHAR

  CHAR類型是定長的:MYSQL 總是根據定義的字符串長度分配足夠的空間。當存儲CHAR時,MYSQL會刪除所有的末尾空格。CHAR會根據需要采用空格進行填充以方便比較。

  char適合存儲很短的字符串,或者所有值都近似一個長度。例如,char非常適合存儲密碼的MD5值。對於經常變更的數據,CHAR也比VARCHAR更好,因為訂場的char類型不容易產生碎片。對於非常短的列,char比varchar 在存儲效率上也更有效率。例如用char(1) 來存儲只有Y和N的值,如果采用單字節字符集只需要一個字節,但是varchar(1)卻需要2個字節,因為還有一個記錄長度的額外字節。

  填充和街區空格的行為在不同的存儲引擎是一樣的,因為這是在mysql服務器層進行處理的。

  與char和varchar類似的類型還有binary和varbinary,它們存儲的是二進制字符串。二進制字符串跟常規字符串非常類似,但是二進制字符串存儲的是字節碼而不是字符。填充也不一樣:MYSQL填充binary采用的是\0 (零字節)而不是空格,在檢索時也不會去掉填充值。

  當需要存儲二進制數據,並且希望mysql使用字節碼而不是字符碼進行比較時,這些類型是非常有用的。而精致比較的優勢不僅僅體現在大小寫敏感上。MYSQL比較binary字符串時,每次按一個字節,並且根據該字節的數值進行比較。因此二進制比較比字符比較簡單很多,所以也就更快。

---------------------------------------------------------------------------------------------------------------------------------------------------------------

  tips:使用varchar(5)和varchar(200)存儲‘hello’的空間開銷是一樣的。name使用更短的列有什麼優勢嗎?

     事實證明有很大的優勢。更長的列會消耗更多的內存,因為mysql通常會分配固定大小的內存來保持內部值。友情是使用內存臨表進行排序或操作時會特別糟糕。在利用磁盤臨表時進行排序時也同樣糟糕。

    所以最好的策略是只分配真正需要的空間。

BLOB 和TEXT類型

  BLOB和TEXT都是為存儲很大的數據而設計的字符串數據類型,分別采用二進制和字符串方式存儲。

  實際上,它們分別屬於兩組不同的數據類型家族:字符類型是TINYTEXT,SMALLTEXT,TEXT,MEDIUMTEXT,LONGTEXT;對應二進制類型是TINYBLOB,SMALLBLOB,BLOB,MEDIUMBLOB,LONGBLOB。BLOB是SMALLBLOB的同義詞,TEXT是SMALLTEXT的同義詞。

  與其他類型不同,MYSQL把每個BLOB和TEXT值當作一個獨立的對象處理。存儲引擎在存儲時通常會做特殊處理。當blob和text值太大時,INNODB會使用專門的“外部”存儲區來進行存儲,因此每個值在行內需要1-4個字節存儲一個指針,然後在外部存儲區域存儲世紀的值。

  BLOB和TEXT家族之間的不同是BLOB類型存儲的是二進制數據,沒有排序規則或字符集,而text類型有字符集和排序規則。

  MYSQL對BLOB和TEXT列進行排序與其他類型是不同的:它只對每個列的最掐面max_sort_length字節而不是整個字符串做排序。如果只需要排前面一小部分字符集,則可以減小max_sort_length的配置,或者使用order by sustring(column,length)。

  mysql不能將blob和text列全部長度的字符串進行索引,也不能使用這些索引消除排序。

  使用枚舉(ENUM)代替字符串類型

  有時候可以使用枚舉列代替常用的字符串類型。枚舉列可以把一些不重復的字符串存儲成一個預定的集合。mysql 在存儲枚舉時非常緊湊,會根據列表值得數量壓縮到一個或者兩個字節中。mysql在內部會將每個值在列表中的位置保存為整數,並且在表的.frm文件中保存‘數字-字符串’映射關系的查找表。

  另外一個令人吃驚的地方是,枚舉字段是按照內部存儲的整數而不是定義的字符串進行排序的。

  枚舉最不好的地方是,字符串列表是固定的,添加或者刪除字符串必須使用ALTER TABLE。因此對於一系列未來可能會改變的字符串,使用枚舉不是一個好主意,出發能接受只在列表尾添加元素

  由於myslq把每個枚舉值保存為整數,並且必須進行查找才能轉換為字符串,所以枚舉列有一些開銷。通常枚舉的列表都是比較小的,所以開銷還可以控制,蛋也不能保證一直如此。在特定的情況下,把char/varchar列與枚舉列進行關聯,可能會比直接關聯char/varchar 列更慢。

  日期和時間類型

  DATETIME

  這個類型能保存大范圍的值,從1001到9999年,精度為秒。它把日期和時間封裝到各式為YYYYMMDDHHMMSS的整數中,與時區無關使用8個字節的存儲空間。

  默認情況下mysql以一種可排序的、無歧義的各式顯示datetime值,例如‘2015-11-17 23:20:00’。這是ANSI標准定義的日期和時間的表示方法。

  TIMESTAMP

  就像它的名字一樣,TIMESTAMP類型保存了從1970年1月1日午夜(格林尼治標准時間)以來的秒數,它和Unix時間戳相同。TIMESTAMP只使用4個字節的存儲空間,因此它的范圍比datetime小的多:只能表示1970年到2038年。mysql 提供了FROM_UNIXTIME()函數把Unix時間戳轉化為日期,並提供了UNIX_TIMESTAMP()函數把日期轉換為UNIX時間戳。

  timestamp顯示的值也依賴於時區。mysql服務器、操作系統、以及客戶端連接都有時區設置。

  因此存儲值為0的timestamp在美國東部時區顯示為1969-12-31 19:00:00 與格林尼治時間差5個小時。有必要強調一下這個區別:如果在多個時區存儲或訪問數據,timestamp和datetime的行為將很不一樣。前者提供的值與時區有關系,後者則保留文本表示的日期時間。

  timestamp也有datetime沒有的特殊屬性。默認情況下,如果插入時沒有指定第一個timestamp列的值,mysql則設置這個列的值為當前時間,在插入一行記錄時,mysql也會默認更細第一個timestamp的值(除非在update語句中明確指定了值)。你可以配置任何timestamp列的插入和更新行為。最後,timestamp 列默認為not null,這也和其他數據類型不一樣。

  除了特殊行為之外,通常也應該盡量使用timestamp ,因為他比datetime空間效率更高。有時候,人們會將Unix時間戳存儲為整數值,但這並不會帶來任何收益。使用整數保存時間戳的格式通常不方便處理,所以我們不推薦這樣做。

  如果需要存儲比秒更小粒度的日期和時間值怎麼辦?myslq 目前沒有提供合適的數據類型,但是可以使用自己的存儲格式:可以使用bigint類型存儲微妙級別的時間戳或者使用double存儲秒之後的小數部分。或者也可以使用MariaDB來代替mysql。

  位數據類型(BIT)

  BIT列的最大長度是64個位。

  MYSQL把bit當作字符串類型,而不是數字類型。當檢索bit(1)的值時,結果是一個包含二進制0或1的字符串,而不是ASCII碼的‘0’或‘1’。然而,在數字上下文的場景中檢索時,記過是將位字符串轉換成數字。如果需要和另外的值比較結果,一定要記住這一點。例如:如果存儲一個值b‘00111001’二進制的值為57,到bit(8)的列並檢索它,的到的內容是字符串碼為57的字符串。也就是說,的到ascii碼為57的字符“9”。但是在數字上下文場景中,的到的數字是57.

  這是相當令人費解的,所以應該謹慎的使用bit類型。對於大部分應用最好避免使用這種類型。

  如果想在一個bit的存儲空間中粗糙一個true或false值,另一個方法是創建一個可以為空的char(0)列。改列可以保持空值(NULL)或者長度為0的字符串(空字符串)。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved