MySql学习笔记06——约束介绍

约束

什么是约束?

约束对应的英语单词:constraint
在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中数据的完整性、有效性!!!约束的作用就是为了保证:表中的数据有效!!

约束的分类

  • 非空约束 not null
  • 唯一性约束 unique
  • 主键约束primary key
  • 外键约束 foreign key
  • 检查约束 check(mysql不支持,oracle支持)

使用语法:

在创建表的时候

create table 表名(
    字段名1 类型1 约束,
    字段名2 类型2 约束,
    字段名3 类型3 约束
);

非空约束

drop table if exists t_vip;
create table t_vip(
    id int,
    name varchar(255) not null
);
insert into t_vip(id,name) values(1,'zhangsan');
insert into t_vip(id,name) values(2,'lisi');

对于批量化执行SQL语句,我们可以使用执行sql脚本的方法。

  • 创建.sql文件
  • 将语句写入文件
  • source 脚本路径
mysql> source D:\mysql_learning\mysql_learning\document\vip.sql
Query OK, 0 rows affected, 1 warning (0.01 sec)

Query OK, 0 rows affected (0.02 sec)

Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)
mysql> select * from t_vip;
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
+------+----------+

由于给字段name加了非空约束,因此每次添加数据的时候,如果没有添加name字段的数据,就会报错,这样就保证了数据的可行性和完整性。

mysql> insert into t_vip(id) values(123);
ERROR 1364 (HY000): Field 'name' doesn't have a default value

唯一性约束

唯一性约束unique约束的字段不能重复,但是可以为null

drop table if exists t_vip;
    create table t_vip(
        id int,
        name varchar(255) unique,
        email varchar(255)
    );
    insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
    insert into t_vip(id,name,email) values(2,'lisi','lisi@123.com');
    insert into t_vip(id,name,email) values(3,'wangwu','wangwu@123.com');
    select * from t_vip;

这个时候加上name重复的信息,就会报错。

mysql> insert into t_vip(id,name,email) values(4,'wangwu','wangwu@sina.com');
ERROR 1062 (23000): Duplicate entry 'wangwu' for key 't_vip.name'

新需求:name和email两个字段联合起来具有唯一性!!!!

也就是说,一条新的数据,与表中的数据进行比较,name或者email字段有一个可以重复,但是如果和某一个数据比较,发现name和email字段的信息都重复了,就会报错。

drop table if exists t_vip;
        create table t_vip(
            id int,
            name varchar(255) unique,  // 约束直接添加到列后面的,叫做列级约束。
            email varchar(255) unique
        );

这种创建方式不能满足我们的新要求,因为这样是分别对两个字段进行唯一性约束,两个字段,各自唯一。

如果

insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
insert into t_vip(id,name,email) values(2,'zhangsan','zhangsan@sina.com');

这样插入新的数据就会报错,因为name字段重复了,我们的需求就是有可能会有重名的人出现,但是email是不一定一样的。

drop table if exists t_vip;
            create table t_vip(
                id int,
                name varchar(255),
                email varchar(255),
                unique(name,email) // 约束没有添加在列的后面,这种约束被称为表级约束。
            );

表级约束,多个字段联合起来进行唯一性约束,与一行数据进行比较,如果两个字段名都重复了,就会报错了。

# 但是这样是不会报错的
insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
insert into t_vip(id,name,email) values(2,'zhangsan','zhangsan@sina.com');

表级约束一般用在需要给多个字段联合起来添加某一个约束的时候,需要使用表级约束:例如允许重名的情况出现,但是不允许同时email也重复了。

uniquenot null可以联合起来进行约束

drop table if exists t_vip;
        create table t_vip(
            id int,
            name varchar(255) not null unique
        );

在mysql当中,如果一个字段同时被not null和unique约束的话,该字段自动变成主键字段。(注意:oracle中不一样!)

not null没有表级约束,只能用列级约束

主键约束

primary key简称pk

主键字段:在字段上加上主键约束,该字段就是主键字段。

主键值:主键上的每个值就是主键值。

主键是每一行记录的唯一标识,是一种类似身份证的存在!!

每张表都应该有主键约束,如果没有主键约束,表就无效了。

主键的特征:not null + unique(主键值不能是NULL,同时也不能重复!)

列级约束:

create table t_vip(
            id int primary key,  //列级约束
            name varchar(255)
        );
        insert into t_vip(id,name) values(1,'zhangsan');
        insert into t_vip(id,name) values(2,'lisi');

        insert into t_vip(id,name) values(2,'wangwu');# 报错,id为2,重复了
        ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'

        insert into t_vip(name) values('zhaoliu');# 报错,id为null,不能为null
        ERROR 1364 (HY000): Field 'id' doesn't have a default value

表级约束:

