所谓的数据类型:对数据进行统一的分类,从系统的角度出发是为了能够使用统一的方式进行管理;更好的利用有限的空间。
SQL 中将数据类型分为了三大类:数值类型,字符串类型和时间类型
数值型数据:都是数值
系统将数值型分为整数型和小数型
整数型
存放整型数据: 在SQL中因为更多的要考虑如何节省磁盘空间,所以系统又将整型细分为了5类:
Tinyint :迷你整型发,使用一个字节存储,表示的状态最多为256种(常用)
Smallint:小整型,使用2个字节存储,表示的状态最多为65536种
Mediumint:中整型 使用3个字符存储
Int:标准整型,使用4个自己存储(常用)
Bigint:大整型,使用8个字节存储
-- 创建整型表
Create table my_int(
Int_1 tinyint,
Int_2 smallint,
Int_3 int,
Int_4 bigint
)charset utf8;
-- 插入数据
Insert into my_int values (100,100,100,100); -- 插入有效数据
Insert into my_int values (‘a’,’b’,’199’,’f’); -- 无效数据:类型限定
SQL中数值类型全部都是默认有符号,分正负
有时候需要使用无符号类型,需要给数据限定 int unsigned –无符号:从0开始
-- 给表增加一个无符号类型
Alter table my_int add int_5 tinyint unsigned; -- 无符号类型
-- 插入数据
Insert into my_int values (127,1000,1000,10000,255);
查看表结构的时候,发现每个字段的数据类型之后都会自带一个括号,里面有指定的数字
显示宽度:没有特别含义:只是默认的告诉用户可以显示的形式而已,实际上用户是可以控制的,这种控制不会改变数据本身的大小。
Alter table my_int add int_6 tinyint(1) unsigned; -- 指定显示宽度为1
显示宽度的意义:在于数据不够显示宽度的时候,会自动让数据变成对应的显示宽度:通常需要搭配一个前导0来增加宽度,不改变值大小:zerofill(零填充)
Alter table my_int add int_7 tinyint(2) zerofill; -- 显示宽度为2,0填充
零填充会导致数值自动变成无符号
零填充-显示宽度
Insert into my_int values (1,1,1,1,1,1,1);
Insert into my_int values (100,100,100,100,100,100,100);
小数型
小整型:带有小数点或者超出整型的数值类型。
SQL中:将小数型细分为两种:浮点型和定点型
浮点型:小数点浮动,精度有限,而且会丢失精度
定点型:小数点固定,精度固定,不会丢失精度
浮点型数据是一种精度型数据:因为超出指定范围之后,会丢失精度(自动四舍五入)
浮点型:理论分为两种精度
Float:单精度,占用4个字节存储数据,精度范围大概为7位左右
Double:双精度,占用8个字节存储数据,精度方位大概为15位左右
创建浮点数表:浮点的使用方式,直接float表示没有小数部分,float(MD):M代表总长度D代表小数部分长度,整数部分长度为M-D
浮点表
Create table my_float(
F1 float,
F2 float(10,2), -- 10 位在精度范围之外
F3 float(6,2) -- 6 位在精度范围之内
)charset utf8;
-- 插入数据
Insert into my_float values (1000.10,1000.10,100.10); -- 符合条件
Insert into my_float values (1234567890,12345678.90,1234.56); -- 符合条件
Insert into my_float values (3e38,01e7,1234.56);
Insert into my_float values (999999,999999.99,999.99) -- 最大值
浮点型数据的插入:整型部分是不能超出长度的,但是小数部分可以超出长度(系统会自动四舍五入)
Insert into my_float values (123456,1234.123456789,123.987654321); -- 小数部分
Insert into my_float values (123456,1234.12,12345.56); -- 整数部分超出
数据结果:浮点数一定会进行四舍五入(超出精度范围):浮点数如果是因为系统进位导致整数部分超出指定的长度,那么系统也是允许的。
定点型
定点型:绝对的保证整数部分不会被四舍五入(不会丢失精度),小数部分有可能(理论小数部分不会丢失精度)
创建定点数表:以浮点数作为对比
-- 创建定点数
Create table my_decimal(
F1 float(10,2);
D1 decimal (10,2)
)charset utf8;
插入数据:定点数的整数部分一定不能超出长度(进位不可以),小数部分的长度可以随意操作(系统自动四舍五入)
-- 插入数据
Insert into my_decimal values (12345678.90,12345678.90); -- 有效数据
Insert into my_decimal values(1234.123456,1234.1234356); -- 小数部分超出
浮点数如果进位导致长度溢出没有问题,但是定点数不行
Insert into my_decimal values (99999999.99,9999999.99); – 没有问题
Insert into my_decimal values (99999999.99,9999999.999); – 进位超出范围
Datetime 时间日期 格式是 YYYY-mm-dd HH:ii:ss表示的范围从1000到9999年都有0值
0000-00-00 00:00:00
Data :日期就是datatime中的data部分
Time:时间(段):指定的某个区间之间, 时间到时间
Timestamp :时间戳,并不是时间戳,只是从1970年开始的YYYY-mm-dd HH:ii:ss格式与datatime完全一致
Year:年份 两种形式year(2)和year(4)
-- 创建时间日期表
Create table my_data(
D1 datetime,
D2 date,
D3 time,
D4 timestamp,
D5 year
)charset utf8;
插入数据:时间time可以是负数,而且可以是很大的负数。Year可以使用2位数插入,也可以使用4位数
-- 插入数据
Insert into my_data values (‘2015-9-28 11:50:36’,’2015-9-28’,’11:50:36’,‘2015-9-28 11:50:36’,2015);
-- 时间使用负数
Insert into my_data values (‘2015-9-28 11:50:36’,’2015-9-28’,’-11:50:36’,‘2015-9-28 11:50:36’,2015);
Insert into my_data values (‘2015-9-28 11:50:36’,’2015-9-28’,’-211:50:36’,‘2015-9-28 11:50:36’,2015);
Insert into my_data values (‘2015-9-28 11:50:36’,’2015-9-28’,’-2 11:50:36’,‘2015-9-28 11:50:36’,2015); -- 2过去两天;48
-- year 可以使用2 位数或者4位数
Insert into my_data values (‘2015-9-28 11:50:36’,’2015-9-28’,’11:50:36’,‘2015-9-28 11:50:36’,69);
Insert into my_data values (‘2015-9-28 11:50:36’,’2015-9-28’,’11:50:36’,‘2015-9-28 11:50:36’,70);
Timestamp 字段: 只要当前所在的记录被更新,该字段一定会自动更新成当前时间。
-- timestamp : 修改记录
Update my_data set d1 = ‘2015-09-11 11:11:11’ where year = 2069;
在SQL中,将字符串类型分成了6类:char varchar text blob enum 和 set
Char类型 定长字符串
在磁盘(二维表)在定义结构的时候就已经确定了数据的存储长度
Char(L):L代表length 可以存储的长度,单位为字符,最大的长度可以为255;
Char(4):在utf8下需要4*3=12个字节
变长字符串:varchar 在分配空间的时候,按照最大的空间分配:但是实际上最终用了最终根据具体放入数据来确定
Varchar(L)L代表字符长度,理论长度是65536个字符,但是会多出,1到2个字节来确定存储的实际长度,但实际上如果实际长度超过255,既不用定长也不用变长,使用文本字符串text
Varchar(10)的确存了10个汉字,utf8环境10*3+1=31
存储了3个汉字 3*3+1=10字节
定长与变长的存储实际空间(utf8)
实际存储数据 Char(4) Varchar(4) Char占用字节 Varchar(占用)
ABCD ABCD ABCD 4*3=12 4*3+1=13
A A A 4*3=12 1*3+1=4
ABCDE × × 数据超过长度 数据超过长度
如何选择定长或者变长字符串呢?
定长的磁盘空间比较浪费,但是效率高;如果数据基本上确定长度都一样,就使用定长
如:身份证,手机号等
变长的磁盘空间比较节省,但是效率低;如果数据不能确定长度(不同数据有变化)如姓名,地址等
如果数据量非常大,通常说超过255个字符就会使用文本字符串
文本字符串根据存储的数据的格式进行:text和blob
Text:存储文字(二进制数据实际实际上都是存储路径)
Blob:存储二进制数据(通常不用)
枚举:enum 事先将所有可能出现的结果都设计好,实际上存储的数据必须是规定好的数据中的一个
枚举的使用方式
定义:enum(可能出现的元素列表);如enum(‘男’‘女’‘保密’)
使用:存储数据,只能存储上面定义好的数据
-- 创建枚举表
Create table my_enum(
Gender enum(‘男’,’女’,’保密’)
)charset utf8;
加入数据:作用之一:规范数据格式:数据只能是规定的数据中的一个
-- 插入数据
Insert into my_enum values (‘男’),(‘保密’);
– 错误数据
Insert into my_enum values(‘female’);
作用之二:节省存储空间(枚举有一个别名)枚举实际存储的是数值不是字符串本身。
在mysql中系统也是自动转换数据格式的,证明字段存储的数据是数值:
将护具取出来+0就可以判断出原来的数据存的到底是字符串还是数值:如果是字符串最终结果永远为0否则就是其他值
-- 将字段结果取出来进行+0运算
Select gender + 0 , gender from my_enum;
枚举原理:枚举在进行数据规范的时候(定义的时候)系统会自动建立一个数字与枚举元素的对应关系(关系放到日志中):然后在进行数据插入的时候,系统自动将字符串换成对应的数字存储,然后在进行数据提取的时候,系统自动减数值换成对应的字符串显示
因为枚举实际存储的是数值,所以可以直接插入数值
-- 数值插入
Insert into my_enum values (1),(2);
集合字符串
集合跟枚举很类似,实际存储的是数值,而不是字符串
集合使用方式:
定义:set(元素列表)
使用:可以使用元素列表中的元素(多个),使用逗号分隔
-- 创建集合表
Create table my_set(
Hobby set (‘篮球’,’足球,’乒乓球’,’羽毛球’,’排球’,’台球’,’网球’,’棒球’)
-- 足球 台球 网球
-- 集合中:每一个元素都是对应的一个二进制位,被选中位1,没有则为0,最后反过来
-- 0 1 0 0 0 1 1 0
-- 反过来 01100010=98
)charset utf8;
-- 插入数据
Insert into my_set values (‘足球,台球,网球’);
Insert into my_set values(3); -- 3=1+2=篮球+足球
查看数据:数值+数据查看
-- 查看集合数据
Select hobby + 0 , hobby from my_set;
集合中每一个元素对应的就是一个二进制位
集合中元素的顺序都没有关系,因为系统会自动匹配顺序