• SQL中的约束


    1、约束
    ---1.1概述
    ---1.2常见约束
    ---1.3常见约束示例
    ---1.4组合使用not null和unique
    2、主键约束PK(primary key)
    ---2.1示例
    ---2.2主键相关术语
    ---2.3主键的作用
    ---2.4主键的分类
    ---2.5主键值自增
    3、外键约束FK(foreign key)
    ---3.1示例
    ---3.2概述及相关术语
    ---3.3外键的分类
    4、级联删除与级联更新
    ---4.1概述
    ---4.2级联删除
    ---4.3级联更新

    约束

    概述

    1、什么是约束(constraint)?
    实际上是对表中数据的限制条件。
    2、设计表时加入约束的目的?
    保证表中数据的完整和有效。

    常见约束

    非空约束(not null):not null约束的字段不能为NULL值,必须赋具体数据。
    唯一约束(unique):unique约束的字段具有唯一性,不可重复。
    主键约束(primary key):约束的字段既不能为NULL,也不能重复(简称PK)。
    外键约束(foreign key):简称FR
    检查约束(check)

    常见约束示例
    • 非空约束
      示例:创建t_user表,name字段不能为空。
    drop table if exists t_user;
    create table t_user ( 
    id int(10), 
    name varchar(32) not null, 
    email varchar(128)
    );
    

    不插入name:

    insert into t_user
    (id, email)
    values(1, '123@qq.com');
    

    会报错:

    Error Code: 1364. 
    Field 'name' doesn't have a default value
    
    • 唯一约束
      1、示例一:创建t_user表,name不能为空,email保证唯一。
      方法一:列级约束
    drop table if exists t_user;
    create table t_user
    (id int(10), 
    name varchar(32) not null, 
    email varchar(128) unique
    );
    insert into t_user
    (id,name,email) 
    values(1, 'zhangsan', '111@qq.com');
    insert into t_user
    (id,name,email) 
    values(2, 'lisi', '111@qq.com');
    

    在这里插入图片描述
    只插入了zhangsan的,lisi字段重复了,报错:

    Error Code: 1062. 
    Duplicate entry '111@qq.com' for key 't_user.email'
    

    再插入空值:

    insert into t_user
    (id,name) 
    values(3, 'wangwu');
    insert into t_user
    (id,name) 
    values(4, 'zhaoliu');
    

    在这里插入图片描述
    结论:“unique约束”约束的字段不能重复,但是可以为NULL,NULL不是一个值,也不能用等号比较。
    方法二:表级约束

    drop table if exists t_user;
    create table t_user
    (id int(10), 
    name varchar(32) not null, 
    email varchar(128), 
    unique(email)
    );
    

    与方法一效果上相同。
    2、示例二:使用表级约束给多个字段联合添加约束(name和email两个字段联合唯一)。

    drop table if exists t_user;
    create table t_user
    (id int(10), 
    name varchar(32) not null, 
    email varchar(128), 
    unique(name, email)
    );
    insert into t_user
    (id,name,email) 
    values(1, 'zhangsan', '111@qq.com'), 
    (2, 'lisi', '111@qq.com');
    insert into t_user
    (id,name,email) 
    values(2, 'lisi', '111@qq.com');
    

    在这里插入图片描述
    由于表级联合约束限制,第二个lisi插入失败,Error Code还是1062。
    3、表级约束还可以给约束起名字,以后可通过名字操作这个约束。

    create table t_user
    (id int(10), 
    name varchar(32) not null, 
    email varchar(128), 
    constraint t_user_email_unique 
    unique(email)
    );
    

    ①查询唯一性约束的名字:show databases;
    在这里插入图片描述
    ②查看information_schema库的表:
    use information_schema;
    show tables;
    ③TABLE_CONSTRAINTS该表格与门存储约束信息:
    desc TABLE_CONSTRAINTS
    ④查询出表t_user中的唯一约束名称:

    SELECT CONSTRAINT_NAME 
    FROM TABLE_CONSTRAINTS
    where TABLE_NAME = 't_user';
    

    在这里插入图片描述

    组合使用not null和unique
    • 作用:被not null和unique约束的字段,该字段即不能为null也不能重复。
    • 示例: 创建t_user表,用户编号为id,用户名称name即不能为空也不能重复。
    drop table if exists t_user;
    create table t_user
    (id int(10), 
    name varchar(32) not null unique
    );
    

    主键约束PK(primary key)

    示例

    1、创建表(插入数据代码省略)

    create table t_user
    (id int(10) primary key, 
    name varchar(255), 
    email varchar(255)
    );
    

    在这里插入图片描述
    2、再次插入id为1的数据:

    insert into t_user(id,name,email) 
    values(1,'ww','ww@123.com');
    

    报错:

    Error Code: 1062. 
    Duplicate entry '1' for key 't_user.PRIMARY'
    

    3、插入id为空的数据:

    insert into t_user(name,email) 
    values('ww','ww@123.com');
    

    报错:

    Error Code: 1364. 
    Field 'id' doesn't have a default value
    
    主键相关术语

    1、主键约束:给某个字段添加的约束。
    2、主键字段:表中某个字段添加主键约束之后,该字段被称为主键字段。
    3、主键值:主键字段中出现的每一个数据都被称为主键值。

    主键的作用

    1、添加主键primary key的字段即不能重复也不能为空,效果与“not null nuique”相同。但本质是不同的,添加主键约束之后,主键不仅会有“not null unique”作用,而且主键字段还会自动添加“索引 — index”
    2、 一张表应该有主键,若没有,表示这张表是无效的(联想:数据库设计第一范式),“主键值”是当前行数据的唯一标识,“主键值”是当前行数据的身份证号。(即使表中两行数据完全相同,但是由于主键不同,我们也认为这是两行完全不同的数据)

    主键的分类
    • 根据主键字段的字段数量来划分:
      1、单一主键(常用):是给一个字段添加主键约束。
      例:(列级)单一主键约束:id int(10) primary key
      (表级)单一主键约束:id int(10), primary key(id)(更常用)
      2、复合主键:多个字段联合起来添加一个主键约束。(违背三范式,不建议使用)
      例:id int(10), name varchar(32), primary key(id, name)
    • 根据主键性质来划分:
      1、自然主键:主键值是一个自然数,并且这个自然数与业务没有任何关系。(推荐使用)
      2、业务主键:主键值和当前表中的业务紧密相关。例如:银行卡的卡号做主键、拿着身份证号码作为主键。(不推荐用,因为业务一旦发生改变,主键值可能也要随之变化,但又无法变化,其会导致主键值重复。)
    • 注:无论是单一主键还是复合主键,一张表中主键约束只能有一个。
    主键值自增
    • MySQL中自动生成主键值(MySQL特有)
      1、定义:MySQL数据库管理系统中提供了一个自增数字auto_increment,专门用来自动生成主键值,主键值不需要用户去维护,也不需要用户生成,MySQL会自动生成。自增数字默认从1开始,以1递增:1、2、3、4、…
      2、示例: 递增关键字:auto_increment
    • 示例
    drop table if exists t_user;
    create table t_user
    (id int(32) primary key auto_increment, 
    name varchar(32)
    );
    insert into t_user(name) 
    values('zhangsan');
    insert into t_user(name) 
    values('lisi');
    

    在这里插入图片描述
    删除lisi的数据:

    delete from t_user 
    where id = 2;
    

    再增加一个wangwu:

    insert into t_user(name) 
    value('wangwu');
    

    在这里插入图片描述
    (主键不会是2,而是继续在原有的基础上增加)

    外键约束FK(foreign key)

    示例

    1、创建t_student表和t_class表(创建成一张表会造成数据的冗余)
    t_class:
    在这里插入图片描述
    t_student:
    在这里插入图片描述
    2、t_student表要与t_class表有关系,需要在t_student表中添加一个classno字段做为外键。
    t_student:
    在这里插入图片描述
    3、结论
    classno值必须来自cno。
    为了保证t_student表中的classno字段中的数据必须来自t_class表中的cno字段中数据,有必要给t_student表中classno字段添加外键约束;classno 称为外键字段,classno 中的100、200、
    300称为外键值,classno在这里是单一外键。
    4、相关SQL语句:

    DROP TABLE
    IF
    	EXISTS t_student;
    DROP TABLE
    IF
    	EXISTS t_class;
    CREATE TABLE t_class ( cno INT ( 3 ) PRIMARY KEY, cname VARCHAR ( 128 ) NOT NULL UNIQUE );
    CREATE TABLE t_student (
    	sno INT ( 3 ) PRIMARY KEY,
    	sname VARCHAR ( 32 ) NOT NULL,
    	classno INT ( 3 ),
    	CONSTRAINT t_student_classno_fk FOREIGN KEY ( classno ) REFERENCES t_class ( cno ) 
    );
    INSERT INTO t_class ( cno, cname )
    VALUES
    	( 100, '高三1班' );
    INSERT INTO t_class ( cno, cname )
    VALUES
    	( 200, '高三2班' );
    INSERT INTO t_class ( cno, cname )
    VALUES
    	( 300, '高三3班' );
    INSERT INTO t_student ( sno, sname, classno )
    VALUES
    	( 1, 'lucy', 100 );
    INSERT INTO t_student ( sno, sname, classno )
    VALUES
    	( 2, 'king', 100 );
    INSERT INTO t_student ( sno, sname, classno )
    VALUES
    	( 3, 'lily', 200 );
    INSERT INTO t_student ( sno, sname, classno )
    VALUES
    	( 4, 'ford', 200 );
    INSERT INTO t_student ( sno, sname, classno )
    VALUES
    	( 5, 'allen', 300 );
    INSERT INTO t_student ( sno, sname, classno )
    VALUES
    	( 6, 'teddy', 300 );
    

    5、关键语句:
    foreign key(classno) references t_class(cno)
    6、测试:
    在t_student表中插入一个班级编号为400的。

    INSERT INTO t_student ( sno, sname, classno )
    VALUES
    	( 7, 'Tom', 400 );
    

    报错:

    a foreign key constraint fails 
    (`powernode`.`t_student`, 
    CONSTRAINT `t_student_ibfk_1` 
    FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))
    

    执行失败原因:
    引用外键值在外键表t_class 中cno数据中不存在。

    概述及相关术语
    • 概述
      1、外键在同一张表中可以有多个外键存在,外键字段可以为NULL,外键为空的数据也叫孤儿数据。
      2、被引用字段必须具有unique约束(不一定是主键)。
      3、有了外键引用之后,表分为父表和子表,以上父表:班级表 t_class; 子表是:学生表 t_student;创建表时先创建父表,再删除子表;插入数据时,先插入父表数据,再插入子表数据。
      4、在MySQL中没有提供修改外键约束的语法功能。
      5、重点:典型的一对多设计是在多的一方加外键。
    • 相关术语
      外键约束:给某个字段添加的外键约束。
      外键字段:被添加外键约束的字段。
      外键值:外键字段中的数据称为外键值。
    外键的分类
    • 根据个数分类
      1、单一外键:给一个字段添加外键约束。
      2、复合外键:给多个字段联合添加一个外键。

    级联删除与级联更新

    概述
    • 用法
      在添加级联更新与级联删除的时候,需要在外键约束后面添关键字。
    • 注意
      级联更新与级联删除操作谨慎使用,因为级联操作会将数据改变或者删除(数据无价)。
    级联删除
    • 定义及语法
      在删除父表数据的时候,级联删除子表中数据。
      语法:
      on delete cascade
    • 例子
      1、删除原有的外键约束(删除t_student中的外键)
      语法:
      ALTER TABLE 表名 DROP FOREIGN KEY 外键字段;
    ALTER TABLE t_student 
    DROP FOREIGN KEY t_student_classno_fk;
    

    2、添加外键约束及级联删除功能(增加t_student_classno_fk外键,并加入级联删除on delete cascade)
    语法:
    ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 引用表名 (引用表中字段名称) ON DELETE CASCADE;

    ALTER TABLE t_student 
    ADD CONSTRAINT t_student_classno_fk 
    FOREIGN KEY (classno) REFERENCES t_class(cno) 
    ON DELETE CASCADE;
    

    3、测试:
    删除t_class表中班级编号为300的信息,包括所在班级的学生信息

    DELETE from t_class WHERE cno = 300;
    

    t_class:
    在这里插入图片描述
    t_student:
    在这里插入图片描述
    删除父表数据之后,同时级联删除了子表中的数据。

    级联更新
    • 定义与语法
      定义:在更新父表中数据的时候,级联更新子表中数据。
      语法:on update cascade
    • 例子
      1、删除外键约束(删除t_student中的外键)
      语法:
      ALTER TABLE 表名 DROP FOREIGN KEY 外键字段;
    alter table t_student 
    drop foreign key t_student_classno_fk;
    

    2、更新外键约束和添加级联更新功能(增t_student_classno_fk外键,并加入级联更新 on update cascade)
    语法:
    ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段) REFERENCES 引用表名称(引用表字段) ON UPDATE CASCADE;

    ALTER TABLE t_student 
    ADD CONSTRAINT t_student_classno_fk 
    FOREIGN KEY (classno) REFERENCES t_class(cno) 
    ON UPDATE CASCADE;
    

    3、测试:
    更新t_class表中班级编号200改为400,包括所在班级的学生信息。

    UPDATE t_class SET cno = 400 
    WHERE cno = 200;
    

    t_class:
    在这里插入图片描述
    t_student:
    在这里插入图片描述

  • 相关阅读:
    【OpenJudge 2.5-1792】这绝壁是一道玄学题!【DFS】
    【BZOJ1034】省队选手不务正业打泡泡堂(我也不知道是啥算法)
    文件操作的常用方法和使用
    数据类型所有方法和使用整理之------字典
    数据类型所有方法和使用整理之------列表
    用类的内置方法实现类型检查
    类的内置方法及描述符
    用python实现MRO算法
    RHEL6.5 DHCP服务器搭建
    Python之禅 吾心笃定
  • 原文地址:https://www.cnblogs.com/yu011/p/13338361.html
Copyright © 2020-2023  润新知