真正约束字段的其实是数据类型,但是数据类型约束很单一。我们需要一些额外的约束,才能保证数据的合法性,从而在业务逻辑角度保证数据的正确性。
例如,在保证一账号只能绑定一个手机号,我们可能需要数据表中的手机号字段的值唯一。
又或者是保证记录某个字段不能为空。
常见的表约束如下表:
约束条件 | 说明 |
---|---|
PRIMARY KEY | 主键约束 |
FOREIGN KEY | 外键约束 |
AUTO_INCREMENT | 自增约束 |
NOT NULL | 非空约束 |
UNIQUE | 唯一约束 |
DEFAULT | 默认值约束 |
CHECK | 检查约束 |
约束介绍
主键约束
在表中,通常我们都需要添加一个主键。主键又可以由多个字段或单个字段组成。
那么这个主键对于表会有什么约束呢?
主键可以唯一标识表中的记录,那就说明主键不能为空,且唯一。
那么主键又为我们带来什么好处呢?
主键其实又叫主键索引,这就说明它能够加快表的查询速度。
外键约束
要明白外键约束,我们先明白什么是外键?
如果表A中的一个或多个字段是表B的主键,即表A的的一个或多个字段能够唯一标识表B的记录,那么我们称表A的一个或多个字段为表B的外键。其中表A为主表,表B为从表。
知道了什么叫主键,我们就来看看什么叫做外键约束,即外键对表有什么约束?
通过外键约束,数据库可以保证无法插入无效的数据。
我们通过一个场景来理解什么叫无效的数据:
假设表B为用户表,表A为订单表。表A订单表存在一个字段user_id
,这个字段是表B用户表的主键。也就是说,表A的字段user_id
为表B用户表的外键。
如果表B用户表不存在一个user_id = 99
的记录,那么现在表A订单表有一个记录,这个记录对应user_id
字段的值为99
。通过逻辑,我们可以判断到 既然都不存在这个用户,怎么可能会有这个用户的订单,这条记录是无效的。这个就叫做无效的数据。
看到这里,我们就懂了,这就是外键约束的作用。
俗话说,有得必有失。外键约束可以保证数据的正确性,那么它肯定是牺牲了什么才换取到的!
没错,每当我们在从表插入一条数据,数据库就会检查主表对应的记录存不存在。这显然会降低数据库插入数据的效率,降低数据率的性能。
因此,大部分互联网应用程序为了追求数据,并不会设置外键约束,而是靠应用程序自身来保证逻辑的正确性。
自增约束
自增约束就是当我们插入数据时,对应的字段没有赋值。那么系统会自动对当前的最大值加1作为这个字段的值。自增约束通常是和主键一起使用的。
注:任何一个字段想要自增,前提本身为索引,而且值为整数。一张表只能有一个自增长。
非空约束
非空约束就没什么好介绍的了,就是对应字段的值不能为空。
唯一约束
唯一约束就是对应字段的值是唯一的,不能重复。
默认值约束
默认值约束就是当插入记录时,对应字段的值没有给定,它会插入提前给定默认值而不是NULL。
检查约束
检查约束就是检查指定字段是否满足条件,满足条件的记录才能被插入数据库。
创建约束
介绍完了常见约束,我们就来看看怎么为表添加约束。
约束分为表级约束和列级约束。
列级约束:该约束应用于一列上。
表级约束:该约束应用于一列或多列上
主键约束
列级约束
CREATE TABLE table_name(
column_name column_type CONSTRAINT [pk_name] PRIMARY KEY,
column_name column_type
);
表级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type,
CONSTRAINT [pk_name] PRIMARY KEY(column_name[, column_name])
);
上面的pk_name
表示是该约束的名称,我们可以为该约束取名,方便后面删除指定的约束。
如果表已经创建,我们可以这样为表增加主键约束:
ALTER TABLE table_name ADD CONSTRAINT [pk_name] PRIMARY KEY(column_name[, column_name]);
外键约束
列级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type CONSTRAINT [fk_name] FOREIGN KEY REFERENCES other_table_name
);
表级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type,
CONSTRAINT [fk_name] FOREIGN KEY REFERENCES other_table_name(column_name[, column_name])
);
这里的fk_name
是为约束取名,方便后面删除指定的约束。other_table_name
是从表的表名。
如果表已经创建,我们可以这样为表增加外键约束:
ALTER TABLE table_name ADD CONSTRAINT [fk_name] FOREIGN KEY REFERENCES(column_name[, column_name]);
唯一约束
列级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type CONSTRAINT [unique_name] UNIQUE
);
表级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type,
CONSTRAINT [unique_name] UNIQUE (column_name[, column_name])
);
如果表已经创建,我们可以这样为表增加唯一约束:
ALTER TABLE table_name ADD CONSTRAINT [unique_name] UNIQUE (column_name[, column_name]);
检查约束
列级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type CONSTRAINT [check_name] CHECK(condition)
);
表级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type,
CONSTRAINT [check_name] CHECK (condition)
);
这里检查约束的表级约束所指定的字段是包含在condition里面的。
举个例子:
CREATE TABLE user(
uid INT UNSIGHED PRIMARY KEY AUTO_INCREMENT,
age TINYINT UNSIGNED,
salary TINYINT UNSIGNED,
CHECK(age>0 AND salary<2000)
);
看到这里,我们就知道了,上面的user
表就限制了age和salary的取值。只有满足上述条件的记录才能插入。
如果表已经创建,我们可以这样为表增加检查约束:
ALTER TABLE table_name ADD CONSTRAINT [check_name] CHECK(condition);
自增约束
列级约束
CREATE TABLE table_name(
column_name column_type PRIMARY KEY AUTO_INCREMENT,
column_name column_type
);
这里说明一下,为什么会有PRIMARY KEY
?
我前面说了,自增约束对应列一定要是索引,而主键约束其实也是一个索引。不记得的,翻回去看看。而且该列的数据类型一定要是数值类型。
那么我们不用主键行不行,当然不用也是可以的。我们可以自己去为指定列创建索引,然后使用自增约束。但是其实一般我们都是把自增约束和主键约束一起使用的。
自增约束是没有表级约束的。至于为什么?
我认为这是因为自增约束是为数字类型的值加一,而且一张表只能有一个自增约束的原因。
非空约束
列级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type NOT NULL
);
非空约束没有表级约束。
如果表已经创建,我们可以这样为表增加非空约束:
ALTER TABLE table_name MODIFY column_name column_type NOT NULL;
默认值约束
列级约束
CREATE TABLE table_name(
column_name column_type,
column_name column_type DEFAULT default_value
);
这里的default_value
就是我们需要提前设定的默认值。当然默认值要符合对应列的数据类型。
默认值约束没有表级约束。
删除约束
删除主键约束
ALTER TABLE table_name DROP PRIMARY KEY;
删除外键约束
ALTER TABLE table_name DROP FOREIGN KEY pk_name;
删除唯一约束
ALTER TABLE table_name DROP INDEX unique_name;
删除检查约束
ALTER TABLE table_name DROP CONSTRAINT check_name;
像自增约束,非空约束,默认值约束这些没有约束名的约束,我们通过修改列结构来实现约束的删除
ALTER TABLE table_name MODIFY column_name column_type;
若有什么错误或补充的,请各位谅解并在评论告知我!谢谢