赞
踩
约束条件就是在给字段加一些约束,使该字段存储的值更加符合我们的预期。
UNSIGNED :无符号,值从0开始,无负数
ZEROFILL:零填充,当数据的显示长度不够的时候可以使用前补0的效果填充至指定长度,字段会自动添加UNSIGNED
NOT NULL:非空约束,表示该字段的值不能为空
DEFAULT:表示如果插入数据时没有给该字段赋值,那么就使用默认值
PRIMARY KEY:主键约束,表示唯一标识,不能为空,且一个表只能有一个主键。一般都是用来约束id
AUTO_INCREMENT:自增长,只能用于数值列,而且配合索引使用,默认起始值从1开始,每次增长1
UNIQUE KEY:唯一值,表示该字段下的值不能重复,null除外。比如身份证号是一人一号的,一般都会用这个进行约束
FOREIGN KEY:外键约束,目的是为了保证数据的完成性和唯一性,以及实现一对一或一对多关系
数值类型包括整数型、浮点型、定点型
M: 表示默认的显示长度,有符号和无符号的默认显示长度是不一致的,比如: INT 有符号默认显示长度为 4,无符号默认显示长度为3
CREATE TABLE int_db(
a TINYINT,
b SMALLINT,
c MIDDLEINT,
d INT,
e BIGINT
);
表结构如下(desc int_db)
解释: 我们来看看type这一列,可以看到,每个字段类型后面都有一个括号,括号里面的有个数值,这个数值实际上就是字段的显示宽度,也就是M的值,M表示整数类型的最大显示宽度。最大显示宽度为255.显示宽度与类型可包含的值范围无关
我们在创建表的时候并没有指定字段类型的显示宽度,那么,默认的显示宽度则是该字段类型最大的显示宽度
例如字段a的显示宽度为4,是因为TINYINT有符号值的范围是-128到127,
-128的长度为4(负号、1、2、8共四位),所以默认的显示宽度最大为4,其他的以此类推
CREATE TABLE int_db( a TINYINT, b SMALLINT, c MIDDLEINT, d INT, e BIGINT );
可以看到,默认显宽度就变成3了,因为无符号的TINYINT的值范围为0-255,没有负号,所以最多是3位。
使用该约束后当数据的长度比我们指定的显示宽度小的时候会使用前补0的效果填充至指定长度,字段会自动添加UNSIGNED
CREATE TABLE int_db2(
a TINYINT(8) ZEROFILL,
b TINYINT(5) UNSIGNED);
INSERT int_db2() VALUES(12,12);
解释: 可以看到,12变成了00000012,自动在前面补了0,这是因为指定的显示宽度是8,但是12只有两位,所以在前面补0,使长度为8。这就是ZEROFILL的效果
实践举例:
我们指定a字段为FLOAT类型,总长度为3,小数点后两位为2,b字段总长度为5,小数点后两位长度为3
CREATE TABLE float_db(
a FLOAT(3,2),
b DOUBLE(5,3)
) ;
解释: 可以看到,我们给a字段的值是1.111,但是只存进去了1.11; 浮点数存在精度丢失的问题,如果涉及到小数运算,尽量不要用浮点型
DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
CREATE TABLE decimal_db(a DECIMAL);
desc decimal_db;
insert into descimal_db values(30.6783);
create table descimal_db2(a decimal(5,3));
desc descimal_db2;
insert into descimal_db values(30.6783);
解释:可以看到,存进去的数值被四舍五入阶段了,也就是说,DECIMAL也在存储时存在精度丢失的问题。
超出范围和溢出处理
当MySQL将值存储在超出列数据类型允许范围的数值列中时,结果取决于当时生效的SQL模式:
如果启用了严格的SQL模式,则MySQL会根据SQL标准拒绝带有错误的超出范围的值,并且插入失败。
如果未启用限制模式,MySQL会将值截断到列数据类型范围的相应端点,并存储结果值,并产生一个警告;
在我们的配置文件中可以看到SQL模式的配置,关于SQL模式详情请看SQL模式官方文档
CREATE TABLE str_db(
a CHAR(4),
b VARCHAR(4));
INSERT str_db() VALUES("","");
INSERT str_db() VALUES("ab","ab");
INSERT str_db() VALUES("abcd","abcd");
INSERT str_db() VALUES("abcdefg","abcdefg");//在严格模式下,该条数据会插入失败,非严格模式则会对数据进行截取
解释: 我们看到查询的结果是一样的,但实际上他们存储时占用的长度是不一样的。
CHAR类型不管存储的值的长度是多少,都会占用M个字节,而VARCHAR则占用实际长度+1个字节。
建议: 但是CHAR的查询效果要高于VARCHAR,所以说,如果字段的长度能够确定的话,比如手机号,身份证号之类的字段,可以用CHAR类型,像地址,邮箱之类的就用VARCHAR
先了解一下,Mysql中length()、char_length()的区别。
1)、length():mysql里面的length()函数是一个用来获取字符串长度的内置函数。
2)、char_length():在mysql内置函数里面查看字符串长度的还有一个函数是char_length()。
3)、这两个函数的区别是:
a)、length(): 单位是字节,utf8编码下,一个汉字三个字节,一个数字或字母一个字节。gbk编码下,一个汉字两个字节,一个数字或字母一个字节。
b)、char_length():单位为字符,不管汉字还是数字或者是字母都算是一个字符。
提示: varchar 单独需要一个或者两个字节来记录该列真实占用的字节数; 真实数据占用的字节数小于等于127,用一个字节记录真实占用的字节数; 真实数据占用的字节数大于127用2个字节记录真实占用的字节数
TEXT系列的存储范围比VARCHAR要大,当VARCHAR不满足时可以用TEXT系列中的类型。需要注意的是TEXT系列类型的字段不能有默认值,在检索的时候不存在大小写转换,没有CHAR和VARCHAR的效率高
CREATE TABLE enum_db(gender ENUM("男","女"));
INSERT enum_db() VALUES("男");
INSERT enum_db() VALUES(1); 也可以使用编号插入值,等同于"男",序号从1开始
INSERT enum_db() VALUES("女");
INSERT enum_db() VALUES(2);等同于"女"
下面我们插入一条不是枚举集合中的数据试一下
在ENUM中我们只能从允许值列表中给字段插入一个值,而在SET类型中可以给字段插入多个值
我们可以看到TIME的存储范围是’-838:59:59’到 ‘838:59:59’,因为TIME类型不仅可以用于表示一天中的时间 ,还可以用于表示两个事件之间的经过时间或时间间隔
格式: D HH:MM:SS
D:表示天数,当指定该值时,存储时小时(24)会先乘以该值
HH:表示小时
MM:表示分钟
SS:表示秒
CREATE TABLE time_db( a TIME ) INSERT time_db() VALUES('22:14:16'); -- -2表示间隔了2两天 INSERT time_db() VALUES('-2 22:14:16'); -- 有冒号从小时开始 INSERT time_db() VALUES('14:16'); -- 没有冒号且没有天数则数据从秒开始 INSERT time_db() VALUES('30'); -- 有天数也从小时开始 INSERT time_db() VALUES('3 10'); -- 直接使用数字代替也可以 INSERT time_db() VALUES(253621);
CREATE TABLE date_db(
a DATE)
INSERT date_db() VALUES(20180813);
INSERT date_db() VALUES("2018-06-1");
INSERT date_db() VALUES("2018-4-1");
INSERT date_db() VALUES("2018-04-07");
CREATE TABLE datetime_db(
a DATETIME
)
INSERT datetime_db() VALUES(20180102235432);
INSERT datetime_db() VALUES("2015-04-21 21:14:32");
INSERT datetime_db() VALUES("2015-04-23");
datetime timestamp date?
datetime 更像日历上面的时间和你手表的时间的结合,就是指具体某个时间,精确到毫,8个字节,
timestamp 更适合来记录时间,比如我在东八区时间现在是 2016-08-02 10:35:52, 你在日本(东九区此时时间为 2016-08-02 11:35:52),我和你在聊天,数据库记录了时间,取出来之后,对于我来说时间是 2016-08-02 10:35:52,对于日本的你来说就是 2016-08-02 11:35:52, 精确到秒 4个字节存储,1970-2038
date: 可以直接使用函数进行比较, 3个字节
CREATE TABLE timestamp_db(
a TIMESTAMP
)
INSERT timestamp_db() VALUES(20020121);
INSERT timestamp_db() VALUES(20020121142554);
INSERT timestamp_db() VALUES("2015-12-16 21:14:15");
INSERT timestamp_db() VALUES("2015-12-17");
INSERT timestamp_db() VALUES(NULL);
INSERT timestamp_db() VALUES(CURRENT_TIMESTAMP);
INSERT timestamp_db() VALUES();
CREATE TABLE year_db(
a YEAR
)
INSERT year_db() VALUES("1993");
INSERT year_db() VALUES(1993);
create table ip_db(ip int(12) );
insert into ip_db values(INET_ATON('127.127.117.163'));
INET_ATON(‘127.127.117.163’) : 把IP转换为数字存储;
INET_ntoa(2139059619) : 把数字转换为IP;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。