哈喽,大家好!我是保护小周ღ,本期为大家带来的是 MySQL 数据库中对表的约束,主要有null (空约束),unique(唯一约束),primary key(主键约束),default(默认值约束), forelgn key(外键约束),check(检查约束),超多实例讲解,通俗易懂。
更多相关知识敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★*
一、数据库的约束
1.1数据库的约束类型
1.2 null 约束
我们在创建表的时候在创建字段的时候可以指定某列不为空,
设计一个学生表 stud ,包含字段 id 类型 varchar(11) , 设置 not null , name 字段,类型 varchar(20)
表创建成功,这是插入两条记录观察一下:
我们可以观察到 插入第一条数据时,没有报错,当第二条记录企图插入一条 null 值时就报错了。
Column 'id' cannot be null —— 列“id”不能为空
当我们企图插入 只有姓名的字段的是否也报错了,字段“id”没有默认值,也是就表示我们不能在id 为空的情况下插入一行记录。show warnings; 可以查看当前的sql语法错误.
1.3 unique (唯一约束)
被指定的该列的记录属性不能重复,比如:每一个人都有自己独有的身份证号,是独一无二的数字组合,所以是不能重复的,在对字段添加该约束后,插入数据时,会根据该字段约束遍历表中的数据,确认没有该字段重复值后方可插入。
设计一个学生表 stud ,包含字段 id 类型 varchar(11) , 设置 unique约束 , name 字段 not null,类型 varchar(20)
此时我们的 stud 表 id 字段的属性不可重复,name 字段属性 不可为空。
插入3条记录观察观察 : 1 张三, 1 ,李四 , 2, null;
Duplicate entry '1' for key 'id' —— 键“id”的重复条目“1”
Column 'name' cannot be null —— 列“name”不能为空
所以最终只插入了一条记录。
1.4 primary key (主键约束)
有了约束之后,我们创建的表格就会越来越规范,根据博主上面所说,unique 约束字段不可重复,
not null 约束字段不可为空,那这次介绍的 主键约束 primary key 相当于 unique + not null 的约束效果,字段不为空且不可重复。
重新构建了学生表 stud,并为 id 字段设置了主键约束,
插入3条记录观察观察 : 1 张三, 1 ,李四 , 2, null;
Duplicate entry '1' for key 'PRIMARY' —— 键“PRIMARY”的重复条目“1”
Column 'name' cannot be null —— 列“name”不能为空
插入:null, 王五 或者 只插入 王五
一个数据表只能有一个主键,一个主键约束也可以针对多个字段创建约束,这样就是多个字段处于不可为空且不可重复的状态。,数据库的主键,指的是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性。主键主要是用与其他表的外键关联,以及文本记录的修改与删除。
主键的作用
1)保证实体的完整性;
2)加快数据库的操作速度
3)在表中添加新记录时,DBMS会自动检查新记录的主键值,不允许该值与其他记录的主键值重复。
4)DBMS自动按主键值的顺序显示表中的记录。如果没有定义主键,则按输入记录的顺序显示表中的记录。
对于整型(int)的主键,可以搭配自增长 auto_increment 使用,在插入数值时,不给主键字段赋值,主键字段就会根据上一条主键字段的值 + 1。
插入2条记录观察观察 : 1 张三, null ,李四 。
可以看到第一条数据我们对主键 id 插入了数值 1 , 第二条记录,我们对主键 id 插入了数值 null ,正是因为我们对整型主键 id 设置了自增长,所以根据上一个字段的 id 值自增 + 1 = 2;
再插入2条记录观察观察 :100, 王五, null 赵六;
这个时候我们可以看到,这个自增属性当面对主动插入时就会失效,当需要自增时还是根据上一条记录的自增字段的值 + 1,所以是赵六的学号是 101, 而不是 3,这个自增属性就像是一个全局变量,可以记录字段的值,输入的时候就赋值,没有赋值的是否就自增。
1.5 default (默认值约束)
当我们对某个字段定义 default 约束的时候,我们在插入记录时,如果忽略该条记录,那么这条记录会按照设置的默认值填充。
例题:重新构建了学生表 stud,并为 sex 字段设置了默认值约束,默认值设置为“男”。
数据表构建完毕, 由上表可见,博主设置了三个字段,id , name ,sex ,并将 sex 字段设置默认值约束。
插入2条记录观察观察 : 1 张三 男, 2 李四 。
第一次我们对第一行记录的所有字段的数据进行插入数据,第二次我们只对第二行记录的 id ,name 字段进行设置,忽略了 sex 字段,但此时我们再对数据表 stud 的数据进行查询的时候发现 第二行记录的sex 字段填充了我们设置的默认值,男。
1.6 forelgn key (外键约束)
作为关系型数据库,外键约束在多表关系中是至关重要的,外键约束主要是关联其他表的主键或者唯一值。语法:
foreign key 【字段名】references 【主表】(主键字段或者唯一字段)
重点:
外键:针对子表,被约束的字段数据,受父字段数据的约束,不可以增改。
外键:针对父表,不能删除修改子表被约束的字段,两表之间约束是双向的。
举个例字:
我们先创建这两张表并为成绩表建立外键约束。
学生表 stud 的创建:
成绩表 score 的创建:
对子表score 的id 字段与 学生表的id字段产生了外键约束, 学生表为主表。
例题: 对stud 学生表插入数据,观察对score 成绩表有什么影响?
1 张三 男, 2 李四 男 , 3 王小六 女
语句正常执行没有任何变化。
例题: 对score 成绩表插入数据,观察对stud 学生表有什么影响?
1 80 99 90, 2 74 80 99 , 3 98 78 69 , 4 50 65 56
当我们插入前三条数据的时候没有任何问题,现在插入第四条数据
直接报错,不必惊慌,错误1452(23000):不能添加或更新子行:外键约束失败(' school ')。' score_ibfk_1 ',约束' score_ibfk_1 '外键(' sc_id ')
这是报错信息,意思就是我们不能添加子行,因为受到了主表 stud, stu_id 字段的约束,
外键:针对子表,被约束的字段数据,受父字段数据的约束,不可以增改(改也只能是修改非约束字段)。通俗来讲就是在添加数据或者是修改数据之前,会先遍历父表,如果在父表中找不到约束的关键字,就不允许在子表中进行 insert / update 操作。
所以我们不能在成绩表中添加学号不在 stud学生表中的信息,在创建成绩表的时候我们也对 sc_id 字段设置了主键约束,所以呢, 要想在成绩表中添加记录需要满足以下要求,该记录 sc_id 字段不可为空且不可重复且该记录中的 sc_id字段值必须在 stud 学生表中存在。
此时我们成绩表的操作并不会对我们的主表造成影响。
例题: 对 stud 学生表删除数据修改数据,观察对 score 成绩表有什么影响?
先尝试删除 学生表中的一条记录:
错误1451(23000):不能删除或更新父行:外键约束失败(' school ')。' score_ibfk_1 ',约束' score_ibfk_1 '外键(' sc_id ')
报错提示的也非常明显,我们不能修改或删除父行, 因为两表之间存在外键约束。
外键:针对父表,不能删除修改子表被约束的字段,两表之间约束是双向的。
尝试修改学生表中的一条记录:将学生表中的学号为3 的同学的学号修改为 4
错误1451(23000):不能删除或更新父行:外键约束失败(' school ')。' score_ibfk_1 ',约束' score_ibfk_1 '外键(' sc_id ')
尝试修改学生表中的一条记录:将学生表中的学号为3 的同学姓名由 王小六 修改为 王六
修改成功,只要不修改作为外键约束的字段,其他字段的值是可以被修改的。
总结:两表之间或者多表之间存在外键约束,作为主表来讲是不可以随便删除记录的, 那么如何保证数据的有效性呢,比如张三同学已经毕业了,那张三同学的信息就失效了。我们有两种做法,
一:是删除所有与主表与子表有对应字段外键关系的记录,主表是不可删除修改,子表是可以删除的, 我们先将子表中的约束记录删除,主表中的约束字段没有在子表中体现,那么主表中自然是允许删除的,但是有一个缺点就是你无法判断该字段建立了多少外键约束,非要删除的话,需要去找到这些子表,子表与子表之间有可能也存在外键约束,就会非常的复杂。
二:对主表添加可以判断数据是否有效的字段,比如是否毕业,当张三毕业时,我们将该字段设置为已毕业,然后再使用数据时是可以添加条件来约束,例如查找有所未毕业同学的信息,利用条件查询即可。
1.7 check 检查约束
在数据库中,CHECK 约束是指约束表中某一个或者某些列中可接受的数据值或者数据格式。
CHECK 约束可以应用于一个或者多个列,也可以将多个CHECK 约束应用于一个列。
当除去某个表时,对这个表的CHECK 约束也将同时被去除。
在更新表数据的时候,系统会检查更新后的数据行是否满足 CHECK 约束中的限定条件。MySQL 可以使用简单的表达式来实现 CHECK 约束,也允许使用复杂的表达式作为限定条件,例如在限定条件中加入子查询。
设置检查约束时要根据实际情况进行设置,这样能够减少无效数据的输入。
这个约束是啥意思呢,就是指定字段中的数据只能存在于设定的数据范围内,例如:sex 字段 ,
check (sex = "男" or sex = "女")
我们这样限定了之后,就不会出现其他的性别,比如说,"双性",不可能输入,只能存在 “男”或 “女”。比如我们限定了学号的范围 [1,10], 我们的id就只能在这个范围内。
表创建完毕,现在插入两条数据观察观察。
但是我们会发现虽然我们期望 check 约束可以将数据限定来我们期望的范围内,但是在添加数据的时候还是可以超出这个限制,原因是因为,不同于SQL,在MYSQL中,CHECK只是一段可调用但无意义的子句。MySQL会直接忽略。 CHECK子句会被分析,但是会被忽略。
说白了就是没用,就是个摆烂的,博主寻思以为自己写错了,特意查询了一波资料,啥用没有,咦~
二、修改表的结构 (alter)
以上约束,可以看到博主都是在创建表的时候添加的( create ),除了我们在创建的时候添加约束,其实还有一种办法就是 修改表的结构 (alter),但是不建议使用吖,因为当我们对已有的表再去修改表的结构的时候会对表中原先存储的数据造成一定程度上的影响,那么我们要添加约束的时候使用修改字段的这个关键字即可 ,就像是创建时的那样,类型后面加上约束。
- 修改字段
ALTER TABLE test.student MODIFY id_card varchar(30) 【约束】
-- 修改表结构
-- 添加字段
-- 新增一个叫做id_card的字段,它的类型是可变字符串且非空。
ALTER TABLE test.student ADD id_card varchar(18) NOT NULL;
-- 修改字段
ALTER TABLE test.student MODIFY id_card varchar(30)
-- 修改字段名
ALTER TABLE test.student CHANGE id_card id_card1 char(10) not null;
-- 删除字段
ALTER TABLE test.student DROP id_card1;
-- 修改表名
ALTER TABLE test.student RENAME test.stu;
好了好了,关于数据库的约束就浅浅的说一一下啦,关于查询还有许多知识,一篇写不下,下篇博客将着重点将查询的进阶~
至此,Mysql 系列的第四篇内容博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。
本期收录于博主的专栏—— MySQL & JDBC,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“MySQL 数据库以及Java JDBC 编程的相关知识”。
下一期:MySQL 数据库查询的进阶
感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★*
遇见你,所有的星星都落在我的头上……