【MySQL】--- 表的约束
【MySQL】--- 表的约束
- 一、空属性
- 二、默认值
- 三、列描述(注释)
- 四、零填充
- 五、主键(唯一&&不能为空)
- 六、复合主键
- 七、自增长
- 八、唯一键
- 九、外键
表的约束实际上就是,对表操作的时候,一种规范,一种制度
一、空属性
空属于用于限制值是否允许为空,默认值为null表示允许为空
,not null表示不允许为空
。虽然默认可以为空,但由于一些字段要参与运算,而空无法被计算,所以要尽可能保证不为空。
示例:
mysql> create table t1(-> id int not null,-> name varchar(20) not null,-> other int );
此时这个表结构:“是否可以为空” 的那一列属性,前两个就是no,意思该属性不能为空!
other 是默认 没有设置 not NULL ,默认就是可以为空!
如果向 前两个属性 进行 NULL插入操作,就会报错!
发生报错,not null
的列值不可以为空。
二、默认值
在插入数据时,如果某些列没有指定数据
,那么就会启用默认值(缺省值)
。默认值通过default
来指定。
示例:
mysql> create table t2 (-> name varchar(20) not NULL,-> age int unsigned default 18,-> gender varchar(5) default '男');
如果再次向表里面只插入 name ,其他的 看看能不能 用默认值!
此时age
和gender
就自动设置为了默认值。
值得注意的是,name列设置了not null属性,但是其default为NULL。如果你不插入name列,此时启用默认值NULL,但是由于该列有not null属性,最后就会报错。
三、列描述(注释)
列描述
相当于代码中的注释
,用于描述一个列的作用。
列描述通过comment
关键字来指定。
示例:
create table t3(
name varchar(20) not null comment '用户名',
age tinyint unsigned default 18 comment '年龄',
gender char(1) default '男' comment '性别'
);
其中\G用于更加美观地输出数据。可以看到每一列后面都可以看到对应的列描述,后续的程序员就知道每一列要插入什么样的数据了。
四、零填充
零填充用于控制数据显示的格式,当数据位数不足时,自动在前面补0。零填充通过zerofill关键字来指定。
create table t4(
a int,
b int(5),
c int(5) zerofill
);
通过desc
查看表的属性:
- 在Type列中,
int后面()内的数字
,用于指定数据的显示宽度
,在没有zerofill属性时,该数字无意义。 注意该值不影响
任何数据的真实存储范围,存储范围由unsigned以及int,tinyint等类型本身的属性来决定。显示宽度要配合zerofill使用才有意义
c的类型是int(5)
,但是最后却多出了unsigned。在指定zerofill属性时
,会自动给整型添加unsigned属性。如果数字显示时位数不足5位,就会自动填充到5位。
- 第一次插入了1, 2, 3,前两个列没有zerofill,只显示单个数字,由于c有zerofill,最后输出了00003。
- 第二次插入了1234567,
超出了5位
,但是显示时没有截断
。说明()内的数字,不会影响数据的显示
。
五、主键(唯一&&不能为空)
主键用于约束每一行数据之间的唯一性,被指定为主键的列不允许重复
,不能为空
,且一张表只能有一个主键。
建表时,通过primary key
来指定主键。
create table t5(
id int unsigned primary key,
name varchar(20)
);
通过desc查看表的属性:
id被指定为了主键,其Key的值位PRI表示这是主键,被设置主键的同时,自动增加了not null属性
。
主键不允许重复:示例:
上图中,第一次id = 1,第二次插入另外一条数据时id = 1,此时发生报错,因为主键不允许重复。
- 当创建好表后如果没有主键,可以
追加主键
:
alter table 表名 add primary key(列名);
- 删除主键:
alter table 表名 drop primary key;
示例:
上图中,先删除了t5的主键
,随后(1, ‘张三’)就可以正常插入了,可以证明主键约束确实不存在
了。
当想要再添加回主键属性
时,由于id列有两个相同的值
,此时id不允许作为主键
了。此时只有修改某个id的值
使之不重复,才能重新设置主键了。
六、复合主键
建表时,可以让多个列共同成为一个主键
,这种主键叫做复合主键
。
通过primary key (列1, 列2 …)来指定复合主键。
create table t6(
id_1 int unsigned,
id_2 int unsigned,
name varchar(20),
primary key (id_1, id_2)
);
通过desc
查看表的属性:
复合主键整体 冲突 才算冲突!
七、自增长
被设置为自增长的列,如果插入数据时没有指定值,那么会根据当前列中的最大值+1
进行插入。
自增长要求:
- 任何一个字段想要自增长,前提是该列本身是一个
索引
(Key栏有值) - 自增长字段必须是整数
- 一张表最多只有一个自增长
通过auto_increment
来设置自增长。
示例:
如果你尚不了解索引,那么可以直接对主键设置auto_increment,主键列自带索引
。
create table t7(
id int unsigned primary key auto_increment,
name varchar(20) not null
);
通过desc查看表的属性:
其中id列被设为了主键,Key的值为PRI
,该列有值说明是索引,因此可以添加auto_increment属性
,在Extra中可以看到id具有该属性。
插入6个张三后,发现明明没有指定id,但是id列还是有值,而且自己从1开始增长了。
再尝试插入其他值:
展示 会根据当前列中的最大值+1
进行插入
其实自增长是依靠一个变量auto_increment来计算的,该 变量可以在建表时直接指定:
这次自增长就从50开始了。
八、唯一键
表中往往有很多字段都需要唯一性
,主键只有一个,不可能所有字段都通过主键来保证唯一性,此时就需要唯一键
主键与唯一键的区别:唯一键可以为空!!!
唯一键通过unique key或unique关键字指定,后面的key省略。
create table t9(
id int unsigned unique,
name varchar(10)
);
通过desc
查看表的属性:
id列的Key属性为UNI,即唯一键。
尝试插入数据:
唯一键 冲突:
但是插入多条数据id为空是合法的,因为唯一键不对空进行重复性比较。
九、外键
在数据库中,往往不只有一张表,而多张表之间往往是有从属关系的。
比如说一个学生属于一个班级,假设有一个学生表,一个班级表。如果只有1,2,3,4四个班级,那么某一个学生就不可能属于五班。这就是班级对学生的约束,从数据库的角度来看就是:学生表的班级字段,必须在班级表中存在。想要实现这个功能,就需要外键。
左侧是学生表,右侧是班级表。学生表中class被指定为外键,受到班级表中id的限制,班级表中id列叫做参照键。
因为学生从属于班级
,所以班级表是主表
,学生表是从表
。外键在从表中,参照键在主表中。外键受到参照键影响:
- 外键的值必须在参照键中存
- 外键的值允许为空
建表时,设置外键的语法为:
foreign key(外键) references 主表(参照键)
另外的,参照键必须具有唯一性,一般为主键或者唯一键。
示例:
主表 - 班级表:
create table class(
id int primary key,
name varchar(32) not null
);
从表 - 学生表:
create table student(
id int unsigned primary key,
name varchar(32) not null,
tel varchar(32) not null,
class_id int,
foreign key(class_id) references class(id)
);
建立学生表时,foreign key(class_id) references class(id)就建立了外键,对应的参照键为class表的id。
通过desc查看表的属性:
外键class_id的Key属性为MUL,表示外键。
class的内容如下:
尝试对学生表插入数据:
另外的,外键其实也会反过来约束参照键!