MySQL——约束(constraint)详解
该博客说说关于数据库中一个重要的知识点——约束
一、什么是约束
约束英文:constraint
约束实际上就是表中数据的限制条件
二、约束作用
表在设计的时候加入约束的目的就是为了保证表中的记录完整和有效
比如name字段中要让其用户名不重复,这就需要添加约束。或者必须注册的时候需要添加邮箱等
三、约束种类
非空约束(not null)
唯一性约束(unique)
主键约束(primary key) PK
外键约束(foreign key) FK
检查约束(目前MySQL不支持、Oracle支持)
下面将逐一介绍以上约束
四、非空约束
用not null约束的字段不能为null值,必须给定具体的数据
创建表,给字段添加非空约束(创建用户表,用户名不能为空)
mysql> create table t_user(
-> id int(10),
-> name varchar(32) not null
-> );
Query OK, 0 rows affected (0.08 sec)
如果没有插入name字段数据,则会报错
mysql> insert into t_user (id) values(1);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
五、唯一性约束
unique约束的字段,具有唯一性,不可重复,但可以为null
创建表,保证邮箱地址唯一(列级约束)
mysql> create table t_user(
-> id int(10),
-> name varchar(32) not null,
-> email varchar(128) unique
-> );
Query OK, 0 rows affected (0.03 sec)
1、表级约束
mysql> create table t_user(
-> id int(10),
-> name varchar(32) not null,
-> email varchar(128),
-> unique(email)
-> );
如果插入相同email会报错
mysql> insert into t_user(id,name,email) values(1,'xlj','932834897@qq.com');
Query OK, 1 row affected (0.00 sec) mysql> insert into t_user(id,name,email) values(2,'jay','932834897@qq.com');
ERROR 1062 (23000): Duplicate entry '932834897@qq.com' for key 'email'
2、使用表级约束,给多个字段联合约束
联合约束,表示两个或以上的字段同时与另一条记录相等,则报错
mysql> create table t_user(
-> id int(10),
-> name varchar(32) not null,
-> email varchar(128),
-> unique(name,email)
-> );
Query OK, 0 rows affected (0.01 sec)
插入第一条数据
mysql> insert into t_user(id,name,email) values(1,'xxx','qq.com');
Query OK, 1 row affected (0.05 sec)
插入第二条数据如果是与联合字段中的一条相同另一条相同,也是可以的
mysql> insert into t_user(id,name,email) values(2,'mmm','qq.com');
Query OK, 1 row affected (0.05 sec)
插入第三条数据,如果与联合字段都相同,则报错
mysql> insert into t_user(id,name,email) values(3,'mmm','qq.com');
ERROR 1062 (23000): Duplicate entry 'mmm-qq.com' for key 'name'
3、表级约束可以给约束起名字(方便以后通过这个名字来删除这个约束)
mysql> create table t_user(
-> id int(10),
-> name varchar(32) not null,
-> email varchar(128),
-> constraint t_user_email_unique unique(email)
-> );
Query OK, 0 rows affected (0.06 sec)
constraint是约束关键字,t_user_email_unique自己取的名字
例:用户名既不能为空,也不能重复
name varchar(32) not null unique
六、主键约束(primary key)PK
表设计时一定要有主键
1、主键涉及术语
主键约束
主键字段
主键值
2、以上三种术语关系
表中的某个字段添加主键约束后,该字段为主键字段,主键字段中出现的每一个数据都称为主键值
3、主键约束与“not null unique”区别
给某个字段添加主键约束之后,该字段不能重复也不能为空,效果和”not null unique”约束相同,但是本质不同。
主键约束除了可以做到”not null unique”之外,还会默认添加”索引——index”
4、一张表应该有主键字段,如果没有,表示该表无效
主键值:是当前行数据的唯一标识、是当前行数据的身份证号
即使表中两行记录相关数据相同,但由于主键值不同,所以也认为是两行不同的记录
5、按主键约束的字段数量分类
无论是单一主键还是复合主键,一张表主键约束只能有一个(约束只能有一个,但可以作用到好几个字段)
单一主键:给一个字段添加主键约束
复合主键:给多个字段联合添加一个主键约束(只能用表级定义)
单一主键(列级定义)
mysql> create table t_user(
-> id int(10) primary key,
-> name varchar(32)
-> );
Query OK, 0 rows affected (0.07 sec)
单一主键(表级定义)
mysql> create table t_user(
-> id int(10),
-> name varchar(32) not null,
-> constraint t_user_id_pk primary key(id)
-> );
Query OK, 0 rows affected (0.01 sec)
复合主键(表级定义)
mysql> create table t_user(
-> id int(10),
-> name varchar(32) not null,
-> email varchar(128) unique,
-> primary key(id,name)
-> );
Query OK, 0 rows affected (0.05 sec)
6、在MySQL数据库提供了一个自增的数字,专门用来自动生成主键值,主键值不用用户维护,自动生成,自增数从1开始,以1递增(auto_increment)
mysql> create table t_user(
-> id int(10) primary key auto_increment,
-> name varchar(32) not null
-> );
Query OK, 0 rows affected (0.03 sec)
插入两行记录,id主键值会自动增加
mysql> insert into t_user(name) values('jay');
Query OK, 1 row affected (0.04 sec)
mysql> insert into t_user(name) values('man');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+----+------+
| id | name |
+----+------+
| 1 | jay |
| 2 | man |
+----+------+
2 rows in set (0.00 sec)
七、外键约束(foreign key)FK
只能是表级定义(如以下例子)
foreign key(classno) references t_class(cno)
什么是外键
若有两个表A、B,id是A的主键,而B中也有id字段,则id就是表B的外键,外键约束主要用来维护两个表之间数据的一致性。
A为基本表,B为信息表
1、外键涉及到的术语
外键约束
外键字段
外键值
2、外键约束、外键字段、外键值之间的关系
某个字段添加外键约束之后,该字段称为外键字段,外键字段中每个数据都是外键值
3、按外键约束的字段数量分类
单一外键:给一个字段添加外键约束
复合外键:给多个字段联合添加一个外键约束
4、一张表可以有多个外键字段(与主键不同)
5、分析场景
设计数据库表,用来存储学生和班级信息
两种方案
方案一:将学生信息和班级信息存储到一张表
sno sname classno cname
1 jay 100 浙江省第一中学高三1班
2 lucy 100 浙江省第一中学高三1班
3 king 200 浙江省第一中学高三2班
缺点:数据冗余,比如cname字段的数据重复太多
方案二:将学生信息和班级信息分开两张表存储
学生表(添加单一外键)
sno(pk) sname classno(fk)
1 jack 100
2 lucy 100
3 king 200
班级表
cno(pk) cname
100 浙江省第一中学高三1班
200 浙江省第一中学高三2班
结论
为了保证学生表中的classno字段中的数据必须来自于班级表中的cno字段中的数据,有必要给学生表中的classno字段添加外键约束
注意点
外键值可以为null
外键字段去引用一张表的某个字段的时候,被引用的字段必须具有unique约束
有了外键引用之后,表分为父表和子表
班级表:父表
学生表:子表
创建先创建父表
删除先删除子表数据
插入先插入父表数据
存储学生班级信息
mysql> drop table if exists t_student;
mysql> drop table if exists t_class; mysql> create table t_class(
-> cno int(10) primary key,
-> cname varchar(128) not null unique
-> ); mysql> create table t_student(
-> sno int(10) primary key auto_increment,
-> sname varchar(32) not null,
-> classno int(3),
-> foreign key(classno) references t_class(cno)
-> ); mysql> insert into t_class(cno,cname) values(100,'aaaaaaxxxxxx');
mysql> insert into t_class(cno,cname) values(200,'oooooopppppp');
mysql> insert into t_student(sname,classno) values('jack',100);
mysql> insert into t_student(sname,classno) values('lucy',100);
mysql> insert into t_student(sname,classno) values('king',200);
班级表t_class
mysql> select * from t_class;
+-----+--------------+
| cno | cname |
+-----+--------------+
| 100 | aaaaaaxxxxxx |
| 200 | oooooopppppp |
+-----+--------------+
学生表t_student
mysql> select * from t_student;
+-----+-------+---------+
| sno | sname | classno |
+-----+-------+---------+
| 1 | jack | 100 |
| 2 | lucy | 100 |
| 3 | king | 200 |
+-----+-------+---------+
上表中找出每个学生的班级名称
mysql> select s.*,c.* from t_student s join t_class c on s.classno=c.cno;
+-----+-------+---------+-----+--------------+
| sno | sname | classno | cno | cname |
+-----+-------+---------+-----+--------------+
| 1 | jack | 100 | 100 | aaaaaaxxxxxx |
| 2 | lucy | 100 | 100 | aaaaaaxxxxxx |
| 3 | king | 200 | 200 | oooooopppppp |
+-----+-------+---------+-----+--------------+
结论
以上是典型的一对多的设计:在多个地方加外键(子表加外键)
原文:https://blog.csdn.net/w_linux/article/details/79655073
MySQL——约束(constraint)详解的更多相关文章
- Oracle约束(Constraint)详解
概述 约束是数据库用来确保数据满足业务规则的手段,不过在真正的企业开发中,除了主键约束这类具有强需求的约束,像外键约束,检查约束更多时候仅仅出现在数据库设计阶段,真实环境却很少应用,更多是放到程序逻辑 ...
- Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock)
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- Mysql加锁过程详解(1)-基本知识
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- Mysql加锁过程详解(5)-innodb 多版本并发控制原理详解
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- 如何查看mysql数据库的引擎/MySQL数据库引擎详解
一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mys ...
- MySQL 联合索引详解
MySQL 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...
- MySQL关闭过程详解和安全关闭MySQL的方法
MySQL关闭过程详解和安全关闭MySQL的方法 www.hongkevip.com 时间: -- : 阅读: 整理: 红客VIP 分享到: 红客VIP(http://www.hongkevip.co ...
- 【转】Nginx+php-fpm+MySQL分离部署详解
转:http://www.linuxidc.com/Linux/2015-07/120580.htm Nginx+php-fpm+MySQL分离部署详解 [日期:2015-07-26] 来源:Linu ...
随机推荐
- UltraEdit 换行替换
需求:想在每行结尾添加 '), 方案:在查找栏填写(^r^n) 替换栏('),^r^n) 效果:
- centos7装机教程
U盘启动电脑进入安装界面 正常情况下你应该会看到下面的这个界面: 选择第一项,然后按TAB键,然后会看到下面这个: 3.修改第二步中按TAB键出来的命令 将命令修改为:>vmlinuz init ...
- BZOJ1941:[SDOI2010]Hide and Seek(K-D Tree)
Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏- ...
- numpy 的排序
import numpy as np # 1.快速排序 ''' 1.np.sort(),不改变原先值的顺序,但是在运行时占内存 2.ndarry.sort(),改变原先值的顺序,不占用内存 ''' # ...
- 《阿里巴巴 Java 开发手册》划重点!
[强制]小数类型为 decimal,禁止使用 float 和 double. 说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不 正确的结果.如果存储的数 ...
- 3.3 线程---Handler消息传递机制浅析
Handler的执行流程图: 当我们的子线程想修改Activity中的UI组件时,我们可以新建一个Handler对象,通过这个对象向主线程发送信息;而我们发送的信息会先到主线程的MessageQueu ...
- mysql row日志格式下 查看binlog sql语句
有时候我们需要使用row作为binlog的日志格式,即配置文件使用了binlog_format= row 参数 这样以来,我们在查看数据库binlog内容时候,就看不到增删改查的具体语句了,在数据库恢 ...
- Python2.7-hashlib
hashlib模块,实现了支持多种不同哈希算法的接口,不同 hash 算法的构造函数就是算法名,返回的哈希对象都具有相同接口.哈希算法不是加密算法,所以下面提到的加密不是真的加密,因为真的加密需要能够 ...
- css 常用单位
em: 相对于应用在当前元素的字体尺寸,1em 等于当前的字体尺寸,2em 等于当前字体尺寸的两倍,一般浏览器字体大小默认为16px,则2em == 32px: W3原文:font size of t ...
- Android 关于在ScrollView中加上一个ListView,ListView内容显示不完全(总是显示第一项)的问题的两种简单的解决方案
是这样的哈: 有这样一个需求: 1.显示一个界面,界面上有一个列表(ListView),列表上面有一个可以滚动的海报. 2.要求在ListView滚动的过程中,ListView上面的海报也可以跟着Li ...