目录
[1. 空属性(NULL)](#1. 空属性(NULL))
[2. 默认值(default)](#2. 默认值(default))
[3. 列描述(comment)](#3. 列描述(comment))
[4. zerofill](#4. zerofill)
[5. 主键(primary_key)](#5. 主键(primary_key))
[6. 自增长(auto_increment)](#6. 自增长(auto_increment))
[7. 唯一键(uniqie)](#7. 唯一键(uniqie))
[8. 外键(foreign key (字段名) references 主表(列)](#8. 外键(foreign key (字段名) references 主表(列))
表的约束:表中有各种类型,每个类型插入的数据都要是合法的,不然插入失败,所以表的约束就是让使用者正确的插入数据,约束本质是通过技术手段,倒逼使用者插入正确的数据来保证未来数据库表中的数据一定符合数据约束的,如果采用文件存储数据,想插入什么类型就插入什么类型,无约束可言。
约束的最终目标 :保证数据的完整性和可预期性。
1. 空属性(NULL)
- 两个值: null (默认的)和 not null( 不为空 )
- 数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空办
法参与运算。
在C语言中 NULL表示 0 / '\0' ,在MySQL中NULL就表示什么都没有。
示例:创建一个表 2个字段,一个姓名不能为空,一个兴趣爱好可以为空。
sql
create table if not exists test9(
name varchar(20) not null,
hobby varchar(30)
);
如果不指定是否为空,则大部分类型默认是允许为空,显然 name指定后 列属性 NULL 是 NO 不允许为空。
第一条数据插入,name和hobby都不为NULL。
第二条数据插入,name不为空,hobby(创建该字段时没有给默认的缺省值,MySQL会优化自动加上默认的缺省值)用的是defalut缺省值NULL。
橙色区域插入失败:只指定插入hoppy,而name(创建的时候指定不能为空,MySQL不会进行优化,也就是默认添加默认的缺省值)没有默认的缺省值,所以插入失败。
绿色区域插入失败:指定name数据为NULL,显然前面创建的时候指明不能为NULL,所以插入失败。
2. 默认值(default)
- 默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值。
示例:创建一个表 2个字段,一个姓名不能为空,一个测试1设置缺省值,一个测试2不能为空,有缺省值。
sql
create table test10(
name varchar(20) not null,
test1 char(10) default '这是默认值test1',
test2 char(10) not null default '这是默认值test2'
);
第一次插入:只插入name列,忽略test1和test2,test1有默认值插入,test2不能为NULL,但test2有默认值也能插入,所以在忽略别的 列的情况下 和为不为空没关系,只跟是否有默认的缺省值有关系。
第二次插入:只插入name列和test2列,忽略test1,test1有默认值插入。
第三次插入:全列插入,test2不允许为空,所以插入失败,说明在不忽略插入的情况下只与为不为空有关系,与默认的缺省值没关系。
第四次插入:忽略name列:name列创建的时候指定不能为空,后面没有默认的缺省值,所以插入失败。
是否为空和默认的缺省值是相辅相成的:如果忽略的情况下看是否有默认的缺省值,如果指定插入的情况下看是否可以为空。
3. 列描述(comment)
列描述: comment ,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或 DBA来进行了解。
比如管理数据库的人员不知道某个字段是什么意思,就可以查看当时创建添加的描述信息。
查看comment描述字段
sql
show create table table_name
4. zerofill
创建表
sql
create table t17(
a int unsigned not null,
b int unsigned not null
);
我们发现表结构的类型创建的时候就一个int,而实际后面多了个(10),这是mysqld进行处理后的结果,那是什么意思呢?下面在列属性后面添加zerofill属性,并修改括号里的值为4。
插入数据:
当插入的数据位数小于该类型括号里的值时,少的位数自动往左补零,如果超过了则什么也不干,实际存储的是实际输入的数据,并不会影响后续的操作。
那么mysqld默认给的10是什么含义呢?10个位数也就是10几亿,无符号int取值范围 0~42亿多,刚好10位,而有符号的取值范围 -42亿多~42亿多,所以无符号的默认应该给11位,多的以为用来存高位符号位。
如果没加zerofill,则括号里的值是没有意义的,加了zerofill只是显示的时候会格式化,不会影响实际存储的值。
5. 主键(primary_key)
1. primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个。
2. 主键所在的列通常是整数类型。
创建表:
sql
// 第一种创建方式
create table test12(
id int unsigned primary key,
age char(1)
);
//第二种创建方式
create table test12(
id int unsigned,
age char(1),
primary key(id)
);
添加了主键的字段默认不能为空,也不会添加默认的缺省值。
插入数据:
第三条插入: 主键对应的字段中不能重复,一旦重复,操作失败。
删除主键/添加主键:
sql
// 添加主键
alter table table_name add primary key(字段1,字段2.....);
// 去掉主键
alter table table_name drop primary key;
复合主键:可以把一个字段当成一个主键,也可以把多个字段当成一个主键(整体)。
插入数据:
前3次插入虽然有部分重复值,但和之前插入的值没有全部重复所以能插入,后2次插入和之前插入的某个值全重复了,所以插入失败。
6. 自增长(auto_increment)
auto_increment :当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。
1. 自增长的特点: 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
2. 自增长字段必须是整数
3. 一张表最多只能有一个自增长
创建表:
sql
create table test13(
-> id int primary key auto_increment,// 必须和主键搭配使用,且类型为整数
-> name varchar(10) not null // 一张表只能有一个自增长,主键也只有一个
-> )auto_increment=1; // 所以一般主键和自增长搭配使用
// 可指定增长起始值
插入数据:
不指定插入带自增长的列字段,系统会从当前字段中已经有的最大值+1操作。
如果指定插入带自增长的字段,系统就会自动更新指定插入的值。
在插入后获取上次插入的 AUTO_INCREMENT 的值(批量插入获取的是第一个值)
sql
select last_insert_id();
7. 唯一键(uniqie)
一张表中可能有多个字段需要具有唯一性,但主键只能有一个,而唯一键也是也可以让字段具有唯一性,且可以有多个唯一键。
唯一键和主键的区别:唯一键可以为NULL,主键不能为NULL,NULL不参与计算。
比如人的身份信息:身份证,电话号码,QQ号,标识人的唯一性当然是身份证(主键),电话号码和QQ号对于人也是唯一的,也需要标识(外键)。
创建表:
sql
create table test14(
id int primary key(,
qq varchar(15) unique
// 可以在这里指定 primary key(字段1,字段2...)/unique(字段1,字段2...)
);
主键是不允许为NULL的,唯一键默认是为NULL的。
插入数据:
第一次插入正确。
第二次插入唯一键冲突,插入失败。
第三次插入唯一键可以为NULL,插入正确。
第四次插入NULL值不参与计算,插入正确。
也可以把唯一键设置成not null,就跟主键一样了,但唯一键可以有多个,虽然主键和唯一键都可以保证数据的唯一性,但他们的侧重点不一样。
8. 外键(foreign key (字段名) references 主表(列)
外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。
学生表为从表,班级表为主表,学生表的class_id字段跟班级表的id字段建立关系,class_id就称为外键约束,如果不建立外键约束,相当于2个表物理上没有关系,但逻辑上未来插入的学生表的class_id必须在班级表的id里,如果没有外键约束,也就是没有关联起来,在逻辑上是不允许的,但物理上能插入进去,如果添加了外键约束,2张表建立了关系,学生表插入班级表没有的id值就会受外键约束,从而插入失败,反之将来学生表的id数据都是在班级表id当中的。
创建学生表:
sql
create table if not exists student(
id int unsigned primary key auto_increment,
name varchar(10) not null unique,
telphone bigint not null unique,
class_id int,
foreign key(class_id) references class(id)
);
创建班级表:
sql
create table class(
id int primary key,
courses varchar(10)
);
给班级表插入数据:
给学生表插入数据:
第一次插入和第二次插入中的class_id都在主表班级表中的id列存在,插入成功。
第三次插入3就不在class_id主表班级表中的id列中,插入失败。
也可以插入NULL。
如果想删除主表(班级表)中的列数据,则主表(班级表)的id对应的从表(学生表)中class_id不存在要删除的主表(班级表)的id。