數值類型
1、整數類型
整數類型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT
作用:存儲年齡,等級,id,各種號碼等
tinyint[(m)] [unsigned] [zerofill] 小整數,數據類型用于保存一些范圍的整數數值范圍:
? ? ? ? ? ? 有符號:
? ? ? ? ? ? ? ? -128 ~ 127? ? ? ? ? ? 無符號:
? ? ? ? ? ? ? ? 0 ~ 255? ? ? ? ? ? PS: MySQL中無布爾值,使用tinyint(1)構造。
? ? ? ? int[(m)][unsigned][zerofill]? ? ? ? ? ? 整數,數據類型用于保存一些范圍的整數數值范圍:
? ? ? ? ? ? 有符號:
? ? ? ? ? ? ? ? ? ? -2147483648 ~ 2147483647? ? ? ? ? ? 無符號:
? ? ? ? ? ? ? ? ? ? 0 ~ 4294967295? ? ? ? bigint[(m)][unsigned][zerofill]? ? ? ? ? ? 大整數,數據類型用于保存一些范圍的整數數值范圍:
? ? ? ? ? ? 有符號:
? ? ? ? ? ? ? ? ? ? -9223372036854775808 ~ 9223372036854775807? ? ? ? ? ? 無符號:
? ? ? ? ? ? ? ? ? ? 0? ~? 18446744073709551615
有符號和無符號tinyint
? ? 1.tinyint默認為有符號
? ? ? ? mysql> create table t1(x tinyint); #默認為有符號,即數字前有正負號? ? ? ? mysql> desc t1;
? ? ? ? mysql> insert into t1 values
? ? ? ? ? ? -> (-129),
? ? ? ? ? ? -> (-128),
? ? ? ? ? ? -> (127),
? ? ? ? ? ? -> (128);
? ? ? ? mysql> select * from t1;
? ? ? ? +------+
? ? ? ? | x? ? |? ? ? ? +------+
? ? ? ? | -128 | #-129存成了-128? ? ? ? | -128 | #有符號,最小值為-128? ? ? ? |? 127 | #有符號,最大值127? ? ? ? |? 127 | #128存成了127? ? ? ? +------+
? ? 2.設置無符號tinyint
? ? ? ? mysql> create table t2(x tinyint unsigned);
? ? ? ? mysql> insert into t2 values
? ? ? ? ? ? -> (-1),
? ? ? ? ? ? -> (0),
? ? ? ? ? ? -> (255),
? ? ? ? ? ? -> (256);
? ? ? ? mysql> select * from t2;
? ? ? ? +------+
? ? ? ? | x? ? |? ? ? ? +------+
? ? ? ? |? ? 0 | -1存成了0? ? ? ? |? ? 0 | #無符號,最小值為0? ? ? ? |? 255 | #無符號,最大值為255? ? ? ? |? 255 | #256存成了255? ? ? ? +------+
有符號和無符號int
? ? 1.int默認為有符號
? ? ? ? mysql> create table t3(x int); #默認為有符號整數? ? ? ? mysql> insert into t3 values
? ? ? ? ? ? -> (-2147483649),
? ? ? ? ? ? -> (-2147483648),
? ? ? ? ? ? -> (2147483647),
? ? ? ? ? ? -> (2147483648);
? ? ? ? mysql> select * from t3;
? ? ? ? +-------------+
? ? ? ? | x? ? ? ? ? |? ? ? ? +-------------+
? ? ? ? | -2147483648 | #-2147483649存成了-2147483648? ? ? ? | -2147483648 | #有符號,最小值為-2147483648? ? ? ? |? 2147483647 | #有符號,最大值為2147483647? ? ? ? |? 2147483647 | #2147483648存成了2147483647? ? ? ? +-------------+
? ? 2.設置無符號int
? ? ? ? mysql> create table t4(x int unsigned);
? ? ? ? mysql> insert into t4 values
? ? ? ? ? ? -> (-1),
? ? ? ? ? ? -> (0),
? ? ? ? ? ? -> (4294967295),
? ? ? ? ? ? -> (4294967296);
? ? ? ? mysql> select * from t4;
? ? ? ? +------------+
? ? ? ? | x? ? ? ? ? |? ? ? ? +------------+
? ? ? ? |? ? ? ? ? 0 | #-1存成了0? ? ? ? |? ? ? ? ? 0 | #無符號,最小值為0? ? ? ? | 4294967295 | #無符號,最大值為4294967295? ? ? ? | 4294967295 | #4294967296存成了4294967295? ? ? ? +------------+
注意:對于整型來說,數據類型后面的寬度并不是存儲長度限制,而是顯示限制,假如:int(8),那么顯示時不夠8位則用0來填充,夠8位則正常顯示,通過zerofill來測試,存儲長度還是int的4個字節長度。默認的顯示寬度就是能夠存儲的最大的數據的長度,比如:int無符號類型,那么默認的顯示寬度就是int(10),有符號的就是int(11),因為多了一個符號,所以我們沒有必要指定整數類型的數據,沒必要指定寬度,因為默認的就能夠將你存的原始數據完全顯示
2、浮點型
定點數類型 DEC,等同于DECIMAL
浮點類型:FLOAT DOUBLE
作用:存儲薪資、身高、溫度、體重、體質參數等
1.FLOAT[(M,D)] [UNSIGNED] [ZEROFILL] 定義:
? ? ? ? ? ? 單精度浮點數(非準確小數值),m是整數部分+小數部分的總個數,d是小數點后個數。m最大值為255,d最大值為30,例如:float(255,30)
? ? 有符號:
? ? ? ? ? ? ? -3.402823466E+38 to -1.175494351E-38,
? ? ? ? ? ? ? 1.175494351E-38 to 3.402823466E+38
? ? 無符號:
? ? ? ? ? ? ? 1.175494351E-38 to 3.402823466E+38
? ? 精確度:
? ? ? ? ? ? ? **** 隨著小數的增多,精度變得不準確 ****
2.DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]? ? 定義:
? ? ? ? ? ? ? 雙精度浮點數(非準確小數值),m是整數部分+小數部分的總個數,d是小數點后個數。m最大值也為255,d最大值也為30
? ? 有符號:
? ? ? ? ? ? ? -1.7976931348623157E+308 to -2.2250738585072014E-308? ? ? ? ? ? ? 2.2250738585072014E-308 to 1.7976931348623157E+308
? ? 無符號:
? ? ? ? ? ? ? 2.2250738585072014E-308 to 1.7976931348623157E+308
? ? 精確度:
? ? ? ? ? ? ? ****隨著小數的增多,精度比float要高,但也會變得不準確 ****
3.decimal[(m[,d])] [unsigned] [zerofill]? ? 定義:
? ? ? ? ? ? ? 準確的小數值,m是整數部分+小數部分的總個數(負號不算),d是小數點后個數。 m最大值為65,d最大值為30。比float和double的整數個數少,但是小數位數都是30位
? ? 精確度:
? ? ? ? ? ? ? **** 隨著小數的增多,精度始終準確 ****
? ? ? ? ? ? ? 對于精確數值計算時需要用此類型
? ? ? ? ? ? ? decimal能夠存儲精確值的原因在于其內部按照字符串存儲。
精度從高到低:decimal、double、float? ? decimal精度高,但是整數位數少
? ? float和double精度低,但是整數位數多float已經滿足絕大多數的場景了,但是什么導彈、航線等要求精度非常高,所以還是需要按照業務場景自行選擇,如果又要精度高又要整數位數多,那么你可以直接用字符串來存。
日期類型
類型:DATE,TIME,DATETIME ,IMESTAMP,YEAR
作用:存儲用戶注冊時間,文章發布時間,員工入職時間,出生時間,過期時間等
YEAR
? ? ? ? ? ? YYYY(范圍:1901/2155)2018? ? ? ? DATE
? ? ? ? ? ? YYYY-MM-DD(范圍:1000-01-01/9999-12-31)例:2018-01-01
? ? ? ? TIME? ? ? ? ? ? HH:MM:SS(范圍:'-838:59:59'/'838:59:59')例:12:09:32? ? ? ? DATETIME
? ? ? ? ? ? YYYY-MM-DD HH:MM:SS(范圍:1000-01-01 00:00:00/9999-12-31 23:59:59? ? Y)例: 2018-01-01 12:09:32? ? ? ? TIMESTAMP
? ? ? ? ? ? YYYYMMDD HHMMSS(范圍:1970-01-01 00:00:00/2037 年某時)
在實際應用的很多場景中,MySQL的這兩種日期類型都能夠滿足我們的需要,存儲精度都為秒,但在某些情況下,會展現出他們各自的優劣。下面就來總結一下兩種日期類型的區別。
1.DATETIME的日期范圍是1001——9999年,TIMESTAMP的時間范圍是1970——2038年。
2.DATETIME存儲時間與時區無關,TIMESTAMP存儲時間與時區有關,顯示的值也依賴于時區。在mysql服務器,操作系統以及客戶端連接都有時區的設置。
3.DATETIME使用8字節的存儲空間,TIMESTAMP的存儲空間為4字節。因此,TIMESTAMP比DATETIME的空間利用率更高。
4.DATETIME的默認值為null;TIMESTAMP的字段默認不為空(not null),默認值為當前時間(CURRENT_TIMESTAMP),如果不做特殊處理,并且update語句中沒有指定該列的更新值,則默認更新為當前時間。
字符串類型
類型:char,varchar
作用:名字,信息等等
#char類型:定長,簡單粗暴,浪費空間,存取速度快 字符長度范圍:0-255(一個中文是一個字符,是utf8編碼的3個字節)
? ? 存儲:
? ? ? ? 存儲char類型的值時,會往右填充空格來滿足長度
? ? ? ? 例如:指定長度為10,存>10個字符則報錯(嚴格模式下),存<10個字符則用空格填充直到湊夠10個字符存儲
? ? 檢索:
? ? ? ? 在檢索或者說查詢時,查出的結果會自動刪除尾部的空格,如果你想看到它補全空格之后的內容,除非我們打開pad_char_to_full_length SQL模式(SET sql_mode = 'strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH';)#varchar類型:變長,精準,節省空間,存取速度慢? ? 字符長度范圍:0-65535(如果大于21845會提示用其他類型 。mysql行最大限制為65535字節,字符編碼為utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)
? ? 存儲:
? ? ? ? varchar類型存儲數據的真實內容,不會用空格填充,如果'ab? ',尾部的空格也會被存起來
? ? ? ? 強調:varchar類型會在真實數據前加1-2Bytes的前綴,該前綴用來表示真實數據的bytes字節數(1-2Bytes最大表示65535個數字,正好符合mysql對row的最大字節限制,即已經足夠使用)
? ? ? ? 如果真實的數據<255bytes則需要1Bytes的前綴(1Bytes=8bit 2**8最大表示的數字為255)
? ? ? ? 如果真實的數據>255bytes則需要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數字為65535)
? ? 檢索:
? ? ? ? 尾部有空格會保存下來,在檢索或者說查詢時,也會正常顯示包含空格在內的內容
char和varchar性能對比:
以char(5)和varchar(5)來比較,加入我要存三個人名:sb,ssb1,ssbb2
char:
優點:簡單粗暴,不管你是多長的數據,我就按照規定的長度來存,5個5個的存,三個人名就會類似這種存儲:sb ssb1 ssbb2,中間是空格補全,取數據的時候5個5個的取,簡單粗暴速度快
缺點:貌似浪費空間,并且我們將來存儲的數據的長度可能會參差不齊
varchar:
varchar類型不定長存儲數據,更為精簡和節省空間
例如存上面三個人名的時候類似于是這樣的:sbssb1ssbb2,連著的,如果這樣存,請問這三個人名你還怎么取出來,你知道取多長能取出第一個嗎?(超哥,我能看出來啊,那我只想說:滾犢子!)
不知道從哪開始從哪結束,遇到這樣的問題,你會想到怎么解決呢?還記的嗎?想想?socket?tcp?struct?把數據長度作為消息頭。
所以,varchar在存數據的時候,會在每個數據前面加上一個頭,這個頭是1-2個bytes的數據,這個數據指的是后面跟著的這個數據的長度,1bytes能表示28=256,兩個bytes表示216=65536,能表示0-65535的數字,所以varchar在存儲的時候是這樣的:1bytes+sb+1bytes+ssb1+1bytes+ssbb2,所以存的時候會比較麻煩,導致效率比char慢,取的時候也慢,先拿長度,再取數據。
? 優點:節省了一些硬盤空間,一個acsii碼的字符用一個bytes長度就能表示,但是也并不一定比char省,看一下官網給出的一個表格對比數據,當你存的數據正好是你規定的字段長度的時候,varchar反而占用的空間比char要多。