数据类型
宽度
单位为字节,如果不指定宽度,数据库在存储的时候都必须给每个字段预留最大的存储空间,这样极大的浪费了空间,也加大了数据库本身管理的难度。
字段类型长度应设置为保证正常使用需求下的最大宽度.
数字类型
数据类型要指定的宽度不是必须的,数字类型的宽度并不是表示存储的宽度,而是表示显示的宽度,
数字中的类型

###常用的几种数字类型 整数型: int 4个字节 默认int(11)显示10位+一个正负符号,
bigint 8个字节 整型其实没有必要指定宽度,也就是()里的内容, 括号里的内容并不是表示存储的宽度,而是表示显示的宽度, 如果你指定int(3)表示 当你输入12 它会显示012(前提你要用fillzero定义),当你输入234455它会显示234455.指定正负号就是默认有正负号的. 浮点型: 1 float (m,n) . 整数加上小数一共有m位,其中小数点后有n位 ,单精度浮点数(非准确小数值),m是数字最多总个数,d是小数点后个数。m最大值为255,n最大值为30.例如float(5,2) 99.77 2 double(m,n)精度比float高, 整数加上小数一共有m位,其中小数点后有n位 ,双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。m最大值为255,n最大值为30.例如 double(5,2) 999.77 ; 3 decimal[(m[,d])] [unsigned] [zerofill]:精度最高但是表示的位数比以上两种少,在表示钱方面使用该类型,因为不会出现精度缺失问题,主要用这个函数.定义: 准确的小数值,m是数字总个数 (负号不算),d是小数点后个数。 m最大值为65,d最大值为30。 精确度: **** 随着小数的增多,精度始终准确 **** 对于精确数值计算时需要用此类型 decaimal能够存储精确值的原因在于其内部按照字符串存储。
字符串类型
字符串的宽度就是存储宽度
char: 固定长度字符串类型,CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充。 字符长度范围:0-255(一个中文是一个字符,是utf8编码的3个字节) 优点: 存储效率高 缺点: 浪费空间 varchar:可变长度字符串类型,但存储效率没有CHAR高。如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。 字符长度范围:0-65535(如果大于21845会提示用其他类型 ) VARCHAR类型的实际长度是它的值的实际长度+1。为什么“+1”呢? 这一个字节用于保存实际使用了多大的长度。mysql行最大限制为65535字节,字符编码为utf-8,与 CHAR 类型不同的是,其存储时需要在 前缀长度列表加上实际存储的字符, 该字符占用 1 ~ 2 字节的空间。当存储的字符串长度小 于 255 字节时,其需要 1 字节的空间,当大于 255 字节时,需要 2 字节的空间。所以,对 于单字节的 latin1 来说, CHAR(10)和 VARCHAR(10)最大占用的存储空间是不同的, CHAR(10)占用 10 个字节这是毫无疑问的,而 VARCHAR(10)的最大占用空间数是 11 字节,因为其需要 1 字节来存放字符长度。 优点:节省空间 缺点: 存储效率低,需计算大小 从空间上考虑,用varchar合适; 从效率上考虑,用char合适,关键是根据实际情况找到权衡点。 存储: varchar类型存储数据的真实内容,不会用空格填充,如果'ab ',尾部的空格也会被存起来 强调:varchar类型会在真实数据前加1-2Bytes的前缀,该前缀用来表示真实数据的bytes字节数(1-2Bytes最大表示65535个数字,正好符合mysql对row的最大字节限制,即已经足够使用) 如果真实的数据<255bytes则需要1Bytes的前缀(1Bytes=8bit 2**8最大表示的数字为255) 如果真实的数据>255bytes则需要2Bytes的前缀(2Bytes=16bit 2**16最大表示的数字为65535) 检索: 尾部有空格会保存下来,在检索或者说查询时,也会正常显示包含空格在内的内容 #注意注意注意: CHAR 和 VARCHAR 是最常使用的两种字符串类型。 一般来说 CHAR(N)用来保存固定长度的字符串,对于 CHAR 类型,N 的范围 为 0 ~ 255 VARCHAR(N)用来保存变长字符类型,对于 VARCHAR 类型,N 的范围为 0 ~ 65 535 CHAR(N)和 VARCHAR(N) 中的 N 都代表字符长度,而非字节长度。 ps:对于 MySQL 4.1 之前的版本,如 MySQL 3.23 和 MySQL 4.0,CHAR(N)和 VARCHAR (N)中的 N 代表字节长度。
重点:
#InnoDB存储引擎:建议使用VARCHAR类型 单从数据类型的实现机制去考虑,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。 但对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。
因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。
enum:枚举类型
规定一个范围,可以有多个值,但是为该字段传值时只能传一个值,.比如规定num('男','女'),你传值只能从男女中拿一个值来传.
CREATE TABLE people (
name VARCHAR(40),
sex ENUM('男', '女') not Null #如果不传值则默认范围内的第一个'男'
);
INSERT INTO shirts (name, sex) VALUES ('小红','男'),
set:集合类型
规定一个范围,可以有多个值,但是为该字段传值时可以传多个值
CREATE TABLE people ( name VARCHAR(40), sex ENUM('男', '女'), hobby set('reading','study','music') ); INSERT INTO shirts (name, sex ,hobby) VALUES ('小红','男','reading ,study'),
#可以给hobby字段传多个值,但是范围是reading,study mysic 如果存的不在这个范围之内,不会报错会显示空值
text:字符串类型;
blob:字节类型;储存二进制
日期时间类型
后边不用加宽度
year: 标准格式YYYY
date:日期字符串类型,标准格式为:'YYYY-MM-DD"; time:时间字符串类型,格式为:'HH:MM:SS' datetime:字符串'yyyy-MM-dd hh:mm:ss' 从1000年开始 timestamp:时间戳类型和datetime 差不多,又有不同支持的时间范围不同它从1970年开始
插入的时候直接用字符串的类型插入就可以了
疑问我们可以用字符串类型代替日期那为什么还要用日期时间类型呢?
这是因为日期时间类型这种格式占用空间少,最多8个字节
mysql对日期处理提供了两个重要的函数:
1.str_to_date('字符串','日期格式') :该函数作用是将日期字符串转换成日期类型数据(即varchar---->date)
常用的日期格式有:
%Y 年4位
%m 月(0-12)
%d 日 (0-31)
%H 时(0-24)
%i 分
%S 秒
mysql默认的日期类型为date,日期格式为:%y-%M-%d, 字符串'2012-3-21' 符合要求,mysql自动将字符串转换成了date类型
#查询1992-5-23出生的员工
select * from emp where birthdate='1992-5-23'; #第一种方法
select * from emp where birthdate = str_to_date('5-23-1992','%M-%d-%y') #第二种方法使用str_to_date 函数
#添加一个员工
insert into emp(name,birthdate) values('xiaoming','2012-3-3') #第一种方法
insert into emp(name,birthdate) values ('xiaoming', str_to_date('3-3-2012','%M-%d-%Y) #第二种方法
2.date_format('日期类型数据','日期格式'') :将日期类型date转换成具有特定格式的日期字符串显示出来(date--->varchar), 主要用在查询语句中,客户需要日期以特定的格式展示的时候.
SELECT DATE_FORMAT(NOW(),'%Y-%m-%d') as 日期
结果:

应用博客园中的日期归档:

准备数据
2 准备表和记录 CREATE TABLE blog ( id INT PRIMARY KEY auto_increment, NAME CHAR (32), sub_time datetime ); ##插入数据 INSERT INTO blog (NAME, sub_time) VALUES ('第1篇','2015-03-01 11:31:21'), ('第2篇','2015-03-11 16:31:21'), ('第3篇','2016-07-01 10:21:31'), ('第4篇','2016-07-22 09:23:21'), ('第5篇','2016-07-23 10:11:11'), ('第6篇','2016-07-25 11:21:31'), ('第7篇','2017-03-01 15:33:21'), ('第8篇','2017-03-01 17:32:21'), ('第9篇','2017-03-01 18:31:21');
查询的结果为:

我们要把它变成像博客园日期归档的一样
select DATE_FORMAT(sub_time,'%Y-%m')as 日期 ,count(1) as 文章数 from blog GROUP BY DATE_FORMAT(sub_time,'%Y-%m%');
结果:

timestamp
`create_time` timestamp not null default current_timestamp comment '创建时间', 2 3 `update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
timestamp有两个属性,分别是CURRENT_TIMESTAMP 和ON UPDATE CURRENT_TIMESTAMP两种,使用情况分别如下:
1.CURRENT_TIMESTAMP
当要向数据库执行insert操作时,如果有个timestamp字段属性设为
CURRENT_TIMESTAMP,则无论这个字段有没有set值都插入当前系统时间
2.
ON UPDATE CURRENT_TIMESTAMP
当执行update操作是,并且字段有ON UPDATE CURRENT_TIMESTAMP属性。则字段无论值有没有变化,它的值也会跟着更新为当前UPDATE操作时的时间。
1. 占用4个字节 2. 允许为空值,但是不可以自定义值,所以为空值时没有任何意义。 3. TIMESTAMP值不能早于1970或晚于2037。这说明一个日期,例如'1968-01-01',虽然对于DATETIME或DATE值是有效的,但对于TIMESTAMP值却无效,如果分配给这样一个对象将被转换为0。 4.值以UTC格式保存( it stores the number of milliseconds) 5.时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区。 6. 默认值为CURRENT_TIMESTAMP(),其实也就是当前的系统时间。 7. 数据库会自动修改其值,所以在插入记录时不需要指定timestamp字段的名称和timestamp字段的值,你只需要在设计表的时候添加一个timestamp字段即可,插入后该字段的值会自动变为当前系统时间。 8. 默认情况下以后任何时间修改表中的记录时,对应记录的timestamp值会自动被更新为当前的系统时间。 9. 如果需要可以设置timestamp不自动更新。通过设置DEFAULT CURRENT_TIMESTAMP 可以实现。
浙公网安备 33010602011771号