【MySQL-约束篇】

目录

  • 1、空值(Null)
  • 2、默认值
  • 3、主键
  • 4、自增
  • 5、唯一键
  • 6、外键

1、空值(Null)

先看一个表结构。

+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(11)     | YES  |     | NULL    |       |
| name    | varchar(11) | YES  |     | NULL    |       |
| password | varchar(11) | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+

该表中的id、name、password字段都允许为空值。
插入一个数据

insert into aaaa values (3,"猫爷");
+------+--------+---------+
| id   | mingzi | pssword |
+------+--------+---------+
|    1 | 猫爷   | 123456  |
|    2 | 狗哥   | 654321  |
|    3 | 猫爷   | NULL    |
+------+--------+---------+

其中,第三行猫爷的password字段为空。

在创建表的时候,我们可以设置字段不为空。在使用表的时候,如果有业务要求可以为空,我们就可以不设置空值,之外我们最好都设置字段不能为空。

数据库是用来管理数据的,他对数据的管理很苛刻,其中是否为空就是数据库对数据的一种约束,只要对数据约束的够好,出现的错误就越少,在使用的时候也更加轻松。

create table bbbb(
	id int not null,
	name varchar(11) not null
);

desc bbbb;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   |     | NULL    |       |
| name  | varchar(11) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

这时候如果漏了一个字段不填数据,就会报错,数据库不允许不守规则的数据进入。

2、默认值

看表结构

+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(11) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

表中默认值为空。默认值也是一种约束,插入一条记录时,某字段没有数据插入,该字段就会插入默认值。

创建一个新表cccc

create table cccc( 
	id int not null,
	name varchar(11) default "三毛",  
	age enum('男','女') default '男'
)charset=utf8;

desc cccc;
+-------+-------------------+------+-----+---------+-------+
| Field | Type              | Null | Key | Default | Extra |
+-------+-------------------+------+-----+---------+-------+
| id    | int(11)           | NO   |     | NULL    |       |
| name  | varchar(11)       | YES  |     | 三毛    |       |
| age   | enum('男','女')   | YES  |      ||       |
+-------+-------------------+------+-----+---------+-------+

插入几条记录

insert into cccc (id,name) values (1,"陈平安");
insert into cccc (id) values (2);
insert into cccc (id,age) values (3,'女');

+----+-----------+------+
| id | name      | age  |
+----+-----------+------+
|  1 | 陈平安     ||
|  2 | 三毛       ||
|  3 | 三毛       ||
+----+-----------+------+

3、主键

主键是用来唯一标识数据库的一个字段的数据,不能重复不能为空

如何设置主键:

create table dddd(
		id int primary key comment '唯一标识',
		name varchar(11) default '三毛'
)charset=utf8;
  • 删除主键 alter table 表名 drop primary key
  • 追加主键 alter table 表名 add primary key(字段列名)

复合主键
有一些业务需求,一个单独的字段无法标识一段数据。
比如我们标识一个进程,是用ip地址和端口号来共同标识的。

create table eeee(
		ip varchar(33) primary key comment 'IP地址',
		port int primary key comment '端口号'
	);
  • 当插入一条ip和post已经存在的记录时就会报错。两个主键一起标识。
insert into eeee values ('127.0.0.1',8000);
插入成功
insert into eeee values ('127.0.0.1',8001);
插入成功
insert into eeee values ('192.0.0.3',8001);
插入成功
insert into eeee values ('127.0.0.1',8000);
插入失败

4、自增

auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。

一搬设置主键的时候会给一个自增属性

mysql> create table tt21(
-> id int unsigned primary key auto_increment,
-> name varchar(10) not null default ''
-> );

mysql> desc aa;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

mysql>
insert into tt21(name) values('a');
mysql> insert into tt21(name) values('b');
mysql> select * from tt21;
+----+------+
| id | name |
+----+------+
| 1  | a    |
| 2  | b    |
+----+------+

