我们往里面插入一些有效数据时:
mysql> insert into test1 values(10);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test1 values(-10);
Query OK, 1 row affected (0.01 sec)
mysql> select *from test1;
+------+
| num |
+------+
| 10 |
| -10 |
+------+
2 rows in set (0.00 sec)
当我们插入越界数据时;
mysql> insert into test1 values(128);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> insert into test1 values(-129);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> insert into test1 values(-200);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
这里会报错,这跟我们C/C++语法不太一样,在C/C++语法中,超过了类型的最大范围后会发生截断,但是在MySQL中超过了该类型字段的最大范围后直接报错,这种严厉的规范其实是比较好的。
在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的,可以通过unsigned
来说明某个字段是无符号的,比如;
mysql> create table test2(num tinyint unsigned);
Query OK, 0 rows affected (0.02 sec)
mysql> desc test2;
+-------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| num | tinyint(3) unsigned | YES | | NULL | |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0.00 sec)
我们往里面插入一些负数时:
mysql> insert into test2 values(-1);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> insert into test2 values(-5);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
会直接报错,但是我们可以插入0或者在tinyint范围内的数据:
mysql> insert into test2 values(0);
Query OK, 1 row affected (0.00 sec)
其他的数值类型也是同理只是范围不一样罢了,大家下去可自行验证。
基本语法:
bit[(M)] : 位字段类型。M表示每个值的位数,范围从1到64。如果M被忽略,默认为1。
举例:
create table test3(id int,is_exit bit(8));
我们向test3里面插入下面的数据:
mysql> insert into test3 values(1,32);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test3 values(2,64);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test3 values(3,97);
Query OK, 1 row affected (0.00 sec)
当我们查询时却发生了怪异的现象,为啥1中的is_exit显示不出来呢?这时因为bit类型显示默认都是以ASCII码的形式来显现,而ASCII码为32的字符是不可显字符。
我们再进行插入:
mysql> insert into test3 values(4,128);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test3 values(5,256);
ERROR 1406 (22001): Data too long for column 'is_exit' at row 1
mysql> insert into test3 values(5,255);
Query OK, 1 row affected (0.01 sec)
发现255可以插入,但是256却不可以插入了,这是因为我们定义的bit类型最大为8个比特位,表示的最大范围为0 ~ 28-1(255)。
语法:
float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4个字节
案例:
小数:float(4,2)表示的范围是-99.99 ~ 99.99,MySQL在保存值时会进行四舍五入。
mysql> create table test4(num float(4,2));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into test4 values(99.99);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test4 values(-99.99);
Query OK, 1 row affected (0.01 sec)
当我们插入下面数据时:
mysql> insert into test4 values(-99.994);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test4 values(-99.995);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
我们发现-99.994可以插入成功,但是-99.995却不可以插入成功,这是因为-99.994四舍五入后为-99.99,而-99.995四舍五入后超过了所定义的范围。
如果定义的是float(4,2) unsigned ,因为把它指定为无符号的数,范围是 0 ~ 99.99。
double的用法与float基本类似,这里就不再多讲解了。
语法:
decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数
decimal(5,2) 表示的范围是 -999.99 ~ 999.99
decimal(5,2) unsigned 表示的范围 0 ~ 999.99
decimal和float很像,但是有区别: float和decimal表示的精度不一样,比如下面:
mysql> insert into test5 values(10.12345678,10.12345678);
Query OK, 1 row affected (0.01 sec)
mysql> select* from test5;
+-------------+-------------+
| f1 | d1 |
+-------------+-------------+
| 10.12345695 | 10.12345678 |
+-------------+-------------+
1 row in set (0.00 sec)
我们发现使用decimal
是更加精确的。因此如果我们希望某个数据表示高精度,选择decimal。
说明:
语法:
char(L): 固定长度字符串,L是可以存储的长度,单位为字符,最大长度值可以为255
注意上面指定的L是表示可以存储字符的长度,并不是字节。
语法:
varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节
案例:
mysql> create table test6(id int,str varchar(128));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into test6 values(1,'我爱你');
Query OK, 1 row affected (0.01 sec)
mysql> insert into test6 values(2,'我爱你,中国');
Query OK, 1 row affected (0.01 sec)
mysql> insert into test6 values(3,'我爱你,中国人');
Query OK, 1 row affected (0.00 sec)
mysql> select* from test6;
+------+-----------------------+
| id | str |
+------+-----------------------+
| 1 | 我爱你 |
| 2 | 我爱你,中国 |
| 3 | 我爱你,中国人 |
+------+-----------------------+
3 rows in set (0.00 sec)
说明:
关于varchar(len),len到底是多大,这个len值,和表的编码密切相关
常用的日期有如下三个:
案例:
mysql> create table birthday (t1 date, t2 datetime, t3 timestamp);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into birthday(t1,t2) values('1997-7-1','2008-8-8 12:1:1');
Query OK, 1 row affected (0.00 sec)
mysql> select *from birthday;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 1997-07-01 | 2008-08-08 12:01:01 | 2023-08-18 15:08:48 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec)
timestamp不需要我们自己填充。
当我们更新数据时:
mysql> update birthday set t1='2000-1-1';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select* from birthday;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 2000-01-01 | 2008-08-08 12:01:01 | 2023-08-18 15:10:51 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec)
timestamp会自动更新到最新时间。
语法:
enum:枚举,“单选”类型;
enum('选项1','选项2','选项3',...);
set:集合,“多选”类型;
set('选项值1','选项值2','选项值3', ...);
说明:不建议在添加枚举值,集合值的时候采用数字的方式,因为不利于阅读。
案例:
mysql> create table hobby(
-> gender enum('男','女'),
-> hobby_sport set('羽毛球','乒乓球','篮球','排球','网球')
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> desc hobby;
+-------------+---------------------------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------------------------------------------+------+-----+---------+-------+
| gender | enum('男','女') | YES | | NULL | |
| hobby_sport | set('羽毛球','乒乓球','篮球','排球','网球') | YES | | NULL | |
+-------------+---------------------------------------------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
当我们插入数据时:
mysql> insert into hobby values('男','羽毛球,篮球');
Query OK, 1 row affected (0.01 sec)
mysql> insert into hobby values('女','网球,排球');
Query OK, 1 row affected (0.00 sec)
mysql> select *from hobby;
+--------+------------------+
| gender | hobby_sport |
+--------+------------------+
| 男 | 羽毛球,篮球 |
| 女 | 排球,网球 |
+--------+------------------+
我们甚至还可以使用数值来插入:
mysql> insert into hobby values(1,7);
Query OK, 1 row affected (0.00 sec)
mysql> insert into hobby values(2,4);
Query OK, 1 row affected (0.01 sec)
mysql> insert into hobby values(2,11);
Query OK, 1 row affected (0.00 sec)
mysql> select* from hobby;
+--------+----------------------------+
| gender | hobby_sport |
+--------+----------------------------+
| 男 | 羽毛球,篮球 |
| 女 | 排球,网球 |
| 男 | 羽毛球,乒乓球,篮球 |
| 女 | 篮球 |
| 女 | 羽毛球,乒乓球,排球 |
+--------+----------------------------+
5 rows in set (0.00 sec)
其中值得注意的点是enum
使用数值插入时,从1开始不断增加,而set
则是用二进制来表示,不过注意二进制左边为低权值位,右边为高权值位,比如上面插入7,用二进制表示应该为00111,但是我们要将二进制颠倒过来变成11100 ,就表示(‘羽毛球’,‘乒乓球’,‘篮球’)。
假设我们向查询出喜欢篮球的人:
mysql> select * from hobby where hobby_sport='篮球';
+--------+-------------+
| gender | hobby_sport |
+--------+-------------+
| 女 | 篮球 |
+--------+-------------+
1 row in set (0.00 sec)
我们发现只查询到了只喜欢打篮球的人,这明显不符合我们的预期,我们想要的是爱好有篮球的人,此时我们可以使用find_ in_ set
函数。
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)
查询喜欢打篮球的人:
mysql> select * from hobby where find_in_set('篮球', hobby_sport);
+--------+----------------------------+
| gender | hobby_sport |
+--------+----------------------------+
| 男 | 羽毛球,篮球 |
| 男 | 羽毛球,乒乓球,篮球 |
| 女 | 篮球 |
+--------+----------------------------+
3 rows in set (0.00 sec)