国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

深入Mysql - 談談我對數據類型的認識

SillyMonkey / 3663人閱讀

摘要:要確保沒有低估需要存儲的值的范圍,更小是相對與數據類型的最大值范圍來講的。如果無法確定哪個數據類型是最好的,就選擇你認為不會超過范圍的最小類型。整數類型有兩個類型的數字整數和實數。列默認為,這與其他的數據類型不一樣。

簡述

良好的邏輯設計和物理設計是高性能系統的基石,比如反范式設計可以加快某些類型的查詢同時也會影響另外一些類型的查詢效率,所以我們必須重視Mysql對于數據庫的設計(本文主要講述表字段類型對于數據庫性能的影響)。

由于Mysql獨有的特性和實現細節對性能的影響是很明顯的,因為做好Mysql數據庫的設計很關鍵。對于數據庫設計,我們不得不提表字段的類型選擇,由于Mysql支持的數據類型非常多,因此如何選擇正確的數據類型對于獲得高性能至關重要。不管要存儲的數據是什么類型,我們都需要根據一些數據庫設計原則來考慮。

選擇數據類型的思考

更小的通常是更好的(一般情況下,應該盡可能使用正確存儲數據的最小數據類型。)

為什么呢?

(1) 因為更小的數據類型通常更快,因為它們占用更少的磁盤、內存和CPU緩存,并且處理時需要的CPU周期也更短。
(2) 要確保沒有低估需要存儲的值的范圍,更小是相對與數據類型的最大值范圍來講的。
(3) 如果無法確定哪個數據類型是最好的,就選擇你認為不會超過范圍的最小類型。

簡單就好(簡單數據類型的操作通常需要更短的CPU周期。)

為什么呢?下面有幾個例子說明一下原因。

(1) 整型比字符串操作代價更低,因為字符串集和校對規則(排序規則)是的字符比較比整型比較更復雜。
(2) 存儲日期和時間應該使用Mysql內建的類型(date,time,datatime)。
(3) IP地址的存儲應該用整型(int)。

盡量避免 NULL (空值)

為什么呢?

(1) 很多表都包含可為NULL的列,就算程序并不需要保存NULL也是如此,這是因為列的默認屬性就是可為NULL。通常情況下最好指定列NOT NULL,除非真的需要存儲NULL。
(2) 如果查詢中包含可為NULL的列,對于Mysql來說是很難優化的,因為NULL的列使得索引,索引統計和值比較都更復雜。可為NULL的列會使用更多的存儲空間,在Mysql里也需要特殊處理。當可為NULL的列被索引時,每個索引記錄需要一個額外的字節,在MyISAM里甚至還可能導致固定大小的索引變成可變大小的索引。
(3) 通常把可為NULL的列改為NOTNULL帶來性能提升比較小,如果計劃在列上建索引的話,就應該盡量避免設計成可為NULL的列。(也有一個例外,那就是在InnoDB中,會使用多帶帶的位(bit)來存儲NULL值,所以對稀疏數據有很好的空間效率。)

總結

在為列選擇數據類型時,第一步需要確定合適的大類型(數字、字符串、時間等等),這通常是很簡單的,那么下一步就是選擇具體的類型了。

很多Mysql的數據類型可以存儲相同類型的數據,只是存儲的長度和范圍不一樣、允許的精度不同,或者需要的物理空間(磁盤和內存空間)不同。相同大類型的不同子類型數據有時候也有一些特殊的行為和屬性。
比如:DATATIME 和 TIMESAMP列都可以存儲相同類型的數據(時間和日期)并且精確到秒,然而TIMESTAMP只使用DATATIME一半的存儲空間,并且會根據時區變化,具有特殊的自動更新能力。另外TIMESTAMP允許的時間范圍要小得多,有時候它的特殊能力會成為障礙,這都是我們開發者需要考慮的。

整數類型

有兩個類型的數字:整數(whole number)和實數(real number)。

如果存儲整數,可以使用這幾種整數類型:TINNYINT(8)、SMALLINT(16)、MEDIUMINT(24)、INT(32)、BIGINT(64)。

整數類型有可選的的UNSIGNED屬性,表示不允許為負值,這大致可以是正數的上限提高一倍。

比如:TINYINT UNSIGNED可以存儲的范圍是0~255,而TINYINT的存儲范圍是-127~128.

有符號和無符號類型使用相同的存儲空間,并具有相同的功能.

因此可以根據實際情況選擇合適的類型。

你的選擇決定Mysql是怎么在內存和磁盤中保存數據的。

