1. 程式人生 > >表 - 資料型別

表 - 資料型別

資料型別:
    儲存引擎決定了表的型別,而表記憶體放的資料也要有不同的型別,每種資料型別都有自己的寬度,但寬度是可選的
    參考:
        http://www.runoob.com/mysql/mysql-data-types.html
        http://dev.mysql.com/doc/refman/5.7/en/data-type-overview.html

    mysql常用資料型別概覽:
        1.數值型別:
            整數型別:tinyint smallint int bigint


            浮點型:float double decimal
                float :在位數比較短的情況下不精準(一般float得精確度也夠用了)
                double :在位數比較長的情況下不精準
                    0.000001230123123123
                    存成:0.000001230000
                decimal:(如果用小數,則推薦使用decimal)

                    精準 內部原理是以字串形式去存
        2.日期型別:
            最常用:datetime  year date time datetime timestamp
        3.字串型別:

            char(6) varchar(6)
            char(10):簡單粗暴,浪費空間,存取速度快,定長;
                root存成root000000
            varchar:精準,節省空間,存取速度慢,變長;

            sql優化:建立表時,定長的型別往前放,變長的往後放
                            比如性別           比如地址或描述資訊

            >255個字元,超了就把檔案路徑存放到資料庫中。
                    比如圖片,視訊等找一個檔案伺服器,資料庫中只存路徑或url。
       4.列舉型別與集合型別:
            enum('male','female')
            set('play','music','read','study')

一、數值型別:
1.整數型別:
整數型別:tinyint 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
========================================
驗證:
複製程式碼
 1             mysql> create table t1(x tinyint);  # 預設是有符號的 -128,127
 2             mysql> insert into t1 values(-129),(128);
 3             mysql> select * from t1;   # 若是 超出範圍 它會自動到 -128 127
 4             +------+
 5             | x    |
 6             +------+
 7             | -128 |
 8             |  127 |
 9             +------+
10 
11             mysql> create table t2(x tinyint unsigned);  # 無符號的
12             mysql> insert into t2 values(-1),(256);
13             mysql> select * from t2;
14             +------+
15             | x    |
16             +------+
17             |    0 |
18             |  255 |
19             +------+
20 
21             mysql> create table t3(id int(1) unsigned);
22             mysql> desc t3;
23             +-------+-----------------+------+-----+---------+-------+
24             | Field | Type            | Null | Key | Default | Extra |
25             +-------+-----------------+------+-----+---------+-------+
26             | id    | int(1) unsigned | YES  |     | NULL    |       |
27             +-------+-----------------+------+-----+---------+-------+
28             mysql> insert into t3 values(2555555555);
29             mysql> insert into t3 values(213123123213231232131212312);
30             mysql> select * from t3;
31             +------------+
32             | id         |
33             +------------+
34             | 2555555555 |
35             | 4294967295 |
36             +------------+
37             int 型 不需要加寬度;  int(1) # 1 不是 指的儲存寬度 而是 顯示寬度
38                 儲存寬度:tinyint int  儲存寬度 都固定死了 你不能修改
39                 顯示寬度: 指的是 查詢時 select * from t4 ;
40                     mysql> create table t5(id int(5) unsigned zerofill);
41                     mysql> insert into t5 values(1);
42                     mysql> select * from t5;
43                     +-------+
44                     | id    |
45                     +-------+
46                     | 00001 |
47                     +-------+
48                     mysql> insert into values(12345671222222222222);
49                     mysql> select * from t5;   # 超過5位了就正常顯示了,所以說顯示寬度對於int來說沒有意義;
50                     +------------+
51                     | id         |
52                     +------------+
53                     |      00001 |
54                     | 4294967295 |
55                     +------------+
56                 預設得顯示寬度: int(0-4294967295)(-2147483648-2147483647)
57                     mysql> create table t6(id int unsigned);  # 預設得無符號得寬度 是10
58                     mysql> desc t6;
59                     +-------+------------------+------+-----+---------+-------+
60                     | Field | Type             | Null | Key | Default | Extra |
61                     +-------+------------------+------+-----+---------+-------+
62                     | id    | int(10) unsigned | YES  |     | NULL    |       |
63                     +-------+------------------+------+-----+---------+-------+
64                     mysql> create table t7(id int);   # 預設得有符號得寬度 是11
65                     mysql> desc t7;
66                     +-------+---------+------+-----+---------+-------+
67                     | Field | Type    | Null | Key | Default | Extra |
68                     +-------+---------+------+-----+---------+-------+
69                     | id    | int(11) | YES  |     | NULL    |       |
70                     +-------+---------+------+-----+---------+-------+
71                     1 row in set (0.03 sec)
複製程式碼 整數型別

