MySQL类型介绍以及适用范围
1. 整型類型
Tinyint(8位)
范圍:無符號(hào)(0~256)、有符號(hào)(-128~127)
場(chǎng)景:一般用于存儲(chǔ)數(shù)字字典,常量表的id,因?yàn)閿?shù)據(jù)量十分有限,又是常量表,所以可以用它存儲(chǔ)
Smallint(16位)
范圍:無符號(hào)(0~65536)、有符號(hào)(-32768~32767)
場(chǎng)景:Tinyint的替代品,若常量表數(shù)據(jù)比較多,比如中國的省-市-自治區(qū)-區(qū)縣-村鎮(zhèn),到這個(gè)范圍下,基本夠用了。中國有65536個(gè)村鎮(zhèn)(區(qū)縣)嗎?
Mediumint(24位)
范圍:無符號(hào)(0~16777216)、有符號(hào)(-8388608~8388607)
場(chǎng)景:1000w以內(nèi)的數(shù)據(jù),這個(gè)若是日志表,又是在一段時(shí)間內(nèi)數(shù)據(jù)量可控,定時(shí)清理,Mediumint不失為是輕量級(jí)的int的一種id選擇。
Int(32位):大多數(shù)場(chǎng)景,一般Java的int也支持不了這么長(zhǎng)的整數(shù)位!
范圍:無符號(hào)(0~4294967296)、有符號(hào)(-2147483648~2147483647)
場(chǎng)景:大多數(shù)的自增id場(chǎng)景,基本夠用了。無符號(hào)40多億數(shù)據(jù),一般的中小型,互聯(lián)網(wǎng),基本夠用。
Bigint(64位)范圍:天文數(shù)字,在Java中必須特殊處理該數(shù)字類型——BigDecimal進(jìn)行處理。
范圍:無符號(hào)(0~18446744073709551616)、有符號(hào)(-922337203685478~922337203685477)。
場(chǎng)景:使用關(guān)系型數(shù)據(jù)庫存儲(chǔ)海量數(shù)據(jù)的id。千萬大一位是億,億大一位是兆,兆在大一位是什么????不過數(shù)據(jù)量在這個(gè)范圍,很難想象還用RDBMS進(jìn)行管理。
有符號(hào)與無符號(hào)的最大區(qū)別就是是否支持負(fù)數(shù)。Unsigned一旦被選擇上了,表示不允許負(fù)數(shù),也就是存儲(chǔ)無符號(hào)數(shù)。一般情況下無符號(hào)int類型的字段幾乎可以滿足系統(tǒng)要求了,就算是自增id類型。40多億的mysql數(shù)據(jù)量也已經(jīng)比較不小了。日交易量記錄上千萬比記錄,一個(gè)月也就區(qū)區(qū)3億記錄。如果大于這個(gè)數(shù)量級(jí)的數(shù)據(jù),又是實(shí)時(shí)數(shù)據(jù),應(yīng)該考慮分表分庫。或者借助NoSQL,將數(shù)據(jù)量散列拆分開。扯遠(yuǎn)了,這里就是告訴大家,數(shù)值類型字段支持的范圍。
2. 實(shí)數(shù)類型
其實(shí)基本上也就是指含有小數(shù)的數(shù),也就是浮點(diǎn)類型的數(shù)據(jù)類型。
Float:4個(gè)字節(jié)存儲(chǔ)
Double:8個(gè)字節(jié)存儲(chǔ)
Decimal:允許65個(gè)數(shù)字
這里有位仁兄總結(jié)的浮點(diǎn)型和定點(diǎn)型計(jì)算的文章,很不錯(cuò)http://www.163ns.com/zixun/post/5226.html。
基本上float可以用作百分比,有點(diǎn)誤差沒關(guān)系,double精確度比float大。而Decimal是完全金額類型計(jì)算。有的非敏感的,金額不是特別精確的系統(tǒng)業(yè)務(wù)場(chǎng)景,筆者也見過也有人使用double的。(你說那些不精確的,被四舍的錢都哪去了,都?xì)w誰了?100個(gè)人也就算了,如果涉及到1000w個(gè)人,每個(gè)人被四舍了的幾厘錢,甚至到分錢誤差,加起來夠買房子了吧?)
3. 字符串類型
字符串類型主要分為varchar、char與blob、text之間的PK了。
一定要將字符串類型的字段調(diào)優(yōu)到極致,因?yàn)閿?shù)據(jù)庫中,我們面對(duì)最多的類型也就是字符串,而我們每天面對(duì)的最多的場(chǎng)景也就是對(duì)文字的處理。
varchar類型:用于存儲(chǔ)可變長(zhǎng)的字符串,比定長(zhǎng)char類型節(jié)省空間(在通常情況下)。除非設(shè)置row_format=fixed,每一行是定長(zhǎng)存儲(chǔ)。varchar額外需要1~2個(gè)字節(jié)存儲(chǔ)字符串的長(zhǎng)度。當(dāng)列的最大長(zhǎng)度< span>字節(jié),用1個(gè)字節(jié)存儲(chǔ)長(zhǎng)度。否則采取2個(gè)字節(jié)。而且在Mysql5以后,varchar字段不會(huì)將末尾的空格剔除了。
char類型:char是定長(zhǎng)類型,那么在存取過程中,會(huì)根據(jù)字符串長(zhǎng)度老老實(shí)實(shí)分配足夠的空間。定長(zhǎng)字符串類型不容易產(chǎn)生磁盤碎片,對(duì)于定長(zhǎng)短列,char比varchar更有效。比如存儲(chǔ)MD5或者SHA1值。
Blob類型:
存儲(chǔ)二進(jìn)制類型的大字段數(shù)據(jù),沒有排序規(guī)則以及字符集。
類型成員有:tinyblob;blob;mediumblob;longblob。
一般情況下存儲(chǔ)圖片、文檔文件,用之。存儲(chǔ)引擎在blob很大時(shí)借助外部存儲(chǔ)(操作系統(tǒng)FS接口)進(jìn)行特殊處理。
Text類型-對(duì)應(yīng)于Oracle的clob:
存儲(chǔ)字符方式存儲(chǔ)大字段類型數(shù)據(jù),有排序規(guī)則和字符集。
類型成員有:tinytext;text;mediumtext;longtext。
一般情況下存儲(chǔ)文章,html頁面內(nèi)容。同理,在text很大時(shí)借助外部存儲(chǔ),進(jìn)行特殊處理。
經(jīng)驗(yàn):
1)一般獲取blob或者text記錄的時(shí)候,將原始記錄值進(jìn)行截?cái)唷猻ubstring(字段名,大小)函數(shù)。之后再轉(zhuǎn)換成為相應(yīng)的字符串。這樣可以使用到Mysql的內(nèi)存臨時(shí)表了,而避免了從磁盤上去取數(shù)據(jù)的IO。
2)臨時(shí)表的大小超過配置的max_ heap_table_size(tmp_table_size)的時(shí)候內(nèi)存臨時(shí)表將使用磁盤臨時(shí)表。(也就是說將內(nèi)存密集型的case負(fù)載到了IO密集型)
4. 枚舉類型
Mysql存取枚舉,緊湊。一般代替常用的字符串類型。Mysql將枚舉列表的個(gè)數(shù)將其壓縮位1~2個(gè)字節(jié)存儲(chǔ)。之后,再將每一個(gè)枚舉值保存為一個(gè)整數(shù)數(shù)字,將整數(shù)數(shù)字與枚舉字符串的值做鍵值對(duì)兒的映射。也就是說,實(shí)際上表中引用枚舉的字段值存儲(chǔ)的是數(shù)字。
實(shí)驗(yàn)證明,著實(shí)如此。
CREATE TABLE user2 (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
type enum(‘魏’,’蜀’,’吳’) CHARACTER SET utf8 DEFAULT ‘魏’,
PRIMARY KEY (id)
) ENGINE=InnoDB
執(zhí)行查詢的時(shí)候?qū)ype字段都加上一個(gè)數(shù)字,得出來的結(jié)果居然是數(shù)字,證明枚舉底層使用的是數(shù)值類型進(jìn)行的存取枚舉。而且若是非要枚舉做外鍵,那么基于基準(zhǔn)測(cè)試給出的結(jié)果,枚舉與枚舉之間的外鍵關(guān)聯(lián)QPS是最高的。Mysql內(nèi)部對(duì)枚舉的數(shù)值做了相應(yīng)的排序優(yōu)化。
場(chǎng)景:能夠使用枚舉做常量時(shí),盡量不要用字符串類型。
5. 日期和時(shí)間
日期和時(shí)間類型有以下幾種:date;time;year;timestamp;datetime;
date:相當(dāng)于截取了datetime的date,范圍時(shí)從公元0年1月1日,可以到公元9999年12月31日。
time:相當(dāng)于截取了datetime的time,范圍就是一天的24小時(shí)。
year:比較尷尬,臨界值是69和70,輸入69,基本上代表2069年。70就是代表1970年。范圍值是0~99,分別代表,0~69:2000~2069;70~99:1970~1999。不是特殊情況,基本棄用。
最常用的應(yīng)該是datetime與timestamp。
datetime:使用8個(gè)字節(jié)存儲(chǔ)日期與時(shí)間,那么可以得出結(jié)論,date使用4個(gè)字節(jié),time也是4個(gè)字節(jié)。精確到秒級(jí)別,與時(shí)區(qū)無關(guān)。范圍是從1000年到9999年的日期和時(shí)間。
timestamp:使用4個(gè)字節(jié)存儲(chǔ)日期與時(shí)間,不過范圍只能表示從1970年~2038年。如果沒有什么意外,看到這篇文章的同志們,大多數(shù)都能活到那一年,之后會(huì)不會(huì)出現(xiàn)timestamp2這種類型來擴(kuò)大時(shí)間戳的范圍,那就得看是不是有支持更大整型數(shù)值的類型出現(xiàn)了。在應(yīng)用層使用long類型插入該字段的值,最后可以存儲(chǔ)正確的日期時(shí)間,而且該字段依賴于時(shí)區(qū)。做國際化產(chǎn)品的時(shí)候需要特別注意!
6. SET類型
用于存儲(chǔ)集合類型的集合類,集合元素里面基本上存儲(chǔ)的是常量值,書中舉了一個(gè)比較貼切的列子,就是權(quán)限控制的權(quán)限集合。其實(shí)也是代表一個(gè)人的聚合元素。但是呢,其實(shí)權(quán)限控制完全用整形也可以表示,就是類似于linux的權(quán)限數(shù)字,比如777代表該文件夾無任何限制可以被其他用戶使用,訪問,修改。
對(duì)于SET類型(mysql數(shù)據(jù)庫中),在Java應(yīng)用層獲取該類型的值,使用字符串就可以,不過獲取的值還需要另外處理,拆解字符串為字符串?dāng)?shù)組(使用,進(jìn)行拆分)。
7. 特殊字段-ipv4地址的存取
存取ip地址可以使用mysql中的兩個(gè)函數(shù)將ipv4字符串轉(zhuǎn)換成為整數(shù),整數(shù)的存取比字符串快。兩個(gè)特殊的函數(shù)是:
Ip地址轉(zhuǎn)成數(shù)字:select inet_aton(“192.168.1.1”);
結(jié)果
+————————–+
| inet_aton(“192.168.1.1”) |
+————————–+
| 3232235777 |
+————————–+
數(shù)字轉(zhuǎn)換成為ip地址
select inet_ntoa(3232235778);
結(jié)果為:
+———————–+
| inet_ntoa(3232235778) |
+———————–+
| 192.168.1.2 |
+———————–+
總結(jié)
以上是生活随笔為你收集整理的MySQL类型介绍以及适用范围的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL数据库优化技巧
- 下一篇: SQL语句之left join、righ