整數一般選擇64位的BIGINT整數,即使在32位環境下也是如此。(但是一些聚合函數是例外,它們是使用DECIMAL或DOUBLE進行計算的)

Mysql可以為整數類型指定寬度。

比如:INT(11),對大多數應用這是沒有意義的:它不會限制值的合法范圍,只是規定了Mysql的一些交互工具(例如Mysql命令行客戶端)用來顯示字符的個數。對于存儲和計算來講,INT(1)和INT(20)是相同的。

一些第三方存儲引擎(比如Infobright)有時也有自定義的存儲格式和壓縮方案,并不一定使用常見的Mysql內置引擎的方式。 
實數類型

實數是帶有小數部分的數字。

它們不只是未來存儲小數部分,也可以使用DECIMAL存儲比BIGINT還要大的整數。Mysql既支持精確類型,也支持不精確類型。

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

在Mysql5.0或者更高版本支持精確運算,而在Mysql4.1以及更早版本中使用浮點運算會出現異常(主要是精度的損失導致的)。

FLOAT和DECIMAL類型都可以指定進度。

對于DECIMAL列可以指定小數點前后所允許的最大位數,這會影響列的空間消耗。有很多方法可以指定FLOAT(浮點)列所需要的精度,這會使得Mysql悄悄選擇了不同的數據類型,或者在存儲時對值進行取舍,但是這些精度往往都是非標準的,所以一般建議只指定數據類型不指定精度。

由于需要額外的空間和計算開銷,所以應該盡量只在對小數進行精確計算時才使用DECIMAL。

比如存儲財務數據,但是如果數據量比較大的時候,可以考慮使用BIGINT代替DECIMAL,將需要存儲的貨幣單位根據小數的位數乘以相應的倍數即可。

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

字符串類型

Mysql支持多種字符串類型,每種類型還有很多變種。其中VARCHAR和CHAR是兩種最主要的字符串類型。

注意:Mysql存儲引擎存儲CHAR或者VARCHAR值的方式在內存中和在磁盤上可能不一樣,所以Mysql服務器從存儲引擎讀取的值可能需要轉換為另外一種存儲格式。

VARCHAR類型用于存儲可變長字符串,是最常見的字符串數據類型。

VARCHAR比定長類型更節省空間,因為它僅使用必要的空間(越短的字符串使用越少的空間)。

VARCHAR需要使用1或2個額外字節記錄字符串的長度。

VARCHAR節省了存儲空間,所以對性能是有幫助的。

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

CHAR類型是定長的。(Mysql總是根據定義的字符串長度分配足夠的空間)

CHAR適合存儲很短的字符串,或者所有值都接近同一個長度。

和VARCHAR和CHAR類似的類型還有BINARY和VARBINARY,它們存儲的都是二進制字符串。

注意:使用VARCAHR(5)和VARCHAR(200)存儲“hello”的空間開銷都是一樣的,那么使用更短的列有什么優勢呢?(事實證明有很大的優勢)

更長的列會消耗更多的內存,因為Mysql通常會分配固定大小的內存塊來保存內部值。尤其是使用內存臨時表進行排序或者操作時會特別糟糕。在利用磁盤臨時表進行排序時也同樣糟糕。

注意:歸根到底,最好的策略是只分配真正需要的空間。

BLOB和TEXT類型

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

實際上它們分別屬于兩組不同的數據類型家族:
字符串類型有TINYTEXT、SMALLTEXT、TEXT、MEDIUMTEXT、LONGTEXT;

二進制類型有TINYBLOB、SMALLBLOB、BLOB、MEDIUMBLOB、LONGBLOB;

ENUM類型

可以使用枚舉(ENUM)代替字符串類型。很多時候建議使用枚舉列代替常用的字符串類型。

(1)枚舉列可以把一些不重復的字符串存儲成一個預定義的集合。
(2)Mysql在存儲枚舉時非常緊湊,會根據列表值的數量壓縮到一到兩個字節中。
(3)Mysql在內部會將每個值在列表中的位置保存為整數,并且在表的.frm文件中保存“數字-字符串”映射關系的“查找表”。

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

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

注意:由于Mysql把每個枚舉值保存為整數,并且必須進行查找才能轉換為字符串,所以枚舉列有一些開銷。

日期和時間類型

Mysql有很多類型可以保存日期和時間值,比如YEAR和DATE。

Mysql能存儲的最小時間粒度為秒(MariaDB支持微秒級別的事件類型)。但是Mysql也可以使用微秒級別的粒度進行臨時運算。

大部分時間類型都沒有替代品,因此沒有什么是最佳選擇的問題。