create table t_vip(
            id int,
            name varchar(255),
            primary key(id)  // 表级约束
        );

表级约束是用来对多个字段进行联合添加约束:

create table t_vip(
            id int,
            name varchar(255),
            email varchar(255),
            primary key(id,name)  # id和name字段联合起来作为主键约束
        );
        insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
        insert into t_vip(id,name,email) values(1,'lisi','lisi@123.com');# 这样是正确的,不会报错

        insert into t_vip(id,name,email) values(1,'lisi','lisi@123.com');# 错误,报错,1-lisi同时重复
        ERROR 1062 (23000): Duplicate entry '1-lisi' for key 'PRIMARY'

一个字段的主键约束被称作单一主键,多个字段联合作为主键被称作复合主键,不推崇复合主键。

同时,一张表只能有一个主键约束。

作为主键约束的字段一般是int bigint char 类型,一般都是定长的,不建议varchar类型

主键除了:单一主键和复合主键之外,还可以这样进行分类?
自然主键:主键值是一个自然数,和业务没关系。
业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。这就是业务主键!

在实际开发中使用业务主键多,还是使用自然主键多一些?
自然主键使用比较多,因为主键只要做到不重复就行,不需要有意义。
业务主键不好,因为主键一旦和业务挂钩,那么当业务发生变动的时候,
可能会影响到主键值,所以业务主键不建议使用。尽量使用自然主键。

使用auto_increment自动维护主键值,auto_increment表示自增,从1开始,以1递增!

mysql> create table t_vip(
    ->  id int primary key auto_increment,
    ->  name varchar(32)
    -> );
# 之后多次插入数据:
insert into t_vip(name) values('zhangsan');
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | zhangsan |
|  3 | zhangsan |
|  4 | zhangsan |
|  5 | zhangsan |
|  6 | zhangsan |
|  7 | zhangsan |
|  8 | zhangsan |
+----+----------+

外键约束

当我们要将两个表连接的时候,各自会将一个字段值作为两个表连接的“接口”,但是有时候这两个表中这个字段值会有点出入,导致两个表连接的时候会有记录无法匹配的情况出现,而外键约束则能保证这两个表中,作为两表接口的字段值能完全匹配上。

两个概念:

子表和父表;

子表引用父表中的一个字段值作为外键约束。

顺序:

删除表的顺序?
先删子,再删父。

创建表的顺序?
先创建父,再创建子。

删除数据的顺序?
先删子,再删父。

插入数据的顺序?
先插入父,再插入子。

foreign key(cno) references t_class(classno)

drop table if exists t_student;
drop table if exists t_class;

create table t_class( # 父表
    classno int primary key,
    classname varchar(255)
);
create table t_student( # 子表
    no int primary key auto_increment,
    name varchar(255),
    cno int,
    foreign key(cno) references t_class(classno)# 参照t_class中的classno对cno进行外键约束
);

insert into t_class(classno, classname) values(100, '北京市大兴区亦庄镇第二中学高三1班');
insert into t_class(classno, classname) values(101, '北京市大兴区亦庄镇第二中学高三1班');

insert into t_student(name,cno) values('jack', 100);
insert into t_student(name,cno) values('lucy', 100);
insert into t_student(name,cno) values('lilei', 100);
insert into t_student(name,cno) values('hanmeimei', 100);
insert into t_student(name,cno) values('zhangsan', 101);
insert into t_student(name,cno) values('lisi', 101);
insert into t_student(name,cno) values('wangwu', 101);
insert into t_student(name,cno) values('zhaoliu', 101);

select * from t_student;
select * from t_class;
mysql> select * from t_student;
+----+-----------+------+
| no | name      | cno  |
+----+-----------+------+
|  1 | jack      |  100 |
|  2 | lucy      |  100 |
|  3 | lilei     |  100 |
|  4 | hanmeimei |  100 |
|  5 | zhangsan  |  101 |
|  6 | lisi      |  101 |
|  7 | wangwu    |  101 |
|  8 | zhaoliu   |  101 |
+----+-----------+------+
8 rows in set (0.00 sec)

mysql> select * from t_class;
+---------+---------------------------------------------------+
| classno | classname                                         |
+---------+---------------------------------------------------+
|     100 | 北京市大兴区亦庄镇第二中学高三1|
|     101 | 北京市大兴区亦庄镇第二中学高三1|
+---------+---------------------------------------------------+
2 rows in set (0.00 sec)

这个时候如果在外键约束之外添加字段cno的字段值

mysql> insert into t_student(name,cno) values('kuku',110);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`bjpowernnode`.`t_student`, CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`classno`))

就会报错。

外键引用父表中的某个字段,该字段应该至少有unique唯一性约束,但不一定是主键

外键值可以是null。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值