MySQL 数据类型
MySQL数据类型(列类型)可归纳为数值型、时间日期型和字符型号。
1.数值型
1.1整数型
tinyint(1), smallint(2), mediumint(3),int(4), bigint(8)。括号中表示该类型所占空间的长度(字节数)
如果为一个数值列指定ZEROFILL,MySQL自动为该列添加UNSIGNED属性。
1.2 小数类型
1.2.1 浮点数
对于浮点列类型,在MySQL中单精度值使用4个字节,双精度值使用8个字节。
MySQL允许使用非标准语法:FLOAT(M,D)或REAL(M,D)或DOUBLE
PRECISION(M,D)。这里,“(M,D)”表示该值一共显示M位整数,其中D位位于小数点后面。例如,定义为FLOAT(7,4)的一个列可以显示为-999.9999。MySQL保存值时进行四舍五入,因此如果在FLOAT(7,4)列内插入999.00009,近似结果是999.0001。
1.2.2 定点数
DECIMAL类型在MySQL中用于保存必须为确切精度的值,例如货币数据。salary decimal(5,2) 5是精度,2是标度。
DECIMAL型的取值范围和DOUBLE相同。但是DECIMAL的有效取值范围由M和D决定,而且DECIMAL型的字节数是M+2。也就是说,定点数的存储空间是根据其精度决定的。
下面详细谈一下float与decimal 的区别
1.指定了精度
建表语句如下:
create table salary_tax(
id int auto_increment,
name varchar(128) not null,
depart varchar(128) not null,
salary float(10,2) not null,
tax decimal(10,2) not null,
primary key(id)
)engine = innodb default charset = utf8;
插入几条数据:
insert into salary_tax (id,name,depart,salary,tax) values(1,'zhang','development',8500.00,1025.45),(2,'liu','sale',10500.00,1725.55),(3,'xiaoming','sale',4256.345,4256.345),(4,'xiaohua','hr',3785.325,3785.325);
insert into salary_tax (id,name,depart,salary,tax) values(5,'hello','sale',12345.3241,12345.3241),(6,'world','sale',1235.4679,1235.4679);
数据库显示结果如下:
分析可知,
如果插入值的精度高于实际定义的精度,系统会自动进行四舍五入处理,使值的精度达到要求
(而且好像float 和decimal 四舍五入处理方式不同【第四条记录】)。
建表语句如下:
create table floatDecimal(
id int auto_increment,
floatValue float(14,4) not null,
decimalValue decimal(14,4) not null,
primary key(id)
)engine = innodb default charset = utf8;
插入数据:
insert into floatDecimal(id,floatValue,decimalValue) values(1,23489.1251,23489.1251),(2,235689.5689,235689.5689),(3,568932.56894,568932.56894);
数据库显示如下:
可以看到
浮点数在存储过程中会出现精度丢失的问题
2.未指定精度
建表语句如下:
create table notprecision(
id int auto_increment,
floatvalue float not null,
decimalvalue decimal not null,
primary key(id)
)engine = innodb default charset = utf8;
插入数据:
insert into notprecision(id,floatvalue,decimalvalue) values(1,23489492.12515158,23489492.12515158),(2,3.1415926,3.1415926),(3,1.1314512,1.1314512),(4,23,23);
insert into notprecision(id,floatvalue,decimalvalue) values(5,234894920.1
2515158,234894920.12515158);
insert into notprecision(id,floatvalue,decimalvalue) values(7,23489492089
89.12515158,2348949208989.12515158);
浮点数和定点数有默认的精度,float和double默认会保存实际精度,decimal型的默认整数位为10,小数位为0,即默认为整数。
在MySQL中,定点数以字符串形式存储,因此,其精度比浮点数要高。
2.日期时间型
mysql 时间类型有,date,time,datetime,timestamp,year五种。
date类型: 支持的范围为’1000-01-01’到’9999-12-31’
time类型: 支持的范围是’-838:59:59’到’838:59:59’
datetime类型:支持的范围是’1000-01-01 00:00:00’到’9999-12-31 23:59:59’
timestamp类型:时间戳,就是表示“当前时刻”,类似函数now()获得的值,用于INSERT或UPDATE操作时自动获得当前时间
year类型: 四位字符串,范围为’1901’到’2155’;四位数字,范围为1901到2155;两位字符串,范围为’00’到’99’;两位整数,范围为1到99
在mysql中除了timestamp 类型允许有默认值外,其他时间类型都不能有默认值,不然会报错。
建表语句
create table shijiantest(
id int auto_increment,
riqi date,
shijian time,
riqishijian datetime ,
shijianchuo timestamp default current_timestamp,
primary key(id)
)engine = innodb default charset = utf8;
插入数据:
insert into shijiantest (id,riqi,shijian,riqishijian) values(1,'2018/1/12',curtime(),now());
insert into shijiantest (id,riqi,shijian,riqishijian) values(2,'2018-01-13','14:38:00',now()),(3,'20180113','143800',now());
mysql常用时间日期函数
获取当前日期和时间: now(); 获取当前日期: curdate(); 获取当前时间:curtime();
将具体时间转换为时间戳:unix_timestamp(); 将时间戳转换为时间:from_unixtime();
3 字符串类型
mysql提供的有CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。
定长字符串char:需要设定长度值,不足设定值,则右侧自动填满空格;最大255个字符
变长字符串varchar:需要设定长度值,最大65532个字节,实际还得考虑一行的其他字段所占的长度,因为一行的最大长度是65534个字节;实际长度以实际内容为准,但不超过设定值
定长二进制字符串binary:类似char,应该设定长度值,只是按“二进制字节”保存存字符数据,最大255个字节,无编码问题
变长二进制字符串varbinary:类似varchar,需要设定长度值,只是按“二进制字节”存字符数据,最大65532个字节,无编码问题
文本列类型text:用于存储普通文本,不受行的最大长度的限制,同类还有:tinytext, mediuntext, longtext
二进制列类型blob:用于存储二进制字节内容,不受行的最大长度的限制,同类的还有:tinyblob, mediumblob, longblob
枚举类型enum: 类似单选项应用中的多个选项值,最大65535个选项值;使用形式:enum(‘value1’, ‘value2’, … );存储数据的时候其实存的是一个对应的数字序号(从1开始)
set类型:类似多选项应用中的多个选项,最多64个选项,使用形式:set(‘value1’, ‘value2’, …); 内部存储的也是数字(依次为1,2,4,8, ….),但可以是多个值,比如5就表示2个值(1,4),14就表示3个值(2,4,8)
CHAR列的长度固定为创建表时声明的长度。长度可以为从0到255的任何值。同CHAR对比,VARCHAR值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则使用两个字节)。CHAR 和 VARCHAR实际所能存储的最大 数据长度跟编码有关,mysql每一行的最大字节数为65535,当使用utf8,一个字符有可能占用三个字节的时候,varchar如果定义允许空的话能定义的最大长度为(65535-1-2)/3=21844.一般写法CHAR(M) 和 VARCHAR(M) ,其中M代表所存储的最大长度,单位是字符。BINARY、VARBINARY和 BLOB可以理解为是CHAR、VARCHAR和TEXT的二进制版本!
create table chartest(
id int auto_increment,
c char(40) not null,
vc varchar(40) not null,
primary key(id)
)engine = myisam default charset = utf8;
insert into chartest(c,vc)values(‘hello world ‘,’hello world ‘),(’ world hello ‘,’ world hello ‘);
mysql> select *,length(c) as clen,length(vc) as vclen,concat(c,’!’),concat(vc,’!
‘) from chartest;
+—-+—————+—————–+——+——-+—————-+——–
———-+
| id | c | vc | clen | vclen | concat(c,’!’) | concat(
vc,’!’) |
+—-+—————+—————–+——+——-+—————-+——–
———-+
| 2 | hello world | hello world | 11 | 13 | hello world! | hello w
orld ! |
| 3 | world hello | world hello | 13 | 15 | world hello! | world
hello ! |
+—-+—————+—————–+——+——-+—————-+——–
———-+
2 rows in set (0.00 sec)
CHAR 和 VARCHAR对字符串末尾的空格处理方式是不同的:CHAR 尾部的空格会被删掉,而VARCHAR则不会!
CHAR 和 VARCHAR 的区别:
SET 和 enum
create table seTest(
id int auto_increment,
hobby set(‘篮球’,’足球’,’羽毛球’,’乒乓球’,’棒球’),
gender enum(‘male’,’female’,’not know’),
primary key(id)
)engine = myisam default charset = utf8;
insert into seTest(hobby,gender) values(‘篮球’,’male’),(‘篮球,足球,棒球’,’not know’);
insert into seTest(hobby,gender) values(‘篮球’,’male,female’);
insert into seTest(hobby,gender) values(‘篮球’,’male female’);
insert into seTest(hobby,gender) values(‘排球’,’male female’);
mysql> show warnings;
+———+——+———————————————+
| Level | Code | Message |
+———+——+———————————————+
| Warning | 1265 | Data truncated for column ‘hobby’ at row 1 |
| Warning | 1265 | Data truncated for column ‘gender’ at row 1 |
+———+——+———————————————+
2 rows in set (0.00 sec)
mysql> select * from setest;
+—-+—————-+———-+
| id | hobby | gender |
+—-+—————-+———-+
| 1 | 篮球 | male |
| 2 | 篮球,足球,棒球 | not know |
| 3 | 篮球 | |
| 4 | 篮球 | |
| 5 | | |
+—-+—————-+———-+
5 rows in set (0.00 sec)
可以看到,当插入的值跟set 、enum 字段值要求不符时,会插入空值。
常用字符串函数
concat(column|str1,column | str2,….)将多个字符串首尾相连后返回。
concat_ws(separator,str1,str2,….)将多个字符串指定连接符separator的首尾相连后返回
substr(str,pos[,len]) 从字符串中的指定位置pos开始取一个字串返回
repeat(str,count) 将字符串str重复count次后返回
reverse(str) 将字符串str反转后返回