注: int(3) 表示得是顯示寬度,不是儲存寬度 ,自己沒有必要指定,
其他所有型別得,指定得寬度都表示儲存寬度。
2.浮點型:
浮點型別:float double decimal=dec
作用:儲存薪資、身高、體重、體質引數等
規則:
======================================
#FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
定義:
單精度浮點數(非準確小數值),m是數字總個數,d是小數點後個數。m最大值為255,d最大值為30
有符號:
-3.402823466E+38 to -1.175494351E-38,
1.175494351E-38 to 3.402823466E+38
無符號:
1.175494351E-38 to 3.402823466E+38
精確度:
**** 隨著小數的增多,精度變得不準確 ****
======================================
#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要高,但也會變得不準確 ****
======================================
decimal[(m[,d])] [unsigned] [zerofill]
定義:
準確的小數值,m是數字總個數(負號不算),d是小數點後個數。 m最大值為65,d最大值為30。
精確度:
**** 隨著小數的增多,精度始終準確 ****
對於精確數值計算時需要用此型別
decaimal能夠儲存精確值的原因在於其內部按照字串儲存。
======================================
驗證:
複製程式碼
 1             mysql> create table t1(x float(256,31));
 2             ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
 3             mysql> create table t1(x float(256,30));
 4             ERROR 1439 (42000): Display width out of range for column 'x' (max = 255)
 5             mysql> create table t1(x float(255,30)); #建表成功
 6             Query OK, 0 rows affected (0.02 sec)
 7 
 8             mysql> create table t2(x double(255,30)); #建表成功
 9             Query OK, 0 rows affected (0.02 sec)
10 
11             mysql> create table t3(x decimal(66,31));
12             ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
13             mysql> create table t3(x decimal(66,30));
14             ERROR 1426 (42000): Too-big precision 66 specified for 'x'. Maximum is 65.
15             mysql> create table t3(x decimal(65,30)); #建表成功
16             Query OK, 0 rows affected (0.02 sec)
17 
18             mysql> show tables;
19             +---------------+
20             | Tables_in_db1 |
21             +---------------+
22             | t1            |
23             | t2            |
24             | t3            |
25             +---------------+
26             rows in set (0.00 sec)
27 
28             mysql> insert into t1 values(1.1111111111111111111111111111111); #小數點後31個1
29             Query OK, 1 row affected (0.01 sec)
30 
31             mysql> insert into t2 values(1.1111111111111111111111111111111);
32             Query OK, 1 row affected (0.00 sec)
33 
34             mysql> insert into t3 values(1.1111111111111111111111111111111);
35             Query OK, 1 row affected, 1 warning (0.01 sec)
36 
37             mysql> select * from t1; #隨著小數的增多,精度開始不準確
38             +----------------------------------+
39             | x                                |
40             +----------------------------------+
41             | 1.111111164093017600000000000000 |
42             +----------------------------------+
43             row in set (0.00 sec)
44 
45             mysql> select * from t2; #精度比float要準確點,但隨著小數的增多,同樣變得不準確
46             +----------------------------------+
47             | x                                |
48             +----------------------------------+
49             | 1.111111111111111200000000000000 |
50             +----------------------------------+
51             row in set (0.00 sec)
52 
53             mysql> select * from t3; #精度始終準確,d為30,於是只留了30位小數
54             +----------------------------------+
55             | x                                |
56             +----------------------------------+
57             | 1.111111111111111111111111111111 |
58             +----------------------------------+
59             row in set (0.00 sec)
複製程式碼 浮點型

