一 MySQL數據類型分類
二 數值型
2.1 整數型
- 可使用unsigned控制是否有正負
- 可以使用zerofill來進行前導零填充
- 也存在 布爾bool類型,但是就是tinyint(1)的別名
- TINYINT[(M)] [UNSIGNED] [ZEROFILL]
- SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
- MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
- INT[(M)] [UNSIGNED] [ZEROFILL] 也可以使用 INTEGER
- BIGINT[(M)] [UNSIGNED] [ZEROFILL]
2.1.1 無格式控制
mysql> create table if not exists int_1(
-> `numA` tinyint,
-> `numB` int
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> insert into int_1 values(100, 101);
mysql> insert into int_1 values(1, 12);
mysql> insert into int_1 values(-1, 12);
mysql> select * from int_1;
+------+------+
| numA | numB |
+------+------+
| 100 | 101 |
| 1 | 12 |
| -1 | 12 |
+------+------+
3 rows in set (0.00 sec)
mysql> insert into int_1 values(127, 12);
Query OK, 1 row affected (0.03 sec)
mysql> insert into int_1 values(128, 12);
ERROR 1264 (22003): Out of range value for column 'numA' at row 1
mysql> insert into int_1 values(-128, 12);
Query OK, 1 row affected (0.02 sec)
mysql> insert into int_1 values(-129, 12);
ERROR 1264 (22003): Out of range value for column 'numA' at row 1
從上述內容可以看到,MySQL對於插入超出範圍的數的處理方式時報錯!不會像CPP語言一樣溢出!!!2.1.2 有格式控制
mysql> create table if not exists int_2(
-> `numA` tinyint(3) unsigned zerofill,
-> `numB` int(3) unsigned zerofill
-> );
Query OK, 0 rows affected (0.06 sec)
mysql> insert into int_2 values(1, 1);
mysql> insert into int_2 values(12, 1234);
mysql> select * from int_2;
+------+------+
| numA | numB |
+------+------+
| 001 | 001 |
| 012 | 1234 |
+------+------+
2 rows in set (0.00 sec)
從數據展示中我們可以看出,通過規定數據的顯示寬度可以達到統一顯示的目的,類型(M)表示的顯示的最小寬度是多少,不會影響寬度大於M的數字。- 設置寬度顯示不影響數的取值範圍,數的取值範圍是有數據類型決定的;
- 設置顯示寬度不會發生數據截取的現象。
2.2 小數型
- 小數型可以用(M,D)控制數值的範圍;
- 可以是無符號的;
- 可以zerofill;
- 可以使用無符號數
單精度:FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
雙精度:DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
其中M表示總的位數,D表示小數位數。此M,D可以控制保存的範圍。Float(10,2) -99999999.99 到 99999999.99
如果省略M,D會根據計算機硬件進行處理。單精度,M大約爲7左右;而雙精度,M大約爲15左右。
定點數:DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
其中M表示總的位數,D表示小數位數。此M,D可以控制保存的範圍。
M,D省略,默認爲10,0;
注意:可以unsigned 但是不會影響範圍。
2.2.1 float類型和double類型
mysql> create table if not exists float_1(
-> `fl` float,
-> `f2` double
-> );
Query OK, 0 rows affected (0.06 sec)
創建一個沒有格式控制的表,表中有兩種數據類型,一種爲float類型,另外一種爲double類型,都是有符號類型,沒有填充的;mysql> insert into float_1 values(12.123, 1234.5678);
mysql> insert into float_1 values(-12.123, -1234.5678);
mysql> select * from float_1;
+---------+------------+
| fl | f2 |
+---------+------------+
| 12.123 | 1234.5678 |
| -12.123 | -1234.5678 |
+---------+------------+
2 rows in set (0.00 sec)
控制數值的範圍(和整型不同),type(M,D)表示小數位數最多爲三位,整數部分最多爲M-D位,超過這麼多位的情況下會提示插入數據錯誤,當然了,如果插入的數據超過了數據的取值範圍的話也會發生錯誤。(M表示所有的數值位數,不包含小數點和符號;D表示允許的小數位數)。
創建一個擁有格式控制的float表
mysql> create table if not exists float_2(
-> `f1` float(5,2) zerofill,
-> `f2` double(6,3) zerofill
-> );
Query OK, 0 rows affected (0.06 sec)
向裏邊插入數據:
mysql> insert into float_2 values(12.34, 12.34);
mysql> insert into float_2 values(1.1, 1.2);
mysql> insert into float_2 values(123.45, 123.456);
數據展示:
mysql> select * from float_2;
+--------+---------+
| f1 | f2 |
+--------+---------+
| 12.34 | 12.340 |
| 01.10 | 01.200 |
| 123.45 | 123.456 |
+--------+---------+
3 rows in set (0.00 sec)
注意:當插入數據的位數超過規定的額定值以後,插入出錯!
mysql> insert into float_2 values(123456.1, 123456.34);
ERROR 1264 (22003): Out of range value for column 'f1' at row 1
mysql> insert into float_2 values(1234.12, 123456.34);
ERROR 1264 (22003): Out of range value for column 'f1' at row 1
NO2 浮點數的科學計數發(E)
mysql> insert into float_2 values(0.1234E2, 0.123456E3);
Query OK, 1 row affected (0.02 sec)
mysql> select * from float_2;
+--------+---------+
| f1 | f2 |
+--------+---------+
| 12.34 | 12.340 |
| 01.10 | 01.200 |
| 123.45 | 123.456 |
| 12.34 | 123.456 |
+--------+---------+
4 rows in set (0.00 sec)
mysql> insert into float_2 values(12.126, 12.34);
Query OK, 1 row affected (0.02 sec)
| 12.13 | 12.340 |
+--------+---------+
2.2.2 定點數
- 小數超過位數的話會出現四捨五入的情況,不會報錯;
- 默認情況下,M爲10,D爲0;
mysql> create table if not exists float_3(
-> `f` decimal(10,4) unsigned zerofill
-> );
Query OK, 0 rows affected (0.07 sec)
插入數據:
mysql> insert into float_3 values(123.45);
mysql> insert into float_3 values(123.4567);
mysql> insert into float_3 values(123.45678);
mysql> select * from float_3;
+-------------+
| f |
+-------------+
| 000123.4500 |
| 000123.4567 |
| 000123.4568 |
+-------------+
3 rows in set (0.00 sec)
2.3 時間日期
年月日時分秒的分隔符可以是任意的標點,但是常用的是-和:,甚至是不使用都可以。
2位的年也是被允許的,但是表示的範圍70-69 表示:1970-2069範圍
TIMESTAMP:時間戳,年份是一個範圍
TIME:TIME類型不僅可以用於表示一天的時間,還可以表示一個間隔時間(或者過去了多久)
因此該類型可以設置爲多個小時,甚至是 幾天幾小時幾分鐘幾秒的情況 D HH:II:SS。
同樣在設置時分秒時,可以使用其他標點符號作爲分隔符,甚至是不用(用天了就不行了)。
2.3.1 Datetime(年月日時分秒)
mysql> create table if not exists date_1(
-> myDate datetime
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> insert into date_1 values('20160803142011');
Query OK, 1 row affected (0.02 sec)
mysql> insert into date_1 values(20160803142015);
Query OK, 1 row affected (0.01 sec)
mysql> insert into date_1 values('2016-08-03 14:20:25');
Query OK, 1 row affected (0.02 sec)
數據展示:
mysql> select * from date_1;
+---------------------+
| myDate |
+---------------------+
| 2016-08-03 14:20:11 |
| 2016-08-03 14:20:15 |
| 2016-08-03 14:20:25 |
+---------------------+
3 rows in set (0.00 sec)
從上方我麼可以看到,插入的時間必須要在一定的範圍之內,插入時間的格式多種多樣,既可以是字符串(用單引號引起來),也可以是單純的整數,同時也可以使用分隔符(使用分隔符的時候相當於使用字符串,一定要用單引號引起來);- 插入的時間一定要在其允許的範圍之內;
- 分隔符可以是任意的字符,但是爲了方便起見,在年份中一般用‘-’,在時間中一般用‘:’。
mysql> insert into date_1 values(0);
| 0000-00-00 00:00:00 |
mysql> insert into date_1 values('16:08:03');
Query OK, 1 row affected (0.03 sec)
| 2016-08-03 00:00:00 |
2.3.2 時間戳timestamp(年月日時分秒/整數)
mysql> create table if not exists date_2(
-> `t` timestamp
-> );
Query OK, 0 rows affected (0.14 sec)
向時間戳表date_2中插入數據:
mysql> insert into date_2 values(20160803143415);
Query OK, 1 row affected (0.02 sec)
mysql> insert into date_2 values('20160803143420');
Query OK, 1 row affected (0.02 sec)
mysql> insert into date_2 values('2016-08-03 14:34:25');
Query OK, 1 row affected (0.02 sec)
mysql> select * from date_2;
+---------------------+
| t |
+---------------------+
| 2016-08-03 14:34:15 |
| 2016-08-03 14:34:20 |
| 2016-08-03 14:34:25 |
+---------------------+
3 rows in set (0.00 sec)
從上方代碼可以看到,時間戳和方法和datetime是一致的,這裏不再詳細贅述!mysql> select t+0 from date_2;
+----------------+
| t+0 |
+----------------+
| 20160803143415 |
| 20160803143420 |
| 20160803143425 |
+----------------+
3 rows in set (0.00 sec)
2.3.3 date(年月日)
創建日期表date_3:mysql> create table if not exists date_3(
-> `t` date
-> );
Query OK, 0 rows affected (0.05 sec)
插入數據:
mysql> insert into date_3 values(20160803);
Query OK, 1 row affected (0.03 sec)
mysql> insert into date_3 values('20160803');
Query OK, 1 row affected (0.03 sec)
mysql> insert into date_3 values('2016:08:03');
Query OK, 1 row affected (0.02 sec)
數據展示:
mysql> select * from date_3;
+------------+
| t |
+------------+
| 2016-08-03 |
| 2016-08-03 |
| 2016-08-03 |
+------------+
3 rows in set (0.00 sec)
mysql> insert into date_3 values('16:08:03');
Query OK, 1 row affected (0.03 sec)
mysql> insert into date_3 values('80:08:03');
Query OK, 1 row affected (0.03 sec)
| 2016-08-03 |
| 1980-08-03 |
70-69 1970 - 2069
70-99 19xx(默認)
0-69 20xx年(默認)
2.3.4 time(時間)
2,表示時間間隔,在表示間隔時(也就是過去了多長時間),
可以使用天來表示。格式:
D HH:MM:SS
D表示天(最大爲34)
mysql> create table if not exists date_4(
-> `t` time
-> );
Query OK, 0 rows affected (0.07 sec)
插入數值:
mysql> insert into date_4 values('14:55:27');
Query OK, 1 row affected (0.03 sec)
mysql> insert into date_4 values('5 14:55:27');
Query OK, 1 row affected (0.02 sec)
mysql> select * from date_4;
+-----------+
| t |
+-----------+
| 14:55:27 |
| 134:55:27 |
+-----------+
2 rows in set (0.00 sec)
第一條表示插入的時間數值;2.3.5 year(年)
mysql> create table if not exists date_5(
-> `y` year
-> );
Query OK, 0 rows affected (0.09 sec)
mysql> insert into date_5 values(1234);
ERROR 1264 (22003): Out of range value for column 'y' at row 1
插入正常範圍內的數據:
mysql> insert into date_5 values(1999);
Query OK, 1 row affected (0.02 sec)
mysql> insert into date_5 values(2016);
Query OK, 1 row affected (0.02 sec)
數據展示:
mysql> select * from date_5;
+------+
| y |
+------+
| 1999 |
| 2016 |
+------+
2 rows in set (0.00 sec)
2.4 字符串類型
CHAR和VARCHAR類型聲明的長度表示你想要保存的最大字符數。
Char,定長字符串,保存時如果字符串長度不夠,則後邊補足空字符串;但是在讀取到數據是,會截取後邊所有的字符串。因此如果真實數據存在左邊空格,則需要注意。
varchar,變長字符串。在保存字符串時,同時保存該字符串的長度,小於255採用一個字節保存,否則採用二個字節保存。不會像char一樣截取空格。
在定義類型長度時,同時一條記錄的總長度是 65535.因此所有字段的總長度不能超過改值。同時每條記錄還需要一個字節保存是否有null值,如果都沒有null(都不允許爲null)則該字節省略。
枚舉
ENUM('value1','value2',...)
枚舉值應該在值列表內,允許使用下標方式標識。1標識第一個元素,逐個遞增。
除此之外,允許null和空字符串(下標爲0)
下標方式,可以使用在檢索中。
集合
Set(‘value1’,’value2’,…);
表示可以選擇可用值的0個或多個組合。
二進制類型:
如果需要保存一個二進制文件內容的話,應該保存成這些類型,例如圖片內容。
2.4.1 char & varchar類型
char(5) | varchar(5) | ||
‘’ | 5個字符 | 1個字符 | varchar需要一個字節保存字符串總長度 |
‘abc’ | 5 | 4 | |
‘abcde’ | 5 | 6 | |
utf8中一個字符佔用三個字節21845*3 = 65536
gbk中一個字符佔用兩個字節32767*2 = 65534
mysql> create table if not exists str_1(
-> `c` char(255)
-> );
Query OK, 0 rows affected (0.07 sec)
mysql> create table if not exists str2(
-> `c` varchar(65535)
-> )character set latin1;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to cha
ge some columns to TEXT or BLOBs
mysql>
因爲varchar類型除了還要保存額外總的字符個數,除了類型本身的限制之外,還有記錄總的長度;mysql> create table if not exists str2(
-> `c` varchar(65533) not null
-> )character set latin1;
Query OK, 0 rows affected (0.09 sec)
mysql> create table if not exists str3(
-> `c` varchar(65533)
-> )character set latin1;
ERROR 1118 (42000): Row size too large. The m
ge some columns to TEXT or BLOBs
mysql>
創建成功:
mysql> create table if not exists str3(
-> `c` varchar(65532)
-> )character set latin1;
Query OK, 0 rows affected (0.09 sec)
varchar特點,當 類型數據超過255個字符時,採用2個字節表示長度。
65535-2=65533
整條記錄,需要一個額外的字節,用於保存當前字段的null值。
除非所有的字段都比不是nul,這個字節纔可以省略。一個記錄,不論有多少個字段
存在null,都是使用統一的一個字節來表示。而不是每個字段一個字節。
創建不成功,因爲下邊的tinyint也要佔用一個null字節:
mysql> create table if not exists str4(
-> `c` varchar(65533) not null,
-> `i` tinyint
-> )character set latin1;
ERROR 1118 (42000): Row size too large. The maximum
ge some columns to TEXT or BLOBs
2.4.2 test
文本,有很多 兄弟類型(不用指定長度)Tinytext longtext
表示的字符串長度不一樣。
2.4.3 枚舉(enum)
mysql> create table if not exists enum_1(
-> `e` enum('female', 'male')
-> );
Query OK, 0 rows affected (0.06 sec)
插入數據方式1:
mysql> insert into enum_1 values('female');
Query OK, 1 row affected (0.02 sec)
mysql> insert into enum_1 values('male');
Query OK, 1 row affected (0.02 sec)
mysql> insert into enum_1 values(2);
Query OK, 1 row affected (0.02 sec)
mysql> insert into enum_1 values(1);
Query OK, 1 row affected (0.01 sec)
數據展示1:
mysql> select * from enum_1;
+--------+
| e |
+--------+
| female |
| male |
| male |
| female |
+--------+
4 rows in set (0.00 sec)
數據展示2:
mysql> select e+0 from enum_1;
+------+
| e+0 |
+------+
| 1 |
| 2 |
| 2 |
| 1 |
+------+
4 rows in set (0.00 sec)
2.4.4 set集合(相當於多項選擇題)
mysql> create table if not exists set_1(
-> `s` set('A', 'B', 'C', 'D')
-> );
Query OK, 0 rows affected (0.06 sec)
mysql> insert into set_1 values('A');
Query OK, 1 row affected (0.03 sec)
mysql> insert into set_1 values('A,B');
Query OK, 1 row affected (0.02 sec)
mysql> insert into set_1 values('C');
Query OK, 1 row affected (0.01 sec)
mysql> insert into set_1 values('C,D');
Query OK, 1 row affected (0.01 sec)
mysql> select * from set_1;
+------+
| s |
+------+
| A |
| A,B |
| C |
| C,D |
+------+
mysql> select s+0 from set_1;
+------+
| s+0 |
+------+
| 1 |
| 3 |
| 4 |
| 12 |
+------+
4 rows in set (0.00 sec)
數據展示2的分析:set總共佔據8個字節,也就是64爲二進制數字,列表中每個參數佔據一位,也就是說最多保存64中狀態。
總結:
- 應該使用最精確的類型。佔用的空間少。
- 還應該考慮到相關應用語言的處理。例如常常將時間日期保存成一個整型。便於計算。
- 考慮移植的兼容性。
類型