MySQL數據類型

1. INT類型

(1)int類型分類
MySQL數據類型
(2)int使用
自增id推薦使用BIGINT,而不是INT
unsigned or signed(根據情況使用,一般推薦使用默認的signed)
注意事項

root@localhost:mysql.sock1 [test]>create table test_unsigned(a int unsigned,b int unsigned);
Query OK, 0 rows affected (5.08 sec)

root@localhost:mysql.sock1 [test]>insert into test_unsigned values(1,2);
Query OK, 1 row affected (0.08 sec)

root@localhost:mysql.sock1 [test]>select a-b from test_unsigned;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(`test`.`test_unsigned`.`a` - `test`.`test_unsigned`.`b`)'
root@localhost:mysql.sock1 [test]>show variables like 'sql_mode%';
+---------------+--------------------------------------------+
| Variable_name | Value                                      |
+---------------+--------------------------------------------+
| sql_mode      | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>set sql_mode='no_unsigned_subtraction';
Query OK, 0 rows affected (0.00 sec)

root@localhost:mysql.sock1 [test]>select a-b from test_unsigned;
+------+
| a-b  |
+------+
|   -1 |
+------+
1 row in set (0.00 sec)

一般情況下使用int,推薦有符號(signed),使用無符號數只是比原來多一倍的取值,數量級上沒有改變。
(3)INT(N)

root@localhost:mysql.sock1 [test]>show create table test_unsigned\G;
*************************** 1. row ***************************
       Table: test_unsigned
Create Table: CREATE TABLE `test_unsigned` (
  `a` int(10) unsigned DEFAULT NULL,
  `b` int(10) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

int(N)中的N是顯示寬度,不表示存儲的數字的長度的上限。
zerofill表示當存儲的數字長度 < N 時,用數字0填充左邊,直到補滿N長度。
當存儲數字長度超過N時,按照實際存儲的數字顯示

root@localhost:mysql.sock1 [test]>create table test_int(a int(3) zerofill);
Query OK, 0 rows affected (0.04 sec)

root@localhost:mysql.sock1 [test]>insert into test_int values(1);
Query OK, 1 row affected (0.00 sec)

root@localhost:mysql.sock1 [test]>select * from test_int;
+------+
| a    |
+------+
|  001 |
+------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>insert into test_int values(1111);
Query OK, 1 row affected (0.02 sec)

root@localhost:mysql.sock1 [test]>select * from test_int;
+------+
| a    |
+------+
|  001 |
| 1111 |
+------+
2 rows in set (0.00 sec)

root@localhost:mysql.sock1 [test]>select a,HEX(a) from test_int\G;
*************************** 1. row ***************************
     a: 001
HEX(a): 1
*************************** 2. row ***************************
     a: 1111
HEX(a): 457
2 rows in set (0.00 sec)

int(N)中的N和zerofill配合纔有意義。

(4)AUTO_INCREMENT
自增
每張表只有一個
必須是索引的一部分

root@localhost:mysql.sock1 [test]>create table test_auto_increment(a int auto_increment);
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
root@localhost:mysql.sock1 [test]>create table test_auto_increment(a int auto_increment primary key);
Query OK, 0 rows affected (0.04 sec)

root@localhost:mysql.sock1 [test]>insert into test_auto_increment values(NULL);
Query OK, 1 row affected (0.01 sec)

root@localhost:mysql.sock1 [test]>select * from test_auto_increment;
+---+
| a |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>insert into test_auto_increment values(0);
Query OK, 1 row affected (0.01 sec)

root@localhost:mysql.sock1 [test]>select * from test_auto_increment;
+---+
| a |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0.00 sec)

root@localhost:mysql.sock1 [test]>insert into test_auto_increment values(-1);
Query OK, 1 row affected (0.01 sec)

root@localhost:mysql.sock1 [test]>select * from test_auto_increment;
+----+
| a  |
+----+
| -1 |
|  1 |
|  2 |
+----+
3 rows in set (0.00 sec)

