mysql数据分类
int数值类型
int数值类型所占空间大小和范围,与c/c++语言上的类型没什么差别
说明:
1、在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的。
2、可以通过UNSIGNED来说明某个字段是无符号的
bit类型
基本语法
bit[(M)] : 位类型。M表示bit个数,范围从1到64。如果M被忽略,默认为1。
注意事项:
bit类型在显示的时候,是按照ASCII码字符的形式显示的,当然了,只有0-255才可以,而且0-255其实有很多是不可打印字符。如果大于了255,那么打印出来的就是乱码
小数类型
1、float
语法:
float[(m, d)] [unsigned] : M表示数据的最大宽度,数据的实际宽度可以小于这个值,d指定小数位数即精度,小数位数必须是d,float占用空间4个字节
案例:
1、float的范围
float(4,2)表示的范围是-99.99 ~ 99.99
小数位数是2,固定死了,所以小数最值是.99,然后是整数最值,最大数据宽度是4,所以整数最大是99,所以两个最值是-99.99和99.99
2、float的四舍五入
假如我往float(4,2)插入的数据是99.995,达到了2位小数的精度,四舍五入,那就变成了100.000,然后取两位小数100.00,很明显大于了4位的最大宽度,所以无法插入
假如我往里插入的数据是100.4,因为没达到两位小数的精度,所以直接出错
假如我插入的是23.596,达到了小数精度,所以四舍五入,得到了23.600,取两位小数插入的就是23.60
float可以表示的精度大约是7位,也就是说如果数字宽度过大,则会有很大精度损失,注意精度损失和(m,d)约束无关,即使没有约束,也照样会有损失,这是IEEE754标准带来的不可避免的精度损失,float本身并不保证准确存储
2、double
同float,只不过占用空间8字节,大约精度是15位数据宽度
3、decimal
语法:
DECIMAL(M, D)
-
M (精度):数据最大宽度,范围 1-65(MySQL 5.0+),默认 10
-
D (标度):小数点后的位数,范围 0-30,默认 0
存储特性:
与 FLOAT/DOUBLE 不同,DECIMAL 以字符串形式存储,完全避免浮点舍入误差
运算规则:
-
精度扩展:
-
加/减运算:结果小数位数为操作数中最大的D值
-
乘运算:结果小数位数为操作数D值之和
-
-
比较运算:
-
DECIMAL 值可以精确比较,不会出现浮点数的近似比较问题
-
字符串类型
1、char
语法:
char(L): L是可以存储的字符个数,L最大可以是255
说明:
1、char(2) 表示可以存放两个字符,可以是字母或汉字,但是不能超过2个, 且最多只能是255
2、需要注意,实际char类型数据的存储空间是需要根据表的字符集来决定的,如果表的字符集是utf8,那么一个字符就是1~3字节,一个ASCII字符就是1字节,一个汉字就是3字节,但是mysql会统一以最大空间来开辟,一个字符给3字节空间,也就是说char(2)的空间是6字节,且无论你存的是一个字符还是两个字符
3、char的最大字符个数是255,所以char类型数据最大765字节
2、varchar
语法:
varchar(L): 可变长度字符串,L表示最大字符个数,L没有固定限制,但L一定要使表中的一行数据满足不超过65535个字节
实际长度:
varchar数据类型的底层存储是会在头部添加1~2字节的长度字段,用来表示实际数据的字节数,如果实际数据字符数<=255,那这个长度字段就是一字节,mysql限制表中一行数据最大65535字节,用2字节长度字段完全可以表示varchar的实际字节数了。实际数据存储的空间以表的字符集来决定,如果是utf8,那每个字符就会取最大的三字节空间来存储。首部字节数+实际数据的字节数=varchar数据的字节数,要注意,L的最大值是由表的结构来决定的,反正最终表中一行数据不能超过65535字节
说明:
varchar不会根据L来开辟空间,而是根据实际数据来开辟空间,比如varchar(6),存了个‘88’,utf8编码那1字符分配最大的3字节空间,那就是1字节首部+6字节数据=7字节空间
3、char和varchar的比较
日期和时间类型
常用的日期有如下三个:
date :日期,格式 'yyyy-mm-dd' ,占用三字节
datetime :时间日期 ,格式'yyyy-mm-dd HH:ii:ss' ,年的范围从 1000 到 9999 ,占用八字节
timestamp :时间戳,格式‘yyyy-mm-dd HH:ii:ss’ ,占用四字节
案例:
//创建表
mysql> create table birthday (t1 date, t2 datetime, t3 timestamp);
Query OK, 0 rows affected (0.01 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 | 2017-11-12 18:28:55 | --添加数据时,时间戳自动补
上当前时间
+------------+---------------------+---------------------+
//更新数据:
mysql> update birthday set t1='2000-1-1';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from birthday;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 2000-01-01 | 2008-08-08 12:01:01 | 2017-11-12 18:32:09 | -- 更新数据,时间戳会更新
成当前时间
+------------+---------------------+---------------------+
enum和set
enum
语法:
enum('选项1','选项2','选项3',...);
enum枚举是单选类型
说明:
enum提供了若干个选项,最终一个单元格中,实际只存储了其中一个选项;而且出于效率考虑,enum底层实际存储的是“数字”,每个选项值依次对应如下数字:1,2,3,....最多65535 个;当我们使用insert into添加枚举值时,可以直接添加对应的数字编号。
set
语法:
set('选项值1','选项值2','选项值3', ...);
set集合,“多选”类型;
说明:
set 提供了若干个选项,最终一个单元格中,可存储了其中任意多个选项;而且出于效率考虑,这些选项实际存储的是二进制位,因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,.... set最多可以有64个选项。如3就是2+1,那就是选择前两个选项
enum和set的查找案例:
有一个调查表votes,需要调查人的喜好, 比如(登山,游泳,篮球,武术)中去选择(可以多选),
(男,女)[单选]
mysql> create table votes(
-> username varchar(30),
-> hobby set('登山','游泳','篮球','武术'), --注意:使用数字标识每个爱好的时候,想想
Linux权限,采用比特位位置来个set中的爱好对应起来
-> gender enum('男','女')); --注意:使用数字标识的时候,就是正常的数组下标
Query OK, 0 rows affected (0.02 sec)
插入数据:
insert into votes values('雷锋', '登山,武术', '男');
insert into votes values('Juse','登山,武术',2);
select * from votes where gender=2;
+----------+---------------+--------+
| username | hobby | gender |
+----------+---------------+--------+
| Juse | 登山,武术 |女 |
+----------+---------------+--------+
有如下数据,想查找所有喜欢登山的人:
+-----------+---------------+--------+
| username | hobby | gender |
+-----------+---------------+--------+
| 雷锋 | 登山,武术 | 男 |
| Juse | 登山,武术 | 女 |
| LiLei | 登山 | 男 |
| LiLei | 篮球 | 男 |
| HanMeiMei | 游泳 | 女 |
+-----------+---------------+--------+
使用如下查询语句:
mysql> select * from votes where hobby='登山';
+----------+--------+--------+
| username | hobby | gender |
+----------+--------+--------+
| LiLei | 登山 | 男 |
+----------+--------+--------+
不能查询出所有,爱好为登山的人。
集合查询使用find_ in_ set函数:
find_in_set(sub,str_list) :如果 sub 在 str_list 中,则返回下标;如果不在,返回0;
str_list 用逗号分隔的字符串。
注意:
1、sub只能是set中的一个选项,不能是多个选项,多个选项就找不到返回0
2、下表从1开始,如果没找到那就是0
案例:
