蔬菜水果網(wǎng)站建設軟文網(wǎng)站推廣
文章目錄
- 數(shù)據(jù)類型分類
- 數(shù)值類型
- tinyint類型
- bit類型
- float類型
- decimal類型
- 字符串類型
- char類型
- varchar類型
- char和varchar對比
- 日期和時間類型
- enum和set類型
數(shù)據(jù)類型分類
MySQL中,支持各種各樣的類型,比如表示數(shù)值的整型浮點型,文本、二進制類型、時間日期型和String類型。
數(shù)值類型
tinyint類型
tinyint類型用于存放數(shù)值比較小的整數(shù),取值范圍-128~127
數(shù)值越界測試:
mysql> create table t1 (-> data tinyint-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t1;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| data | tinyint(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)mysql> insert into t1 (data) values (1);
Query OK, 1 row affected (0.00 sec)mysql> insert into t1 (data) values (128);
ERROR 1264 (22003): Out of range value for column 'data' at row 1
mysql> insert into t1 (data) values (-129);
ERROR 1264 (22003): Out of range value for column 'data' at row 1mysql> select * from t1;
+------+
| data |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
在C/C++中,如果賦值超出類型范圍,會發(fā)生對應的數(shù)據(jù)類型截斷,編譯器不會報錯,但是在MySQL中,數(shù)據(jù)必須具有很強的明確性,超出數(shù)據(jù)類型的范圍,MySQL不允許插入數(shù)據(jù)。
所以在MySQL中,數(shù)據(jù)類型是一種約束。
說明:
- 在MySQL中,整型可以指定是有符號的和無符號的,默認是有符號的。
- 可以通過UNSIGNED來說明某個字段是無符號的。
案例:
mysql> create table t2 (-> data tinyint unsigned -> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t2;
+-------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| data | tinyint(3) unsigned | YES | | NULL | |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0.00 sec)mysql> insert into t2 (data) values (255);
Query OK, 1 row affected (0.00 sec)mysql> insert into t2 (data) values (-1);
ERROR 1264 (22003): Out of range value for column 'data' at row 1mysql> select * from t2;
+------+
| data |
+------+
| 255 |
+------+
1 row in set (0.00 sec)
bit類型
基本語法:
bit[(M)] : 位字段類型。M表示每個值的位數(shù),范圍從1到64。如果M被忽略,默認為1。
舉例:
mysql> create table t3 (-> id int,-> data bit(8)-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t3;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| data | bit(8) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)mysql> insert into t3 (id, data) values (10, 10);
Query OK, 1 row affected (0.00 sec)mysql> select * from t3;
+------+------+
| id | data |
+------+------+
| 10 |
+------+------+
1 row in set (0.00 sec)
通過上面的案例,我們發(fā)現(xiàn)bit字段在顯示時不是直接顯示數(shù)值大小的。
bit字段在顯示時,是按照ASCII碼對應的值顯示的。
mysql> insert into t3 (id, data) values (65, 65);
Query OK, 1 row affected (0.00 sec)mysql> select * from t3;
+------+------+
| id | data |
+------+------+
| 10 |
| 65 | A |
+------+------+
2 rows in set (0.00 sec)
bit可以表示只存放1或0的數(shù)值需求,這樣可以節(jié)省空間。
mysql> create table t4 (-> data bit(1)-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t4;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| data | bit(1) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)mysql> insert into t4 (data) values (1);
Query OK, 1 row affected (0.00 sec)mysql> insert into t4 (data) values (0);
Query OK, 1 row affected (0.00 sec)mysql> insert into t4 (data) values (2);
ERROR 1406 (22001): Data too long for column 'data' at row 1
float類型
基本語法:
float[(m, d)] [unsigned] : M指定顯示長度,d指定小數(shù)位數(shù),占用空間4個字節(jié)
案例:
float(4,2)表示的范圍是-99.99 ~ 99.99,MySQL在保存值時會進行四舍五入。
mysql> create table t5 (-> data float(4, 2)-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t5;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| data | float(4,2) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)mysql> insert into t5 (data) values (99.99);
Query OK, 1 row affected (0.01 sec)mysql> insert into t5 (data) values (-99.99);
Query OK, 1 row affected (0.01 sec)mysql> insert into t5 (data) values (-99.991);
Query OK, 1 row affected (0.01 sec)mysql> insert into t5 (data) values (-99.996);
ERROR 1264 (22003): Out of range value for column 'data' at row 1
mysql> select * from t5;
+--------+
| data |
+--------+
| 99.99 |
| -99.99 |
| -99.99 |
+--------+
3 rows in set (0.00 sec)
案例:
如果定義的是float(4,2) unsigned 這時,因為把它指定為無符號的數(shù),范圍是 0 ~ 99.99
mysql> create table t6 (-> data float(4,2) unsigned -> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.01 sec)mysql> desc t6;
+-------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| data | float(4,2) unsigned | YES | | NULL | |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0.00 sec)mysql> insert into t6 (data) values (0);
Query OK, 1 row affected (0.01 sec)mysql> insert into t6 (data) values (99.99);
Query OK, 1 row affected (0.00 sec)mysql> insert into t6 (data) values (-1);
ERROR 1264 (22003): Out of range value for column 'data' at row 1
mysql> insert into t6 (data) values (100);
ERROR 1264 (22003): Out of range value for column 'data' at row 1
decimal類型
基本語法:
decimal(m, d) [unsigned] : 定點數(shù)m指定長度,d表示小數(shù)點的位數(shù)
- decimal(5,2) 表示的范圍是 -999.99 ~ 999.99
- decimal(5,2) unsigned 表示的范圍 0 ~ 999.99
- decimal和float很像,但是有區(qū)別: float和decimal表示的精度不一樣
案例:
mysql> create table t7 (-> data1 float(10,8),-> data2 decimal(10,8)-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t7;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| data1 | float(10,8) | YES | | NULL | |
| data2 | decimal(10,8) | YES | | NULL | |
+-------+---------------+------+-----+---------+-------+
2 rows in set (0.00 sec)mysql> insert into t7 (data1, data2) values (23.12345612, 23.12345612);
Query OK, 1 row affected (0.00 sec)mysql> select * from t7;
+-------------+-------------+
| data1 | data2 |
+-------------+-------------+
| 23.12345695 | 23.12345612 |
+-------------+-------------+
1 row in set (0.00 sec)
通過上面的案例,我們可以發(fā)現(xiàn)decimal的精度更準確,因此當我們需要高精度儲存浮點數(shù)時,優(yōu)先使用decimal。
- float表示的精度大約是7位。
- decimal整數(shù)最大位數(shù)m為65。支持小數(shù)最大位數(shù)d是30。如果d被省略,默認為0.如果m被省略,默認是10。
字符串類型
char類型
基本語法:
char(L): 固定長度字符串,L是可以存儲的長度,單位為字符,最大長度值可以為255
案例:
mysql> create table t8 (-> data char(2)-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t8;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| data | char(2) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.01 sec)mysql> insert into t8 (data) values ('OK');
Query OK, 1 row affected (0.01 sec)mysql> insert into t8 (data) values ('好的');
Query OK, 1 row affected (0.00 sec)mysql> insert into t8 (data) values ('中國人');
ERROR 1406 (22001): Data too long for column 'data' at row 1mysql> select * from t8;
+--------+
| data |
+--------+
| OK |
| 好的 |
+--------+
2 rows in set (0.00 sec)
char(2) 表示可以存放兩個字符,可以是字母或漢字,但是不能超過2個, 最多只能是255
mysql> create table t8 (-> data char(256)-> )engine=innodb default charset-utf8;
ERROR 1074 (42000): Column length too big for column 'data' (max = 255); use BLOB or TEXT instead
varchar類型
基本語法:
varchar(L): 可變長度字符串,L表示字符長度,最大長度65535個字節(jié)
案例:
mysql> create table t9 (-> data varchar(5)-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.03 sec)mysql> desc t9;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| data | varchar(5) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)mysql> insert into t9 value ('hello');
Query OK, 1 row affected (0.00 sec)mysql> insert into t9 value ('你好,世界');
Query OK, 1 row affected (0.00 sec)mysql> select * from t9;
+-----------------+
| data |
+-----------------+
| hello |
| 你好,世界 |
+-----------------+
2 rows in set (0.00 sec)
關于varchar(len),len到底是多大,這個len值,和表的編碼密切相關:
- varchar長度可以指定為0到65535之間的值,但是有1 - 3 個字節(jié)用于記錄數(shù)據(jù)大小,所以說有效字節(jié)數(shù)是65532。
- 當我們的表的編碼是utf8時,varchar(n)的參數(shù)n最大值是65532/3=21844(因為utf中,一個字符占用3個字節(jié)),如果編碼是gbk,varchar(n)的參數(shù)n最大是65532/2=32766(因為gbk中,一個字符占用2字節(jié))。
mysql> create table t10 (-> data varchar(21845)-> )engine=innodb default charset=utf8;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBsmysql> create table t10 ( data varchar(21844) )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t10;
+-------+----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| data | varchar(21844) | YES | | NULL | |
+-------+----------------+------+-----+---------+-------+
1 row in set (0.00 sec)
char和varchar對比
如何選擇定長或變長字符串?
- 如果數(shù)據(jù)確定長度都一樣,就使用定長(char),比如:身份證,手機號。
- 如果數(shù)據(jù)長度有變化,就使用變長(varchar), 比如:名字,地址,但是你要保證最長的能存的進去。
- 定長的磁盤空間比較浪費,但是效率高。
- 變長的磁盤空間比較節(jié)省,但是效率低。
- 定長的意義是,直接開辟好對應的空間。
- 變長的意義是,在不超過自定義范圍的情況下,用多少,開辟多少。
日期和時間類型
常用的日期有如下三個:
- date :日期 ‘yyyy-mm-dd’ ,占用三字節(jié)
- datetime 時間日期格式 ‘yyyy-mm-dd HH:ii:ss’ 表示范圍從 1000 到 9999 ,占用八字節(jié)
- timestamp :時間戳,從1970年開始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字節(jié)
案例:
mysql> create table t11 (-> d1 date,-> d2 datetime,-> d3 timestamp-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc t11;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| d1 | date | YES | | NULL | |
| d2 | datetime | YES | | NULL | |
| d3 | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
3 rows in set (0.00 sec)mysql> insert into t11 (d1, d2) values ('2023-1-29', '2023-1-29 10:00:00');
Query OK, 1 row affected (0.00 sec)mysql> insert into t11 (d1, d2) values ('2023-1-30', '2023-1-30 11:00:00');
Query OK, 1 row affected (0.00 sec)mysql> select * from t11;
+------------+---------------------+---------------------+
| d1 | d2 | d3 |
+------------+---------------------+---------------------+
| 2023-01-29 | 2023-01-29 10:00:00 | 2023-01-29 21:45:20 |
| 2023-01-30 | 2023-01-30 11:00:00 | 2023-01-29 21:45:29 |
+------------+---------------------+---------------------+
2 rows in set (0.00 sec)
在添加數(shù)據(jù)時,timestamp時間戳會自動添加當前時間,修改數(shù)據(jù)時同理也會修改當前時間。
mysql> select * from t11;
+------------+---------------------+---------------------+
| d1 | d2 | d3 |
+------------+---------------------+---------------------+
| 2023-01-29 | 2023-01-29 10:00:00 | 2023-01-29 21:45:20 |
| 2023-01-30 | 2023-01-30 11:00:00 | 2023-01-29 21:45:29 |
+------------+---------------------+---------------------+
2 rows in set (0.00 sec)mysql> update t11 set d1='2023-1-31';
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2 Changed: 2 Warnings: 0mysql> select * from t11;
+------------+---------------------+---------------------+
| d1 | d2 | d3 |
+------------+---------------------+---------------------+
| 2023-01-31 | 2023-01-29 10:00:00 | 2023-01-29 21:47:55 |
| 2023-01-31 | 2023-01-30 11:00:00 | 2023-01-29 21:47:55 |
+------------+---------------------+---------------------+
2 rows in set (0.00 sec)
enum和set類型
基本語法:
enum:枚舉,“單選”類型;
enum('選項1','選項2','選項3',...);
該設定只是提供了若干個選項的值,最終一個單元格中,實際只存儲了其中一個值;而且出于效率考慮,這些值實際存儲的是“數(shù)字”,因為這些選項的每個選項值依次對應如下數(shù)字:1,2,3,…最多65535個;當我們添加枚舉值時,也可以添加對應的數(shù)字編號。
set:集合,“多選”類型;
set('選項值1','選項值2','選項值3', ...);
該設定只是提供了若干個選項的值,最終一個單元格中,設計可存儲了其中任意多個值;而且出于效率考慮,這些值實際存儲的是“數(shù)字”,因為這些選項的每個選項值依次對應如下數(shù)字:1,2,4,8,16,32,… 最多64個。
說明:不建議在添加枚舉值,集合值的時候采用數(shù)字的方式,因為不利于閱讀。
案例:
有一個調(diào)查表votes,需要調(diào)查人的喜好, (登山,游泳,籃球,武術)中選擇(可以多選),性別(男,女)單選。
mysql> create table votes (-> name varchar(20),-> hobby set('登山','游泳','武術','籃球'),-> gender enum('男','女')-> )engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.02 sec)mysql> desc votes;
+--------+------------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------------------------------+------+-----+---------+-------+
| name | varchar(20) | YES | | NULL | |
| hobby | set('登山','游泳','武術','籃球') | YES | | NULL | |
| gender | enum('男','女') | YES | | NULL | |
+--------+------------------------------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
插入數(shù)據(jù):
mysql> insert into votes (name, hobby, gender) values ('Jame', '游泳,武術', '男');
Query OK, 1 row affected (0.00 sec)mysql> insert into votes (name, hobby, gender) values ('Lisa', '游泳,登山', '女');
Query OK, 1 row affected (0.00 sec)mysql> insert into votes (name, hobby, gender) values ('Jack', '游泳,籃球,武術', '男');
Query OK, 1 row affected (0.01 sec)mysql> insert into votes (name, hobby, gender) values ('Maria', '游泳', '女');
Query OK, 1 row affected (0.00 sec)mysql> select * from votes;
+-------+----------------------+--------+
| name | hobby | gender |
+-------+----------------------+--------+
| Jame | 游泳,武術 | 男 |
| Lisa | 登山,游泳 | 女 |
| Jack | 游泳,武術,籃球 | 男 |
| Maria | 游泳 | 女 |
+-------+----------------------+--------+
4 rows in set (0.00 sec)
有如上數(shù)據(jù),想查找所有喜歡游泳的人:
mysql> select * from votes where hobby='游泳';
+-------+--------+--------+
| name | hobby | gender |
+-------+--------+--------+
| Maria | 游泳 | 女 |
+-------+--------+--------+
1 row in set (0.00 sec)
我們會發(fā)現(xiàn)我們只能查找到興趣愛好只有游泳的人,不能查詢到興趣愛好中含有游泳的人。
集合查詢使用find_ in_ set函數(shù):
find_in_set(sub,str_list) :如果 sub 在 str_list 中,則返回下標;如果不在,返回0; str_list 用逗號分
隔的字符串:
示例:
mysql> select find_in_set('a', 'a,b,c');
+---------------------------+
| find_in_set('a', 'a,b,c') |
+---------------------------+
| 1 |
+---------------------------+
1 row in set (0.00 sec)mysql> select find_in_set('d', 'a,b,c');
+---------------------------+
| find_in_set('d', 'a,b,c') |
+---------------------------+
| 0 |
+---------------------------+
1 row in set (0.00 sec)
在votes表中查詢喜歡游泳的人:
mysql> select * from votes where find_in_set('游泳', hobby);
+-------+----------------------+--------+
| name | hobby | gender |
+-------+----------------------+--------+
| Jame | 游泳,武術 | 男 |
| Lisa | 登山,游泳 | 女 |
| Jack | 游泳,武術,籃球 | 男 |
| Maria | 游泳 | 女 |
+-------+----------------------+--------+
4 rows in set (0.00 sec)