資料類型及分類
在MySQL中有着類似于C語言的各種資料類型,他們分别有着不同的大小,适用于不同的資料表示情況。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2csQzaq1UNZpmT4FleYhnRzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuYTO5QzM1YTM2ITMwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
數值類型
在數值類型中與C語言基本類似,每個類型都有有符号與無符号兩種,表示範圍也在上表中有所描述,接下來我挑幾個比較特殊的類型進行講解。
tinyint類型
tinyint
能表示剛好一個位元組大小的數值,與c語言中
char
類型十分類似,不過在MySQL中此類型作為數值類型而非字元類型出現。接下來看看MySQL中對于數值越界的表現。
MariaDB [student]> create table test
(
id tinyint
);
MariaDB [student]> insert into test values(128);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
很明顯,MySQL提醒我們我們所插入的數值越界了。
接下來我們定義一個無符号的
tityint
類型,并插入一個負數。
MariaDB [student]> create table test
-> (
-> id tinyint unsigned
-> );
Query OK, 0 rows affected (0.01 sec)
MariaDB [student]> desc test;
+-------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| id | tinyint(3) unsigned | YES | | NULL | |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0.00 sec)
MariaDB [student]> insert into test values(-1);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
在這裡對無符号插入負數也會顯示越界。在MySQL中可以指定有符号與無符号,預設是有符号的。
bit類型
bit(N)
類型能表示任意位大小的數值,N的數值是1-64如果忽略N則預設是1。
bit
最為特殊的地方是它在顯示的時候預設是按照字元型進行顯示的,這和其他數值類型都不同。
MariaDB [student]> create table test
-> (
-> id int,
-> Bit bit(8)
-> );
Query OK, 0 rows affected (0.11 sec)
MariaDB [student]> insert into test values(10, 10), (65, 65);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [student]> select * from test;
+------+------+
| id | Bit |
+------+------+
| 10 | |
| 65 | A |
+------+------+
2 rows in set (0.00 sec)
可以發現
bit
類型為10的顯示無法出現,而65出現了A,由此則可以說明
bit
類型特殊的顯示方式。同時,如果一個字段隻需要顯示0或1用bit(1)可以大大的減少空間。
float類型
float(M, D)
,M表示顯示的長度,D表示小數的位數,MySQL會自動四舍五入。占用空間四個位元組。
MariaDB [student]> insert into test values(99.991), (99.99);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [student]> select * from test;
+--------+
| salary |
+--------+
| 99.99 |
| 99.99 |
+--------+
2 rows in set (0.00 sec)
MySQL自動将我們的資料多餘的額不服進行四舍五入後再進行存儲。
同時
float
雖然是小數類型但是也同樣擁有無符号類型。
float(4,2)
的範圍就是
0 ~ 99.99
。
decimal類型
decimal
也是小數類型,其大體與
float
類似,但是
decimal
可以表示更大的精度,類似于C語言中的
double型
。
MariaDB [student]> create table test
-> (
-> salary decimal(10,8),
-> salary2 float(10,8)
-> );
Query OK, 0 rows affected (0.00 sec)
MariaDB [student]> insert into test values(12.12345678, 12.12345678);
Query OK, 1 row affected (0.00 sec)
MariaDB [student]> select * from test;
+-------------+-------------+
| salary | salary2 |
+-------------+-------------+
| 12.12345678 | 12.12345695 |
+-------------+-------------+
1 row in set (0.01 sec)
是以我們再要表示精度更高的資料時往往使用
decimal
類型。
float表示的精度大約是7位。
decimal整數最大位數M為65。支援小數最大位數D是30。如果D被省略,預設為0。如果M被省略,預設是
10。
字元串類型
注意在MySQL中字元串用
''
或者
""
标記均可,不做區分
char類型
char(L)
為固定長度字元串類型,最大長度可以是255。意思是說
char
類型的字段存放資料最多隻能放255個字母或者漢字,這點與C語言有很大差別。
MariaDB [student]> create table test
-> (
-> name char(256)
-> );
ERROR 1074 (42000): Column length too big for column 'name' (max = 255); use BLOB or TEXT instead
MariaDB [student]> create table test ( name char(255) );
Query OK, 0 rows affected (0.01 sec)
MariaDB [student]> insert into test values('張三');
Query OK, 1 row affected (0.08 sec)
MariaDB [student]> select * from test;
+--------+
| name |
+--------+
| 張三 |
+--------+
1 row in set (0.00 sec)
varchar類型
varchar(L)
為可變長度字元串類型,最大長度為65535。
其實
varchar
最大長度為多少與字元編碼密切相關,varchar長度可以指定為0到65535之間的值,但是有1 - 3個位元組用于記錄資料大小,是以說有效位元組數是65532。當我們的表的編碼是utf8時,varchar(n)的參數n最大值是65532/3=21844[因為utf中,一個字元占用3個字
節],如果編碼是gbk,varchar(n)的參數n最大是65532/2=32766(因為gbk中,一個字元占用2位元組)。
MariaDB [student]> create table test ( name varchar(21845) )charset=utf8;
ERROR 1074 (42000): Column length too big for column 'name' (max = 21844); use BLOB or TEXT instead
以上代碼驗證了utf8下确實長度不能超過21844。
同時
char
與
varchar
之間關于定長和變長有着很大的差別。
如上表所示,通常我們在使用
char
類型時,定義多長的長度,實際使用時不會改變大小,但是
varchar
不同,會根據實際存儲資料大小進行自動調節和變更,但是會多占用一個位元組的大小,同時還很吃效率,是以實際使用中選擇合适的類型是至關重要的。
日期類型和時間類型
常用的時間類型有以下三個。
datetime 時間日期格式 ‘yyyy-mm-dd HH:ii:ss’ 表示範圍從1000到9999,占用八位元組。
date:日期 ‘yyyy-mm-dd’,占用三位元組。
timestamp:時間戳,從1970年開始的 yyyy-mm-dd HH:ii:ss格式和datetime完全一緻,占用四位元組。
時間戳我們在C語言中也已經有所接觸了,可以幫助我們自動顯示目前的時間,但是時間戳也有大小限制。(貌似目前已經快到極限了)
MariaDB [student]> create table test
-> (
-> d1 date,
-> d2 datetime,
-> d3 timestamp
-> );
Query OK, 0 rows affected (0.01 sec)
MariaDB [student]> insert into test(d1,d2) values('1999-1-20', '1999-1-20 1:0:0');
Query OK, 1 row affected (0.01 sec)
MariaDB [student]> select * from test;
+------------+---------------------+---------------------+
| d1 | d2 | d3 |
+------------+---------------------+---------------------+
| 1999-01-20 | 1999-01-20 01:00:00 | 2019-01-19 09:51:26 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec)
時間戳會自動幫我們補齊,取目前系統時間。
enum和set類型
enum
枚舉類型,用于多選一。最多可添加65535個選項。
set
集合類型,用于多選多。最多可添加64個選項。
MariaDB [student]> create table test
-> (
-> username varchar(30),
-> hobby set('遊戲','追番','搞比利'),
-> gender enum('男','女')
-> );
Query OK, 0 rows affected (0.04 sec)
MariaDB [student]> insert into test values('張三','搞比利,追番','男');
Query OK, 1 row affected (0.00 sec)
MariaDB [student]> insert into test values('李四','遊戲,追番',2);
Query OK, 1 row affected (0.00 sec)
MariaDB [student]> select * from test;
+----------+------------------+--------+
| username | hobby | gender |
+----------+------------------+--------+
| 張三 | 追番,搞比利 | 男 |
| 李四 | 遊戲,追番 | 女 |
+----------+------------------+--------+
2 rows in set (0.00 sec)
我們在給
enum
和
set
類型添加資料時可以選擇使用數字選擇選項的方式進行添加,但是不建議這種方式,因為十分不利于代碼可讀性。
MariaDB [student]> select * from test where hobby = '追番,搞比利';
+----------+------------------+--------+
| username | hobby | gender |
+----------+------------------+--------+
| 張三 | 追番,搞比利 | 男 |
+----------+------------------+--------+
1 row in set (0.00 sec)
我們同時可以使用以上方式找到集合中指定選項的所有資料。還可以利用
find_in_set()
函數進行查詢。
MariaDB [student]> select * from test where find_in_set('追番',hobby);
+----------+------------------+--------+
| username | hobby | gender |
+----------+------------------+--------+
| 張三 | 追番,搞比利 | 男 |
| 李四 | 遊戲,追番 | 女 |
+----------+------------------+--------+
2 rows in set (0.01 sec)
由此即可查詢出所有hobby集合中包含追番的資料。