root@localhost:mysql.sock1 [test]>insert into test_auto_increment select '0';
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

root@localhost:mysql.sock1 [test]>select * from test_auto_increment;
+----+
| a  |
+----+
| -1 |
|  1 |
|  2 |
|  3 |
+----+
4 rows in set (0.00 sec)

root@localhost:mysql.sock1 [test]>update test_auto_increment set a=0 where a=-1;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1  Changed: 1  Warnings: 0

root@localhost:mysql.sock1 [test]>select * from test_auto_increment;
+---+
| a |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
+---+
4 rows in set (0.00 sec)

root@localhost:mysql.sock1 [test]>insert into test_auto_increment values (NULL),(100),(NULL);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

root@localhost:mysql.sock1 [test]>select * from test_auto_increment;
+-----+
| a   |
+-----+
|   0 |
|   1 |
|   2 |
|   3 |
|   4 |
| 100 |
| 101 |
+-----+
7 rows in set (0.00 sec)

root@localhost:mysql.sock1 [test]>insert into test_auto_increment select 99;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

root@localhost:mysql.sock1 [test]>select * from test_auto_increment;
+-----+
| a   |
+-----+
|   0 |
|   1 |
|   2 |
|   3 |
|   4 |
|  99 |
| 100 |
| 101 |
+-----+
8 rows in set (0.00 sec)

另外 insert into test_auto_increment select NULL 等價於 insert into test_auto_increment values(NULL);

2. 數字類型

MySQL數據類型
注意財物系統必須用DECIMAL

3. 字符串類型

(1)字符串類型介紹
MySQL數據類型

(2)N和字符集
假設當前table的字符集的 最大長度 爲 W , 則 char(N) 的最大存儲空間爲 (N X W)Byte ;假設使用 UTF-8 ,則char(10)可以最小存儲10個字節的字符,最大存儲30個字節的字符,其實是另一種意義上的 varchar ,
當存儲的字符數 小於N 時,尾部使用 空格 填充,並且填充最小字節的空格

測試char(n)

root@localhost:mysql.sock1 [test]>create table test_char(a char(10));
Query OK, 0 rows affected (0.52 sec)