接下來唯一的問題是保存日期和時間的時候需要做什么。

DATETIME

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

TIMESTAMP

(1)TIMESTAMP類型保存了從1970年1月1日午夜以來的秒數,它和UNIX時間戳相同。
(2)TIMESTAMP只使用4個字節的存儲空間,因此它的范圍比DATETIME小得多。
(3)TIMESTAMP顯示的值依賴時區。

DATETIME和TIMESTAMP的對比:

(1)默認情況下,如果插入時沒有指定第一個TIMESTAMP列的值,Mysql則設置這個列的值為當前時間。(這是DATETIME沒有的特性)
(2)在插入一行記錄時,Mysql默認也會更新第一個TIMESTAMP列的值。
(3)TIMESTAMP列默認為NOT NULL,這與其他的數據類型不一樣。

總結

(1)除了特殊行為之外,通常也應該盡可能使用TIMESTAMP,因為它比DATETIME空間效率更高。
(2)一般來講不建議把UNIX時間戳保存為整數值,這不會帶來任何收益,用整數保存時間戳格式通常不方便處理。
(3)如果需呀存儲比秒更小粒度的日期和時間值,可以使用BIGINT類型存儲微秒級別的時間戳,或者使用DOUBLE存儲秒之后的小數部分,也可以用MariaDB替代Mysql。

位數據類型

BIT定義一個包含單個位的字段,BIT(2)存儲2個位,最大長度是64個位。

注意:一般建議謹慎使用BIT類型,對于大部分應用來講最好避免使用這種類型。

選擇標識符

為identifier(標識列)選擇合適的數據類型非常重要。

一般來講更有可能用標識列與其他值進行比較,或者通過標識列尋找其他列。

當選擇標識列的類型時,不僅僅需要考慮存儲類型,還需要考慮Mysql對這種類型怎么執行計算和比較。

一旦選定了一種類型,要確保在所有關聯表中都使用同樣的類型。

在可以滿足值的范圍需求,并且預留未來增長空間的前提下,應該選擇最小的數據類型。

注意:整數通常是標識列最好的選擇,因為它們很快而且可以使用AUTO_INCREMENT。
注意:ENUM和SET是最糟糕的選擇了;如果可能也盡可能避免使用字符串作為標識列,因為它們很消耗空間并且通常比數字類慢。

全文總結

對于數據庫設計,一定要三思而后行,選擇最適合的數據列類型還有決定數據列的大小都是很關鍵的一步。
其實大可不必驚慌,無論對于任何類型需求的數據表設計,你只要記住一個原則,很重要很重要很重要的原則:盡可能使用正確存儲數據的最小數據類型。

PS:很晚了,總結先草草了事,日后還會更新......

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30278.html

相關文章

  • 深入Mysql - 談談我對數據類型認識

    摘要:要確保沒有低估需要存儲的值的范圍,更小是相對與數據類型的最大值范圍來講的。如果無法確定哪個數據類型是最好的,就選擇你認為不會超過范圍的最小類型。整數類型有兩個類型的數字整數和實數。列默認為,這與其他的數據類型不一樣。 簡述 良好的邏輯設計和物理設計是高性能系統的基石,比如反范式設計可以加快某些類型的查詢同時也會影響另外一些類型的查詢效率,所以我們必須重視Mysql對于數據庫的設計(本...

    junbaor 評論0 收藏0
  • 談談我對面向對象以及類與對象理解

    showImg(https://segmentfault.com/img/remote/1460000007103938?w=391&h=247); 文章最初發表于我的個人博客非典型性程序猿 對于剛接觸JAVA或者其他面向對象編程語言的朋友們來說,可能一開始都很難理解面向對象的概念以及類和對象的關系。筆者曾經帶過一個短期培訓班教授java入門基礎,在最后結束課程的時候,還有很多同學不太理解面向對象...

    walterrwu 評論0 收藏0
  • 計算機常識 - 收藏集 - 掘金

    摘要:使用簡記后端掘金全稱為即消息隊列。優測優社區干貨精選老司機亂談編輯器之神掘金前言是一種信仰,我自從年有了這個信仰,已經個年頭了。 PHP 程序員進階學習書籍參考指南 - 后端 - 掘金PHP程序員進階學習書籍參考指南 @heiyeluren lastmodify: 2016/2/18 ... 當我們在談論前端加密時,我們在談些什么 - 前端 - 掘金潘建旭,豈安科技(www.bigse...

    Yi_Zhi_Yu 評論0 收藏0

發表評論

0條評論

SillyMonkey

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<