自增长的特点:

  • 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
  • 自增长字段必须是整数
  • 一张表最多只能有一个自增长

5、唯一键

唯一键和主键有一点类似,都是不许字段中的数据重复。
一张表中,主键的选取一般情况下是都是与业务无关的字段,但表中的字段也有一些具有唯一属性,我们也不能把他设置成主键,故可以把这些字段设置成唯一键。

create table students(
	id int primary key comment "表的主键",
	name varchar(11) not null comment "学生名字",
	phone varchar(11) unique comment "学生的电话号码",
	identity varchar(18) unique comment "身份证号"
);

关于唯一键和主键的区别:
我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复

mysql> desc students;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(11)     | NO   | PRI | NULL    |       |
| name    | varchar(13) | NO   |     | NULL    |       |
| phone   | varchar(11) | YES  | UNI | NULL    |       |
| dentity | varchar(18) | YES  | UNI | NULL    |       |
+---------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
创建成功。。。。。。。。
insert into students values (1,"王二","12345678","111111111111111111");
插入成功
insert into students values (2,"王二","123456789","111111111111111111");
插入失败,dentity字段的内容在表中已经存在,不能重复
insert into students values (2,"王二","123456789","");
插入成功
insert into students values (3,"王二","1111","1111");
插入成功

 select * from students;
+----+--------+-----------+--------------------+
| id | name   | phone     | dentity            |
+----+--------+-----------+--------------------+
|  1 | 王二   | 12345678  | 111111111111111111 |
|  2 | 王二   | 123456789 |                    |
|  3 | 王二   | 1111      | 1111               |
+----+--------+-----------+--------------------+
3 rows in set (0.00 sec)

小知识:如果表已经创建成功,但是想要修改表中的字符集
alter table students convert to character set utf8

6、外键

外键就需要涉及多张表了。
比如:

表一,班级表
create table classes(
	id int primary key comment "班级号",
	name varchar(11 not null comment "班级名称"
);

表二,学生表
create table students(
	id int primary key comment "学号",
	name varchar(11 not null comment "名字",
	class_id int comment "所处班级"
);

这两张表中,其中班级表 name字段就是外键。
学生表关联班级表,班级表是被关联者,班级表属于主表,学生表属于从表。

但是上面两张表并没有构成外键约束。
看例子:

mysql> select * from students;
+-----+--------+--------+
| id  | name   | class_id |
+-----+--------+--------+
|   2 | 小彭   |    101 |
|   3 | 小波   |    102 |
|   4 | 小烧   |    400 |
|   1 | 小陈   |    100 |
+-----+--------+--------+
我是能插入班级等于400的数据的,可实际上班级表中并没有400这个班级,这就是并没有设置外键约束

mysql> select * from classes;
+-----+-----------+
| id  | name      |
+-----+-----------+
| 100 | 尖子班    |
| 101 | 普通班    |
| 103 | 文艺班    |
+-----+-----------+
正确做法,在创建班级表的时候加外键约束
表一,班级表
create table classes(
	id int primary key comment "班级号",
	name varchar(11 not null comment "班级名称",
	foreign key (class_id) references myclass(id)
);

语法:foreign key (字段名) references 主表(列)

可能有人会说,我们不是可以用一张表吗?在学生表后面再加一个班级字段就行了啊,为什么还要多弄处一张表出来?

一张表会造成数据冗余

首先我们承认,这个世界是数据很多都是相关性的。
理论上,上面的例子,我们不创建外键约束,就正常建立学生表,以及班级表,该有的字段我们都有。
因为此时两张表在业务上是有相关性的,但是在业务上没有建立约束关系,那么就可能出现问题。
解决方案就是通过外键完成的。建立外键的本质其实就是把相关性交给mysql去审核了,提前告诉mysql表之间的约束关系,那么当用户插入不符合业务逻辑的数据的时候,mysql不允许你插入。

你可能感兴趣的:(mysql)