root@localhost:mysql.sock1 [test]>show create table test_char;
+-----------+------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                   |
+-----------+------------------------------------------------------------------------------------------------+
| test_char | CREATE TABLE `test_char` (
  `a` char(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-----------+------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

root@localhost:mysql.sock1 [test]>insert into test_char values('abc');
Query OK, 1 row affected (0.08 sec)

root@localhost:mysql.sock1 [test]>insert into test_char values('你好嗎');
Query OK, 1 row affected (0.12 sec)

root@localhost:mysql.sock1 [test]>insert into test_char values('大家好ab');
Query OK, 1 row affected (0.06 sec)

root@localhost:mysql.sock1 [test]>insert into test_char values('大家ab好');
Query OK, 1 row affected (0.09 sec)

root@localhost:mysql.sock1 [test]>insert into test_char values('大家ab好嗎');
Query OK, 1 row affected (0.05 sec)

root@localhost:mysql.sock1 [test]>select a,length(a) from test_char;
+----------------+-----------+
| a              | length(a) |
+----------------+-----------+
| abc            |         3 |
| 你好嗎         |         9 |
| 大家好ab       |        11 |
| 大家ab好       |        11 |
| 大家ab好嗎     |        14 |
+----------------+-----------+
5 rows in set (0.13 sec)

root@localhost:mysql.sock1 [test]>select a,hex(a) from test_char;
+----------------+------------------------------+
| a              | hex(a)                       |
+----------------+------------------------------+
| abc            | 616263                       |
| 你好嗎         | E4BDA0E5A5BDE59097           |
| 大家好ab       | E5A4A7E5AEB6E5A5BD6162       |
| 大家ab好       | E5A4A7E5AEB66162E5A5BD       |
| 大家ab好嗎     | E5A4A7E5AEB66162E5A5BDE59097 |
+----------------+------------------------------+
5 rows in set (0.00 sec)

root@localhost:mysql.sock1 [test]>select hex(' ');
+----------+
| hex(' ') |
+----------+
| 20       |
+----------+
1 row in set (0.00 sec)

測試 varchar(n) 類型 這裏就不介紹了。。

(3)BLOB和TEXT
在BLOB和TEXT上創建索引時,必須制定索引前綴的長度

root@localhost:mysql.sock1 [test]>create table test_text(a int primary key,b text,key(b));
ERROR 1170 (42000): BLOB/TEXT column 'b' used in key specification without a key length
root@localhost:mysql.sock1 [test]>create table test_text(a int primary key,b text,key(b(64)));
Query OK, 0 rows affected (0.17 sec)

BLOB和TEXT列不能有默認值
BLOB和TEXT列排序時只使用該列的前max_sort_length個字節
root@localhost:mysql.sock1 [test]>select @@max_sort_length;
+-------------------+
| @@max_sort_length |
+-------------------+
| 1024 |
+-------------------+
1 row in set (0.04 sec)
不建議在mysql中存儲大型的二進制數據比如歌曲視頻等。

4. 字符集

(1)常見字符集
utf8 utf8mb4 gbk gb18030
root@localhost:mysql.sock1 [test]>show character set;
+----------+------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+------------------+---------------------+--------+
| big5 | | big5_chinese_ci | 2 |
| dec8 | | dec8_swedish_ci | 1 |
| cp850 | | cp850_general_ci | 1 |
| hp8 | | hp8_english_ci | 1 |
| koi8r | | koi8r_general_ci | 1 |
| latin1 | | latin1_swedish_ci | 1 |
| latin2 | | latin2_general_ci | 1 |
| swe7 | | swe7_swedish_ci | 1 |
| ascii | | ascii_general_ci | 1 |
| ujis | | ujis_japanese_ci | 3 |
| sjis | | sjis_japanese_ci | 2 |
| hebrew | | hebrew_general_ci | 1 |
| tis620 | | tis620_thai_ci | 1 |
| euckr | | euckr_korean_ci | 2 |
| koi8u | | koi8u_general_ci | 1 |
| gb2312 | | gb2312_chinese_ci | 2 |
| greek | | greek_general_ci | 1 |
| cp1250 | | cp1250_general_ci | 1 |
| gbk | | gbk_chinese_ci | 2 |
| latin5 | | latin5_turkish_ci | 1 |
| armscii8 | | armscii8_general_ci | 1 |
| utf8 | | utf8_general_ci | 3 |
| ucs2 | | ucs2_general_ci | 2 |
| cp866 | | cp866_general_ci | 1 |
| keybcs2 | | keybcs2_general_ci | 1 |
| macce | | macce_general_ci | 1 |
| macroman | | macroman_general_ci | 1 |
| cp852 | | cp852_general_ci | 1 |
| latin7 | | latin7_general_ci | 1 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_general_ci | 4 |
| cp1251 | | cp1251_general_ci | 1 |
| utf16 | UTF-16 Unicode | utf16_general_ci | 4 |
| utf16le | UTF-16LE Unicode | utf16le_general_ci | 4 |
| cp1256 | | cp1256_general_ci | 1 |
| cp1257 | | cp1257_general_ci | 1 |
| utf32 | UTF-32 Unicode | utf32_general_ci | 4 |
| binary | | binary | 1 |
| geostd8 | | geostd8_general_ci | 1 |
| cp932 | | cp932_japanese_ci | 2 |
| eucjpms | | eucjpms_japanese_ci | 3 |
+----------+------------------+---------------------+--------+
40 rows in set (0.09 sec)

(2)排序規則(collation)
collation的含義是指排序規則, ci(case insensitive) 結尾的排序集是不區分大小寫的

root@localhost:mysql.sock1 [test]>show variables like 'colla%';
+----------------------+--------------------+
| Variable_name        | Value              |
+----------------------+--------------------+
| collation_connection | utf8_general_ci    |
| collation_database   | utf8mb4_general_ci |
| collation_server     | utf8mb4_general_ci |
+----------------------+--------------------+

root@localhost:mysql.sock1 [test]>select 'a'='A';
+---------+
| 'a'='A' |
+---------+
|       1 |
+---------+
1 row in set (0.05 sec)

root@localhost:mysql.sock1 [test]>select 'a'='A   ';
+------------+
| 'a'='A   ' |
+------------+
|          1 |
+------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>create table test_ci (a varchar(10),key(a));
Query OK, 0 rows affected (0.13 sec)

root@localhost:mysql.sock1 [test]>insert into test_ci values('a');
Query OK, 1 row affected (0.18 sec)

root@localhost:mysql.sock1 [test]>insert into test_ci values('A');
Query OK, 1 row affected (0.08 sec)

root@localhost:mysql.sock1 [test]>select * from test_ci where a='a';
+------+
| a    |
+------+
| a    |
| A    |
+------+
2 rows in set (0.09 sec)

root@localhost:mysql.sock1 [test]>select * from test_ci where a='A';
+------+
| a    |
+------+
| a    |
| A    |
+------+
2 rows in set (0.00 sec)

上面的情況如果從業務的角度上看,可以很好理解,比如創建一個用戶叫做Tom,你是不希望再創建一個叫做tom的用戶的

修改默認的collation(當前session有效)
root@localhost:mysql.sock1 [test]>set names utf8mb4 collate utf8mb4_bin;
Query OK, 0 rows affected (0.05 sec)

root@localhost:mysql.sock1 [test]>select 'a'='A';
+---------+
| 'a'='A' |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)

字符集的指定,可以在創建數據庫的時候指定,也可以在創建表的時候單獨指定,也可以創建列的時候進行指定

5. 集合類型

集合類型ENUM和SET
ENUM類型最多允許65536值
set類型最多允許64個值
通過sql_mode參數可以約束用戶約束檢查。

(1)集合類型排序
root@localhost:mysql.sock1 [test]>create table test_col(user varchar(10),sex enum('male','fmale'));
Query OK, 0 rows affected (0.20 sec)

root@localhost:mysql.sock1 [test]>insert into test_col values("tom","male");
Query OK, 1 row affected (0.00 sec)

root@localhost:mysql.sock1 [test]>insert into test_col values("tom","xxxmale");
ERROR 1265 (01000): Data truncated for column 'sex' at row 1
root@localhost:mysql.sock1 [test]>insert into test_col values("tom","xmale");
ERROR 1265 (01000): Data truncated for column 'sex' at row 1
root@localhost:mysql.sock1 [test]>set sql_mode='strict_trans_tables';
Query OK, 0 rows affected (0.00 sec)

上面因爲報錯我的my.cnf配置裏面已經寫了sql_mode的配置。嚴格要求檢查。
強烈建議新業務上都設置成嚴格模式

(2)集合類型排序
create table test_col_sort(
user char(10),
type enum('aaa','zzz','bbb','yyy','fff')
);

insert into test_col_sort values ('user1','aaa');
insert into test_col_sort values ('user2','zzz');
insert into test_col_sort values ('user3','bbb');
insert into test_col_sort values ('user4','yyy');

與type作爲key,進行升序排序
select from test_col_sort order by type asc;
select
from test_col_sort order by cast(type as char) asc; //cast轉換爲某種類型。
select * from test_col_sort order by concat(type) asc; //concat()是連接字符串函數

6. 日期類型

MySQL數據類型
(1)TIMESTAMD和DATETIME

root@localhost:mysql.sock1 [test]>create table test_time(a timestamp,b datetime);
Query OK, 0 rows affected (0.15 sec)

root@localhost:mysql.sock1 [test]>insert into test_time values(now(),now());
Query OK, 1 row affected (0.04 sec)

root@localhost:mysql.sock1 [test]>select * from test_time;
+---------------------+---------------------+
| a | b |
+---------------------+---------------------+
| 2018-01-15 00:17:52 | 2018-01-15 00:17:52 |
+---------------------+---------------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>select @@time_zone;
+-------------+
| @@time_zone |
+-------------+
| SYSTEM |
+-------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>set time_zone='+00:00';
Query OK, 0 rows affected (0.00 sec)

root@localhost:mysql.sock1 [test]>select @@time_zone;
+-------------+
| @@time_zone |
+-------------+
| +00:00 |
+-------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>select * from test_time;
+---------------------+---------------------+
| a | b |
+---------------------+---------------------+
| 2018-01-14 16:17:52 | 2018-01-15 00:17:52 |
+---------------------+---------------------+
1 row in set (0.00 sec)

(2)微妙
從mysql5.6.x開始,支持微妙,最大顯示6位。

root@localhost:mysql.sock1 [test]>select now();
+---------------------+
| now() |
+---------------------+
| 2018-01-14 16:20:27 |
+---------------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>select now(7);
ERROR 1426 (42000): Too big precision 7 specified for column 'now'. Maximum is 6.
root@localhost:mysql.sock1 [test]>select now(6);
+----------------------------+
| now(6) |
+----------------------------+
| 2018-01-14 16:20:44.778626 |
+----------------------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>create table test_time_fac(t datetime(6));
Query OK, 0 rows affected (0.10 sec)

root@localhost:mysql.sock1 [test]>insert into test_time_fac values(now(6));
Query OK, 1 row affected (0.00 sec)

root@localhost:mysql.sock1 [test]>select * from test_time_fac;
+----------------------------+
| t |
+----------------------------+
| 2018-01-14 16:21:57.664172 |
+----------------------------+
1 row in set (0.00 sec)

(3)時間函數
常用函數
MySQL數據類型
root@localhost:mysql.sock1 [test]>select now(6),sysdate(6),sleep(5),now(6),sysdate(6);
+----------------------------+----------------------------+----------+----------------------------+----------------------------+
| now(6) | sysdate(6) | sleep(5) | now(6) | sysdate(6) |
+----------------------------+----------------------------+----------+----------------------------+----------------------------+
| 2018-01-14 16:24:28.193852 | 2018-01-14 16:24:28.194042 | 0 | 2018-01-14 16:24:28.193852 | 2018-01-14 16:24:33.250232 |
+----------------------------+----------------------------+----------+----------------------------+----------------------------+
1 row in set (5.06 sec)

增加5天
root@localhost:mysql.sock1 [test]>select date_add(now(),interval 5 day);
+--------------------------------+
| date_add(now(),interval 5 day) |
+--------------------------------+
| 2018-01-19 16:27:15 |
+--------------------------------+
1 row in set (0.00 sec)

減少5天
root@localhost:mysql.sock1 [test]>select date_add(now(),interval -5 day);
+---------------------------------+
| date_add(now(),interval -5 day) |
+---------------------------------+
| 2018-01-09 16:28:28 |
+---------------------------------+
1 row in set (0.00 sec)

增加5月
root@localhost:mysql.sock1 [test]>select date_add(now(),interval 5 month);
+----------------------------------+
| date_add(now(),interval 5 month) |
+----------------------------------+
| 2018-06-14 16:28:54 |
+----------------------------------+
1 row in set (0.00 sec)

還有其他函數,這裏就不一一講了。。

(4)字段更新時間
create table test_field_update(
a int(10),
b timestamp not null default current_timestamp on update current_timestamp
);

insert into test_field_update values(1, now(6));

root@localhost:mysql.sock1 [test]>select * from test_field_update;
+------+---------------------+
| a | b |
+------+---------------------+
| 1 | 2018-01-14 16:34:05 |
+------+---------------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock1 [test]>update test_field_update set a=100 where a=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

root@localhost:mysql.sock1 [test]>select * from test_field_update;
+------+---------------------+
| a | b |
+------+---------------------+
| 100 | 2018-01-14 16:34:48 |
+------+---------------------+
1 row in set (0.00 sec)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章