MySQL-語法-字段類型

字段類型

? 整型

TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT 分別使用 8, 16, 24, 32, 64 位存儲空間,一般情況下越小的列越好。

INT(11) 中的數(shù)字只是規(guī)定了交互工具顯示字符的個數(shù),對于存儲和計算來說是沒有意義的。

? 浮點數(shù)

FLOAT 和 DOUBLE 為浮點類型,DECIMAL 為高精度小數(shù)類型。CPU 原生支持浮點運算,但是不支持 DECIMAl 類型的計算,因此 DECIMAL 的計算比浮點類型需要更高的代價。

FLOAT、DOUBLE 和 DECIMAL 都可以指定列寬,例如 DECIMAL(18, 9) 表示總共 18 位,取 9 位存儲小數(shù)部分,剩下 9 位存儲整數(shù)部分。

int(10)代表的含義:

int(10)的意思是假設(shè)有一個變量名為id,它的能顯示的寬度能顯示10位。

在使用id時,假如我給id輸入10,那么mysql會默認給你存儲0000000010。

當你輸入的數(shù)據(jù)不足10位時,會自動幫你補全位數(shù)。

假如我設(shè)計的id字段是int(20),那么我在給id輸入10時,mysql會自動補全18個0,補到20位為止。

總結(jié):

int(M)的作用于int的范圍明顯是無關(guān)的,int(M)只是用來顯示數(shù)據(jù)的寬度,我們能看到的寬度。

當字段被設(shè)計為int類型,那么它的范圍就已經(jīng)被寫死了,與M無關(guān)。

? 字符串

主要有 CHAR 和 VARCHAR 兩種類型,一種是定長的,一種是變長的。

字符串類型選擇策略

當我們?yōu)樽址愋偷淖侄芜x取類型的時候,判斷該選取VARCHAR還是CHAR,我們可以從以下幾個方面來考慮:

  • 該字段數(shù)據(jù)集的平均長度與最大長度是否相差很小,若相差很小優(yōu)先考慮CHAR類型,反之,考慮VARCHAR類型。

  • 若字段存儲的是MD5后的哈希值,或一些定長的值,優(yōu)先選取CHAR類型。

  • 若字段經(jīng)常需要更新,則優(yōu)先考慮CHAR類型,由于CHAR類型為定長,因此不容易產(chǎn)生碎片。

  • 對于字段值存儲很小的信息,如性別等,優(yōu)先選取CHAR類型,因為VARCHAR類型會占用額外的字節(jié)保存字符串長度信息。

總之一句話,當我們能夠選取CHAR類型的時候,或者說空間消耗相對并不是影響因素的重點時,盡量選取CHAR類型,因為在其他方面,CHAR類型都有著或多或少的優(yōu)勢。而當空間消耗成為了很大的影響因素以后,我們則考慮使用VARCHAR類型

varchar(50)代表的含義:

varchar(50)中50的涵義最多存放50個字符,varchar(50)和(200)存儲hello所占空間一樣,但后者在排序時會消耗更多內(nèi)存,因為order by xxx采用fixed_length計算xxx長度。

早期MySQL版本中50表示字節(jié)數(shù),現(xiàn)在表示字符數(shù)

? BLOB 和 TEXT

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

與其他類型不同,MySQL把每個BLOB和TEXT值當做一個獨立的對象去處理。當BLOB和TEXT值太大時,InnoDB會使用專門的“外部”存儲區(qū)域來進行存儲,此時每個值在行內(nèi)需要1~4個字節(jié)存儲一個指針,然后在外部存儲區(qū)域存儲實際的值。

MySQL對BLOB和TEXT列進行排序與其他類型是不同的:它只對每個列的最前max_sort_length個字節(jié)而不是整個字符串做排序。同樣的,MySQL也不能將BLOB或TEXT列全部長度的字符串進行索引。

? 時間和日期

MySQL 提供了兩種相似的日期時間類型: DATETIME 和 TIMESTAMP。

? 1. DATETIME

能夠保存從 1001 年到 9999 年的日期和時間,精度為秒,使用 8 字節(jié)的存儲空間。

它與時區(qū)無關(guān)。

默認情況下,MySQL 以一種可排序的、無歧義的格式顯示 DATETIME 值,例如“2008-01-16 22:37:08”,這是 ANSI 標準定義的日期和時間表示方法。

? 2. TIMESTAMP

和 UNIX 時間戳相同,保存從 1970 年 1 月 1 日午夜(格林威治時間)以來的秒數(shù),使用 4 個字節(jié),只能表示從 1970 年 到 2038 年。

它和時區(qū)有關(guān),也就是說一個時間戳在不同的時區(qū)所代表的具體時間是不同的。

MySQL 提供了 FROM_UNIXTIME() 函數(shù)把 UNIX 時間戳轉(zhuǎn)換為日期,并提供了 UNIX_TIMESTAMP() 函數(shù)把日期轉(zhuǎn)換為 UNIX 時間戳。

默認情況下,如果插入時沒有指定 TIMESTAMP 列的值,會將這個值設(shè)置為當前時間。

應(yīng)該盡量使用 TIMESTAMP,因為它比 DATETIME 空間效率更高。

? 選擇表示符(identifier)

整數(shù)類型通常是標識列的最佳選擇,因為它們很快并且可以使用AUTO_INCREMENT。 如果可能,應(yīng)該避免使用字符串類型作為標識列,因為它們很耗空間,并且比數(shù)字類型慢。 對于完全隨機的字符串也需要多加注意,例如MD5(),SHA1()或者UUID()產(chǎn)生的字符串。這些函數(shù)生成的新值會任意分布在很大的空間內(nèi),這會導(dǎo)致INSERT以及一些SELECT語句變得很慢:

  • 因為插入值會隨機的寫入到索引的不同位置,所以使得INSERT語句更慢。這會導(dǎo)致葉分裂、磁盤隨機訪問。

  • SELECT語句會變的更慢,因為邏輯上相鄰的行會分布在磁盤和內(nèi)存的不同地方。

  • 隨機值導(dǎo)致緩存對所有類型的查詢語句效果都很差,因為會使得緩存賴以工作的局部性原理失效。

? 選擇優(yōu)化的數(shù)據(jù)類型

  • 更小的通常更好;更小的數(shù)據(jù)類型通常更快,因為它們占用更少的磁盤、內(nèi)存和CPU緩存,并且處理時需要的CPU周期也更少;

  • 簡單就好;例如,整形比字符串操作代價更低;實用內(nèi)建類型而不是字符串來存儲日期和時間;用整形存儲IP地址等;

  • 盡量避免NULL;如果查詢中包含可為NULL的列,對MySQL來說更難優(yōu)化,因為可為NULL 的列使得索引、索引統(tǒng)計和值比較都更復(fù)雜。盡管把可為NULL的列改為NOT NULL帶來的性能提升比較小,但如果計劃在列上創(chuàng)建索引,就應(yīng)該盡量避免設(shè)計成可為NULL的列;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容