目录
一、表的约束
前面我们所讲到的数据类型就是一种表的约束。为什么这么说呢?因为数据类型有自己的大小,也就是我们插入的数据是有范围的,不能够随意插入,这就对程序员的插入操作作了规范和约束,保证了插入的数据的合法性和完整性以及可预期性。
但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如:身高不能为负数,每个人的电话号码都是唯一的等。
约束本质:通过技术手段,倒逼程序员,插入正确的数据。
二、空属性
cpp
null(默认的)和 not null(不为空)
数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算。并且有的数据是不能为空的。
比如,在学校中,一个学生一定有其所在的班级,且不能为空,因为某个学生一定是属于一个确定的班级的,并且这个班级所在的教室也是确定的且不能为空,不然学生就不知道在哪里上课了。所以如果我们要创建一个学生的信息表的话,这两个字段不能够为空。
我们先创建一个学生信息表:
cpp
mysql> create table stu(
-> name varchar(20),
-> class_name varchar(20) not null,
-> class_room varchar(20) not null
-> );
如下图的表结构:null一栏,yes表示可以为空,no表示不能为空。
然后我们向其中插入一些数据:
而如果我们插入null数据的话,就会出错:
而允许为空的列,它的默认值是null。所以如果插入null,则是合法的:
三、默认值
默认值(default):某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值。
下面我们在学生信息表中插入一列年龄信息,并设置其默认值是18。
下面我们进行包含age数据的插入,和不包含age数据的插入:
我们发现,如果用户指明了年龄,就使用用户指定的年龄,如果用户没有指明年龄,就使用我们设置的默认值。默认值的生效:数据在插入的时候不给该字段赋值,就使用默认值。
如果没有明确指定一列要插入,用的是default值,而如果没有设置default值,就会出错:比如下面,name就没有设置default值。
注:只有设置了default的列,才可以在插入值的时候,对列进行省略。
四、列描述
列描述:comment,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或DBA来进行了解列字段的含义。
具体使用方式如下:
cpp
mysql> create table users(
-> name varchar(20) comment '用户名字',
-> address varchar(32) comment '用户地址',
-> telephone int comment '用户电话'
-> );
五、zerofill
引列:对于下表。
cpp
mysql> create table t12(
-> id int
-> );
我们查看一下它的属性:
我们发现,int类型后面还跟了一个数字10。它肯定不是表示int类型的大小,因为int类型的大小是4字节,那么这个10代表什么意思呢?
其实没有zerofill这个约束的话,括号内的数字是毫无意义的。所以我们需要将他们结合起来理解。
比如,对于下表:
cpp
mysql> create table t12(
-> a int(5),
-> b int(5)
-> );
一般情况下,我们向表中插入数据没有什么特别的地方:
但是对列添加了zerofill约束后,显示的结果就有所不同了。修改t12表中,b的约束条件:
cpp
alter table t12 change b b int(5) zerofill;
然后,我们再查看t12表中的数据:
其实,int身后括号里面的数字就表示数值显示的宽度。这里面显示的宽度是5。加了zerofill约束后,这次可以看到b的值由原来的2变成00002,这就是zerofill约束的作用,如果宽度小于设定的宽度(这里设置的是5),自动填充0。
根据上面的结果,要注意的是,这只是最后显示的结果,在MySQL中实际存储的还是1。可以看出数据库内部存储的还是1,00001只是设置了zerofill属性后的一种格式化输出而已。
六、主键
主键:primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键。主键所在的列通常是整数类型。
创建表的时候直接在字段上指定主键约束(primary key)。我们先创建一个包含主键约束的学生信息表:
cpp
mysql> create table stu(
-> id int primary key,
-> name varchar(20),
-> password int
-> );
然后查看其列属性:列属性中key一列中pri表示该字段是主键。
先插入两条数据:
如果我们再插入一条id为2的记录,就会报错:
报错的提示信息就是id为2的主键冲突了。即主键对应的字段中不能重复,一旦重复,插入操作就会失败。
当表创建好以后,但是没有在创建时就指定主键的时候,可以再次追加主键。
cpp
alter table 表名 add primary key(字段列表);
当你不再需要主键的时候, 可以删除主键:
cpp
alter table 表名 drop primary key;
复合主键:在创建表的时候,在所有字段之后,使用primary key来创建主键,如果设置多个字段作为主键,这就是复合主键。
我们先创建一个包含复合主键约束的学生信息表:id表示学生编号,crouse_id表示课程编号,score表示该学生该课程的分数。
cpp
mysql> create table stu(
-> id int,
-> crouse_id int,
-> score int,
-> primary key(id,crouse_id)
-> );
然后我们向其中插入一些数据:
我们发现,对于复合主键,这里是(id,crouse_id),只要两个中有一个和表中数据不一样,就可以插入成功。如果两个中同时和表中的数据冲突了,那么插入失败。也就是说,(id,crouse_id)同时构成了主键。用上面的例子解释的话,就是一个同学可以选多个课程,多个同学选同一个课程,但是同一个同学不能多次选择同一个课程。
七、自增长
auto_increment:当对应的字段不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值 +1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。
自增长的特点:
~ 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)。
~ 自增长字段必须是整数。
~ 一张表最多只能有一个自增长。
我们先创建一个包含自增长约束的信息表:
cpp
mysql> create table stu(
-> id int primary key auto_increment,
-> name varchar(20)
-> );
然后我们插入一些数据,并进行查询:
我们发现,有了自增长约束,我们不需要手动插入id数据,并且每次插入它还会自加1。这样还保证了主键不会冲突。
如果我手动插入id,会是怎么样呢?
从上面的结果可以看出,如果我们手动插入, 就会是我们用户自己指定的数据进行插入。而下一次插入时,也不指定id的话,id就会从13开始自增。
当然,我们也可以在创建表的时候就指定自增长值:
cpp
mysql> create table stu1(
-> id int primary key auto_increment,
-> name varchar(20)
-> )auto_increment=10;
插入数据:
八、唯一键
一张表中有往往有很多字段需要唯一性,使其数据不能重复。但是一张表中只能有一个主键,所以唯一键就可以解决表中有多个字段需要唯一性约束的问题。
唯一键的本质和主键差不多,唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。
我们创建如下的学生信息表:
cpp
mysql> create table stu(
-> id int primary key auto_increment,
-> telphone int unique key
-> );
如下,key一列中的UNI就表示该字段是唯一键:
然后我们向表中插入一些数据:
我们发现,如果telphone插入相同的值就会报错,报错就是唯一键发生了冲突。
唯一键是可以为空的:
唯一键 VS 主键
主键:主要是用来标识表中一条数据的唯一性。
唯一键:主要是用来标识某一列的字段的数据不能出现重复。
九、外键
外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。
语法:
cpp
foreign key (字段名) references 主表(列)
下面创建一张班级信息表(主表):
cpp
mysql> create table class(
-> id int primary key,
-> name varchar(20) not null
-> );
插入一些数据:
再创建一张学生表(从表):
cpp
create table stu(
id int primary key,
name varchar(20) not null,
class_id int,
foreign key (class_id) references class(id)
);
下图,key列 MUL 就表示该字段是外键。
插入数据:
如果我们在stu表中插入class表中不存在的班级会发生什么呢?插入一个班级号为3的学生,因为class表中没有这个班级,所以插入失败了。
我们发现,报错提示会告诉我们不存在3号外键。
如下图,如果我们想要删除班级号为1的班级信息,就会报错,因为班级号为1的班级里还有学生。