注:精度最高得是 decimal double float

二、日期型別:
YEAR DATE TIME DATETIME TIMESTAMP
作用:儲存使用者註冊時間,文章釋出時間,員工入職時間,出生時間,過期時間等
規則:
YEAR
YYYY(1901/2155)
DATE
YYYY-MM-DD(1000-01-01/9999-12-31)
TIME
HH:MM:SS('-838:59:59'/'838:59:59')
DATETIME
YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 Y)
TIMESTAMP
YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某時)
驗證:
 1             ============year===========
 2             MariaDB [db1]> create table t10(born_year year); #無論year指定何種寬度,最後都預設是year(4)
 3             MariaDB [db1]> insert into t10 values
 4                 -> (1900),
 5                 -> (1901),
 6                 -> (2155),
 7                 -> (2156);
 8             MariaDB [db1]> select * from t10;
 9             +-----------+
10             | born_year |
11             +-----------+
12             |      0000 |
13             |      1901 |
14             |      2155 |
15             |      0000 |
16             +-----------+
17 
18             ============date,time,datetime===========
19             MariaDB [db1]> create table t11(d date,t time,dt datetime);
20             MariaDB [db1]> desc t11;
21             +-------+----------+------+-----+---------+-------+
22             | Field | Type     | Null | Key | Default | Extra |
23             +-------+----------+------+-----+---------+-------+
24             | d     | date     | YES  |     | NULL    |       |
25             | t     | time     | YES  |     | NULL    |       |
26             | dt    | datetime | YES  |     | NULL    |       |
27             +-------+----------+------+-----+---------+-------+
28 
29             MariaDB [db1]> insert into t11 values(now(),now(),now());
30             MariaDB [db1]> select * from t11;
31             +------------+----------+---------------------+
32             | d          | t        | dt                  |
33             +------------+----------+---------------------+
34             | 2017-07-25 | 16:26:54 | 2017-07-25 16:26:54 |
35             +------------+----------+---------------------+
36 
37             ============timestamp===========
38             MariaDB [db1]> create table t12(time timestamp);
39             MariaDB [db1]> insert into t12 values();
40             MariaDB [db1]> insert into t12 values(null);
41             MariaDB [db1]> select * from t12;
42             +---------------------+
43             | time                |
44             +---------------------+
45             | 2017-07-25 16:29:17 |
46             | 2017-07-25 16:30:01 |
47             +---------------------+
48 
49             ============注意啦,注意啦,注意啦===========
50             1. 單獨插入時間時,需要以字串的形式,按照對應的格式插入
51             2. 插入年份時,儘量使用4位值
52             3. 插入兩位年份時,<=69,以20開頭,比如50,  結果2050
53                             >=70,以19開頭,比如71,結果1971
54             MariaDB [db1]> create table t12(y year);
55             MariaDB [db1]> insert into t12 values
56                 -> (50),
57                 -> (71);
58             MariaDB [db1]> select * from t12;
59             +------+
60             | y    |
61             +------+
62             | 2050 |
63             | 1971 |
64             +------+
65 
66             ============綜合練習===========
67             MariaDB [db1]> create table student(
68                 -> id int,
69                 -> name varchar(20),
70                 -> born_year year,
71                 -> birth date,
72                 -> class_time time,
73                 -> reg_time datetime);
74 
75             MariaDB [db1]> insert into student values
76                 -> (1,'alex',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"),
77                 -> (2,'egon',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"),
78                 -> (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13");
79 
80             MariaDB [db1]> select * from student;
81             +------+------+-----------+------------+------------+---------------------+
82             | id   | name | born_year | birth      | class_time | reg_time            |
83             +------+------+-----------+------------+------------+---------------------+
84             |    1 | alex |      1995 | 1995-11-11 | 11:11:11   | 2017-11-11 11:11:11 |
85             |    2 | egon |      1997 | 1997-12-12 | 12:12:12   | 2017-12-12 12:12:12 |
86             |    3 | wsb  |      1998 | 1998-01-01 | 13:13:13   | 2017-01-01 13:13:13 |
87             +------+------+-----------+------------+------------+---------------------+
日期型別

datetime與timestamp的區別
在實際應用的很多場景中,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語句中沒有指定該列的更新值,則預設更新為當前時間。

三、字串型別:
#官網:https://dev.mysql.com/doc/refman/5.7/en/char.html
#注意:char和varchar括號內的引數指的都是字元的長度

1.char型別:定長,簡單粗暴,浪費空間,存取速度快
字元長度範圍:0-255(一箇中文是一個字元,是utf8編碼的3個位元組)
儲存:
儲存char型別的值時,會往右填充空格來滿足長度
例如:指定長度為10,存>10個字元則報錯,存<10個字元則用空格填充直到湊夠10個字元儲存

檢索:
在檢索或者說查詢時,查出的結果會自動刪除尾部的空格,除非我們開啟pad_char_to_full_length SQL模式(SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)

2.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)

檢索:
尾部有空格會儲存下來,在檢索或者說查詢時,也會正常顯示包含空格在內的內容

                        

    驗證:
length:檢視位元組數
char_length:檢視字元數
1. char填充空格來滿足固定長度,但是在查詢時卻會很不要臉地刪除尾部的空格(裝作自己好像沒有浪費過空間一樣),然後修改sql_mode讓其現出原形。
驗證:
 1                 mysql> create table t1(x char(5),y varchar(5));
 2                 Query OK, 0 rows affected (0.26 sec)
 3 
 4                 #char存5個字元,而varchar存4個字元
 5                 mysql> insert into t1 values('你瞅啥 ','你瞅啥 ');
 6                 Query OK, 1 row affected (0.05 sec)
 7 
 8                 mysql> SET sql_mode='';
 9                 Query OK, 0 rows affected, 1 warning (0.00 sec)
10 
11                 #在檢索時char很不要臉地將自己浪費的2個字元給刪掉了,裝的好像自己沒浪費過空間一樣,而varchar很老實,存了多少,就顯示多少
12                 mysql> select x,char_length(x),y,char_length(y) from t1;
13                 +-----------+----------------+------------+----------------+
14                 | x         | char_length(x) | y          | char_length(y) |
15                 +-----------+----------------+------------+----------------+
16                 | 你瞅啥    |              3 | 你瞅啥     |              4 |
17                 +-----------+----------------+------------+----------------+
18                 row in set (0.00 sec)
19 
20                 #略施小計,讓char現出原形
21                 mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
22                 Query OK, 0 rows affected (0.00 sec)
23 
24                 #這下子char原形畢露了......
25                 mysql> select x,char_length(x),y,char_length(y) from t1;
26                 +-------------+----------------+------------+----------------+
27                 | x           | char_length(x) | y          | char_length(y) |
28                 +-------------+----------------+------------+----------------+
29                 | 你瞅啥      |              5 | 你瞅啥     |              4 |
30                 +-------------+----------------+------------+----------------+
31                 row in set (0.00 sec)
32 
33                 #char型別:3箇中文字元+2個空格=11Bytes
34                 #varchar型別:3箇中文字元+1個空格=10Bytes
35                 mysql> select x,length(x),y,length(y) from t1;
36                 +-------------+-----------+------------+-----------+
37                 | x           | length(x) | y          | length(y) |
38                 +-------------+-----------+------------+-----------+
39                 | 你瞅啥      |        11 | 你瞅啥     |        10 |
40                 +-------------+-----------+------------+-----------+
41                 row in set (0.00 sec)
字串型別

2. 雖然 CHAR 和 VARCHAR 的儲存方式不太相同,但是對於兩個字串的比較,都只比 較其值,忽略 CHAR 值存在的右填充,即使將 SQL _MODE 設定為 PAD_CHAR_TO_FULL_LENGTH 也一樣,,但這不適用於like。
驗證:
 1                 Values in CHAR and VARCHAR columns are sorted and compared according to the character set collation assigned to the column.
 2 
 3                 All MySQL collations are of type PAD SPACE. This means that all CHAR, VARCHAR, and TEXT values are compared without regard to any trailing spaces. “Comparison” in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant. For example:
 4 
 5                 mysql> CREATE TABLE names (myname CHAR(10));
 6                 Query OK, 0 rows affected (0.03 sec)
 7 
 8                 mysql> INSERT INTO names VALUES ('Monty');
 9                 Query OK, 1 row affected (0.00 sec)
10 
11                 mysql> SELECT myname = 'Monty', myname = 'Monty  ' FROM names;
12                 +------------------+--------------------+
13                 | myname = 'Monty' | myname = 'Monty  ' |
14                 +------------------+--------------------+
15                 |                1 |                  1 |
16                 +------------------+--------------------+
17                 row in set (0.00 sec)
18 
19                 mysql> SELECT myname LIKE 'Monty', myname LIKE 'Monty  ' FROM names;
20                 +---------------------+-----------------------+
21                 | myname LIKE 'Monty' | myname LIKE 'Monty  ' |
22                 +---------------------+-----------------------+
23                 |                   1 |                     0 |
24                 +---------------------+-----------------------+
25                 row in set (0.00 sec)
字串型別

  3.總結:
  #常用字串系列:char與varchar
  注:雖然varchar使用起來較為靈活,但是從整個系統的效能角度來說,char資料型別的處理速度更快,有時甚至可以超出varchar處理速度的50%。因此,使用者在設計資料庫時應當綜合考慮各方面的因素,以求達到最佳的平衡

  #其他字串系列(效率:char>varchar>text)
   TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
   BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB
   BINARY系列 BINARY VARBINARY

   text:text資料型別用於儲存變長的大字串,可以多到65535 (2**16 − 1)個字元。
   mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
   longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.

注意:
# 注:末尾去空格 只適應等號 不適應 like

name char(5) # 簡單粗暴 來幾個存5個
egon |alex |wxx |
name varchar(5) # 先存長度 # 頭不是固定1bytes 超過256 就變成了2bytes 65535 但mysql 固定了
#不能超過65535 ,對於大檔案 不應該存在資料庫, 資料庫存 精簡得 檔案伺服器 資料庫伺服器
4 + egon|4 + alex|3+ wxx

char(5) 簡單粗暴 存快 取快 缺點 浪費空間 #大部分情況 下 用 char
varchar(5) 存慢 取慢 有頭得存在 優點 省空間 # 存完之後 不查得話 就可以用varchar

建表得時候: 定長得資料 往前放,變長得資料往後放
一張表,char varchar 不要混著用

四、列舉型別與集合型別:
欄位的值只能在給定範圍中選擇,如單選框,多選框
enum 單選 只能在給定的範圍內選一個值,如性別 sex 男male/女female
set 多選 在給定的範圍內可以選擇一個或一個以上的值(愛好1,愛好2,愛好3...)

[db1]> create table consumer(
-> name varchar(50),
-> sex enum('male','female'),
-> level enum('vip1','vip2','vip3','vip4','vip5'), #在指定範圍內,多選一
-> hobby set('play','music','read','study') #在指定範圍內,多選多
-> );

[db1]> insert into consumer values
-> ('egon','male','vip5','read,study'),
-> ('alex','female','vip1','girl');

[db1]> select * from consumer;
+------+--------+-------+------------+
| name | sex | level | hobby |
+------+--------+-------+------------+
| egon | male | vip5 | read,study |
| alex | female | vip1 | |
+------+--------+-------+------------+