-1]上面[]包含的內容是可選的,默認是有符號類型的,無符號的需要在類型後面跟上unsigned
示例 1:有符號類型mysql> create table demo1( c1 tinyint ); Query OK, 0 rows affected (0.01 sec) mysql> insert into demo1 values(-pow(2,7)),(pow(2,7)-1); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from demo1; +-+ | c1 | +-+ | -128 | | 127 | +-+ 2 rows in set (0.00 sec) mysql> insert into demo1 values(pow(2,7)); ERROR 1264 (22003): Out of range value for column 'c1' at row 1demo1 表中c1欄位為 tinyint 有符號類型的,可以看一下上面的演示,有超出範圍報錯的。
關於數值對應的範圍計算方式屬於計算機基礎的一些知識,可以去看一下計算機的二進位表示相關的文章。
示例 2:無符號類型mysql> create table demo2( c1 tinyint unsigned ); Query OK, 0 rows affected (0.01 sec) mysql> insert into demo2 values (-1); ERROR 1264 (22003): Out of range value for column 'c1' at row 1 mysql> insert into demo2 values (pow(2,8)+1); ERROR 1264 (22003): Out of range value for column 'c1' at row 1 mysql> insert into demo2 values (0),(pow(2,8)); mysql> insert into demo2 values (0),(pow(2,8)-1); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from demo2; +-+ | c1 | +-+ | 0 | | 255 | +-+ 2 rows in set (0.00 sec)c1 是無符號的 tinyint 類型的,插入了負數會報錯。
類型(n)說明在開發中,我們會碰到有些定義整型的寫法是 int(11),這種寫法個人感覺在開發過程中沒有什麼用途,不過還是來說一下,int(N)我們只需要記住兩點:
N 表示的是顯示寬度,不足的用 0 補足,超過的無視長度而直接顯示整個數字,但這要整型設置了 unsigned zerofill 才有效 看一下示例,理解更方便:
mysql> CREATE TABLE test3 ( `a` int, `b` int(5), `c` int(5) unsigned, `d` int(5) zerofill, `e` int(5) unsigned zerofill, `f` int zerofill, `g` int unsigned zerofill ); Query OK, 0 rows affected (0.01 sec) mysql> insert into test3 values (1,1,1,1,1,1,1),(11,11,11,11,11,11,11),(12345,12345,12345,12345,12345,12345,12345); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from test3; +--+--+--+--+--+--+--+ | a | b | c | d | e | f | g | +--+--+--+--+--+--+--+ | 1 | 1 | 1 | 00001 | 00001 | 0000000001 | 0000000001 | | 11 | 11 | 11 | 00011 | 00011 | 0000000011 | 0000000011 | | 12345 | 12345 | 12345 | 12345 | 12345 | 0000012345 | 0000012345 | +--+--+--+--+--+--+--+ 3 rows in set (0.00 sec) mysql> show create table test3; | Table | Create Table | test3 | CREATE TABLE `test3` ( `a` int(11) DEFAULT NULL, `b` int(5) DEFAULT NULL, `c` int(5) unsigned DEFAULT NULL, `d` int(5) unsigned zerofill DEFAULT NULL, `e` int(5) unsigned zerofill DEFAULT NULL, `f` int(10) unsigned zerofill DEFAULT NULL, `g` int(10) unsigned zerofill DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)show create table test3;輸出了表test3的創建語句,和我們原始的創建語句不一致了,原始的d欄位用的是無符號的,可以看出當使用了zerofill自動會將無符號提升為有符號。
說明:
int(5)輸出寬度不滿 5 時,前面用 0 來進行填充
int(n)中的 n 省略的時候,寬度為對應類型無符號最大值的十進位的長度 ,如 bigint 無符號最大值為 -1 = 18,446,744,073,709,551,615;長度是 20 位,來個 bigint 左邊 0 填充的示例看一下
mysql> CREATE TABLE test4 ( `a` bigint zerofill ); Query OK, 0 rows affected (0.01 sec) mysql> insert into test4 values(1); Query OK, 1 row affected (0.00 sec) mysql> select *from test4; +--+ | a | +--+ | 00000000000000000001 | +--+ 1 row in set (0.00 sec)上面的結果中 1 前面補了 19 個 0,和期望的結果一致。
浮點類型(容易懵,注意看)類型字節大小範圍(有符號)範圍(無符號)用途float[(m,d)]4(-3.402823466E+38,3.402823466351E+38)[0,3.402823466E+38)單精度 浮點數值double[(m,d)]8(-1.7976931348623157E+308,1.797693134 8623157E+308)[0,1.797693134862315 7E+308)雙精度 浮點數值decimal[(m,d)]對 DECIMAL(M,D) ,如果 M>D,為 M+2 否則為 D+2依賴於 M 和 D 的值依賴於 M 和 D 的值小數值float 數值類型用於表示單精度浮點數值,而 double 數值類型用於表示雙精度浮點數值,float 和 double 都是浮點型,而 decimal 是定點型。
浮點型和定點型可以用類型名稱後加(M,D)來表示,M 表示該值的總共長度,D 表示小數點後面的長度,M 和 D 又稱為精度和標度。
float 和 double 在不指定精度時,默認會按照實際的精度來顯示,而 DECIMAL 在不指定精度時,默認整數為 10,小數為 0。
示例 1(重點)mysql> create table test5(a float(5,2),b double(5,2),c decimal(5,2)); Query OK, 0 rows affected (0.01 sec) mysql> insert into test5 values (1,1,1),(2.1,2.1,2.1),(3.123,3.123,3.123),(4.125,4.125,4.125),(5.115,5.115,5.115),(6.126,6.126,6.126),(7.116,7.116,7.116),(8.1151,8.1151,8.1151),(9.1251,9.1251,9.1251),(10.11501,10.11501,10.11501),(11.12501,11.12501,11.12501); Query OK, 7 rows affected, 5 warnings (0.01 sec) Records: 7 Duplicates: 0 Warnings: 5 mysql> select * from test5; +--+--+--+ | a | b | c | +--+--+--+ | 1.00 | 1.00 | 1.00 | | 2.10 | 2.10 | 2.10 | | 3.12 | 3.12 | 3.12 | | 4.12 | 4.12 | 4.13 | | 5.12 | 5.12 | 5.12 | | 6.13 | 6.13 | 6.13 | | 7.12 | 7.12 | 7.12 | | 8.12 | 8.12 | 8.12 | | 9.13 | 9.13 | 9.13 | | 10.12 | 10.12 | 10.12 | | 11.13 | 11.13 | 11.13 | +--+--+--+ 11 rows in set (0.00 sec)結果說明(注意看):
c 是 decimal 類型,認真看一下輸入和輸出,發現decimal 採用的是四捨五入
認真看一下a和b的輸入和輸出,盡然不是四捨五入,一臉悶逼,float 和 double 採用的是四捨六入五成雙
decimal 插入的數據超過精度之後會觸發警告。
什麼是四捨六入五成雙?
就是 5 以下捨棄 5 以上進位,如果需要處理數字為 5 的時候,需要看 5 後面是否還有不為 0 的任何數字,如果有,則直接進位,如果沒有,需要看 5 前面的數字,若是奇數則進位,若是偶數則將 5 舍掉
示例 2我們將浮點類型的(M,D)精度和標度都去掉,看看效果:
mysql> create table test6(a float,b double,c decimal); Query OK, 0 rows affected (0.02 sec) mysql> insert into test6 values (1,1,1),(1.234,1.234,1.4),(1.234,0.01,1.5); Query OK, 3 rows affected, 2 warnings (0.00 sec) Records: 3 Duplicates: 0 Warnings: 2 mysql> select * from test6; +--+--+-+ | a | b | c | +--+--+-+ | 1 | 1 | 1 | | 1.234 | 1.234 | 1 | | 1.234 | 0.01 | 2 | +--+--+-+ 3 rows in set (0.00 sec)說明:
a 和 b 的數據正確插入,而 c 被截斷了
浮點數 float、double 如果不寫精度和標度,則會按照實際顯示
decimal 不寫精度和標度,小數點後面的會進行四捨五入,並且插入時會有警告!
再看一下下面代碼:
mysql> select sum(a),sum(b),sum(c) from test5; +---+---+---+ | sum(a) | sum(b) | sum(c) | +---+---+---+ | 67.21 | 67.21 | 67.22 | +---+---+---+ 1 row in set (0.00 sec) mysql> select sum(a),sum(b),sum(c) from test6; +++---+ | sum(a) | sum(b) | sum(c) | +++---+ | 3.4679999351501465 | 2.2439999999999998 | 4 | +++---+ 1 row in set (0.00 sec)從上面 sum 的結果可以看出float、double會存在精度問題,decimal精度正常的,比如銀行對統計結果要求比較精準的建議使用decimal。
日期類型類型字節大小範圍格式用途DATE31000-01-01/9999-12-31YYYY-MM-DD日期值TIME3'-838:59:59'/'838:59:59'HH:MM:SS時間值或持續時間YEAR11901/2155YYYY年份值DATETIME81000-01-01 00:00:00/9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS混合日期和時間值TIMESTAMP41970-01-01 00:00:00/2038 結束時間是第 2147483647 秒,北京時間 2038-1-19 11:14:07 ,格林尼治時間 2038 年 1 月 19 日 凌晨 03:14:07YYYYMMDD HHMMSS混合日期和時間值,時間戳字符串類型類型範圍存儲所需字節說明char(M)[0,m],m 的範圍[0, -1]m定產字符串varchar(M)[0,m],m 的範圍[0, -1]m0-65535 字節tinyblob0-255( -1)字節L+1不超過 255 個字符的二進位字符串blob0-65535( -1)字節L+2二進位形式的長文本數據mediumblob0-16777215( -1)字節L+3二進位形式的中等長度文本數據longblob0-4294967295( -1)字節L+4二進位形式的極大文本數據tinytext0-255( -1)字節L+1短文本字符串text0-65535( -1)字節L+2長文本數據mediumtext0-16777215( -1)字節L+3中等長度文本數據longtext0-4294967295( -1)字節L+4極大文本數據char 類型佔用固定長度,如果存放的數據為固定長度的建議使用 char 類型,如:手機號碼、身份證等固定長度的信息。
表格中的 L 表示存儲的數據本身佔用的字節,L 以外所需的額外字節為存放該值的長度所需的字節數。
MySQL 通過存儲值的內容及其長度來處理可變長度的值,這些額外的字節是無符號整數。
請注意,可變長類型的最大長度、此類型所需的額外字節數以及佔用相同字節數的無符號整數之間的對應關係:
例如,MEDIUMBLOB 值可能最多 - 1 字節長並需要 3 個字節記錄其長度,3 個字節的整數類型 MEDIUMINT 的最大無符號值為 - 1。
mysql 類型和 java 類型對應關係MySQL Type Name Return value ofGetColumnClassName Returned as Java Class BIT(1) (new in MySQL-5.0)BITjava.lang.BooleanBIT( > 1) (new in MySQL-5.0)BITbyte[]TINYINTTINYINTjava.lang.Boolean if the configuration property tinyInt1isBit is set to true(the default) and the storage size is 1, orjava.lang.Integer if not.BOOL, BOOLEANTINYINTSee TINYINT, above as these are aliases forTINYINT(1), currently.SMALLINT[(M)][unsigned]SMALLINT [UNSIGNED]java.lang.Integer (regardless if UNSIGNED or not)MEDIUMINT[(M)][unsigned]MEDIUMINT [UNSIGNED]java.lang.Integer, if UNSIGNEDjava.lang.LongINT,INTEGER[(M)][unsigned]INTEGER [UNSIGNED]java.lang.Integer, if UNSIGNEDjava.lang.LongBIGINT[(M)][unsigned]BIGINT [UNSIGNED]java.lang.Long, if UNSIGNEDjava.math.BigIntegerFLOAT[(M,D)]FLOATjava.lang.FloatDOUBLE[(M,B)]DOUBLEjava.lang.DoubleDECIMAL[(M[,D])]DECIMALjava.math.BigDecimalDATEDATEjava.sql.DateDATETIMEDATETIMEjava.sql.TimestampTIMESTAMP[(M)]TIMESTAMPjava.sql.TimestampTIMETIMEjava.sql.TimeYEAR[(2|4)]YEARIf yearIsDateType configuration property is set to false, then the returned object type isjava.sql.Short. If set to true (the default) then an object of type java.sql.Date (with the date set to January 1st, at midnight).CHAR(M)CHARjava.lang.String (unless the character set for the column is BINARY, then byte[]is returned.VARCHAR(M) [BINARY]VARCHARjava.lang.String (unless the character set for the column is BINARY, then byte[]is returned.BINARY(M)BINARYbyte[]VARBINARY(M)VARBINARYbyte[]TINYBLOBTINYBLOBbyte[]TINYTEXTVARCHARjava.lang.StringBLOBBLOBbyte[]TEXTVARCHARjava.lang.StringMEDIUMBLOBMEDIUMBLOBbyte[]MEDIUMTEXTVARCHARjava.lang.StringLONGBLOBLONGBLOBbyte[]LONGTEXTVARCHARjava.lang.StringENUM('value1','value2',...)CHARjava.lang.StringSET('value1','value2',...)CHARjava.lang.String數據類型選擇的一些建議選小不選大 :一般情況下選擇可以正確存儲數據的最小數據類型,越小的數據類型通常更快,佔用磁碟,內存和 CPU 緩存更小。簡單就好 :簡單的數據類型的操作通常需要更少的 CPU 周期,例如:整型比字符操作代價要小得多,因為字符集和校對規則(排序規則)使字符比整型比較更加複雜。儘量避免 NULL :儘量制定列為 NOT NULL,除非真的需要 NULL 類型的值,有 NULL 的列值會使得索引、索引統計和值比較更加複雜。記錄時間的建議使用 int 或者 bigint 類型,將時間轉換為時間戳格式,如將時間轉換為秒、毫秒,進行存儲,方便走索引 最新資料