完整性约束

关键字:
  not null 与 default
  unique
  primary
  auto_increment
  foreign key

1、介绍

约束条件与数据类型的宽度一样,都是可选参数
作用:用于保证数据的完整性和一致性

主要分为:
PRIMARY KEY (PK)    #标识该字段为该表的主键,可以唯一的标识记录
FOREIGN KEY (FK)    #标识该字段为该表的外键
NOT NULL           #标识该字段不能为空
UNIQUE KEY (UK)      #标识该字段的值是唯一的
AUTO_INCREMENT   #标识该字段的值自动增长(整数类型,而且为主键)
DEFAULT          #为该字段设置默认值
UNSIGNED       #无符号
ZEROFILL        #使用0填充

说明:
#1. 是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值

#2. 字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值
sex enum('male','female') not null default 'male'
#必须为正值(无符号) 不允许为空 默认是20
age int unsigned NOT NULL default 20

# 3. 是否是key
主键 primary key
外键 foreign key
索引 (index,unique...)

2、not null 与default

是否可空,null表示空,非字符串
not null - 不可空
null - 可空(默认)

默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值

create table tb1(
id int not null defalut 2,
num int not null
);

3、unique

3.1、单列唯一

举例说明:创建公司部门表(每个公司都有唯一的一个部门)。
使用约束条件unique,来对公司部门的字段进行设置。

#第一种创建unique的方式

#例子1:插入的值不唯一时会报错无法插入
create table department(
id int,
name char(10) unique
);
mysql> insert into department values(1,'it'),(2,'it');
ERROR 1062 (23000): Duplicate entry 'it' for key 'name' #例子2:
create table department(
id int unique,
name char(10) unique
);
insert into department values(1,'it'),(2,'sale'); #第二种创建unique的方式
create table department(
id int,
name char(10) ,
unique(id),
unique(name)
);
insert into department values(1,'it'),(2,'sale');

3.2、联合唯一

只要两列记录,有一列不同,既符合联合唯一的约束

# 创建services表
mysql> create table services(
id int,
ip char(15),
port int,
unique(id),
unique(ip,port)
);
Query OK, 0 rows affected (0.05 sec) mysql> desc services;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | UNI | NULL | |
| ip | char(15) | YES | MUL | NULL | |
| port | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec) mysql> insert into services values
(1,'192,168,11,23',80),
(2,'192,168,11,23',81),
(3,'192,168,11,25',80);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from services;
+------+---------------+------+
| id | ip | port |
+------+---------------+------+
| 1 | 192,168,11,23 | 80 |
| 2 | 192,168,11,23 | 81 |
| 3 | 192,168,11,25 | 80 |
+------+---------------+------+
3 rows in set (0.00 sec) mysql> insert into services values (4,'192,168,11,23',80);
ERROR 1062 (23000): Duplicate entry '192,168,11,23-80' for key 'ip'

4、primary key

在MySQL的一个表中只有唯一的一个主键,不能有多列主键,但可以有复合主键

一个表中可以:
单列做主键
多列做主键(复合主键)

约束:等价于 not null unique,字段的值不为空且唯一

存储引擎默认是(innodb):对于innodb存储引擎来说,一张表必须有一个主键。

4.1、单列主键

# 创建t1表,为id字段设置主键,唯一的不同的记录
create table t1(
id int primary key,
name char(16)
); insert into t14 values
(1,'xiaoming'),
(2,'xiaohong'); mysql> insert into t1 values(2,'wxxx');
ERROR 1062 (23000): Duplicate entry '' for key 'PRIMARY' mysql> desc t1;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(16) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.02 sec)

4.2、复合主键

限制ip和port为复合主键,两个值不能同时相同,只要有一个不相同即可

create table t1(
ip char(15),
port int,
primary key(ip,port)
); mysql> desc t1;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| ip | char(15) | NO | PRI | | |
| port | int(11) | NO | PRI | 0 | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.01 sec) insert into t1 values ('1.1.1.1',80);
insert into t1 values ('1.1.1.1',82);
insert into t1 values ('1.1.1.2',80); mysql> select * from t1;
+---------+------+
| ip | port |
+---------+------+
| 1.1.1.1 | 80 |
| 1.1.1.1 | 82 |
| 1.1.1.2 | 80 |
+---------+------+

可以看出第1个和第2个ip相同,但port不同
第1个和第3个port相同,但是ip不同,这两种情况都是可以插入的

5、auto_increment

约束:约束的字段为自动增长,约束的字段必须同时被key约束

# 创建student
create table student(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male'
); mysql> desc student;
+-------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL |auto_increment|
| name | varchar(20) | YES | | NULL | |
| sex | enum('male','female') | YES | | male | |
+-------+-----------------------+------+-----+---------+----------------+
3 rows in set (0.17 sec) #插入记录,不指定id时,默认id从1开始自增1
mysql> insert into student(name) values ('老白'),('小白');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from student;
+----+--------+------+
| id | name | sex |
+----+--------+------+
| 1 | 老白 | male |
| 2 | 小白 | male |
+----+--------+------+
2 rows in set (0.00 sec) #指定id时,以指定的id为准
mysql> insert into student values(4,'asb','female');
Query OK, 1 row affected (0.00 sec) mysql> insert into student values(7,'wsb','female');
Query OK, 1 row affected (0.01 sec) mysql> select * from student;
+----+--------+--------+
| id | name | sex |
+----+--------+--------+
| 1 | 老白 | male |
| 2 | 小白 | male |
| 4 | asb | female |
| 7 | wsb | female |
+----+--------+--------+
4 rows in set (0.00 sec) # 再次插入一条不指定id的记录,会在之前的最后一条记录继续增长
mysql> insert into student(name) values ('大白');
Query OK, 1 row affected (0.00 sec) mysql> select * from student;
+----+--------+--------+
| id | name | sex |
+----+--------+--------+
| 1 | 老白 | male |
| 2 | 小白 | male |
| 4 | asb | female |
| 7 | wsb | female |
| 8 | 大白 | male |
+----+--------+--------+
5 rows in set (0.00 sec)

对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长

清空表区分delete和truncate的区别:

delete from t1; #如果有自增id,新增的数据,仍然是以删除前的最后一样作为起始。
truncate table t1;数据量大,删除速度比上一条快,且直接从零开始。

6、foreign key

之前创建表的时候都是在一张表中添加记录,比如如下表:

如果员工数量非常多时,在添加部门信息时会存在大量的重复数据,占用空间
这时,我们需要创建两张表,一张表保存员工信息,另一张表保存部门信息,然后将这两张表关联起来即可。

此时有两张表,一张是employee表,简称emp表(关联表,也叫从表)。一张是department表,简称dep表(被关联表,也叫主表)。

创建两张表操作:

1.创建表时先创建被关联表(主表),再创建关联表(从表)

# 先创建被关联表(dep表)
create table dep(
id int primary key,
name varchar(20) not null,
descripe varchar(20) not null
); #再创建关联表(emp表)
create table emp(
id int primary key,
name varchar(20) not null,
age int not null,
dep_id int,
constraint fk_dep foreign key(dep_id) references dep(id)
);

2.插入记录时,先往被关联表中(主表)插入记录,再往关联表(从表)中插入记录

insert into dep values
(1,'IT'),
(2,'销售部'),
(3,'财务部'); insert into emp values
(1,'tom',21,1),
(2,'mike',22,1),
(3,'jack',23,2),
(4,'lucy',24,3),
(5,'alice',25,2);

3.删除表
#按道理来说,删除了部门表中的某个部门,员工表的有关联的记录相继删除。

mysql> delete from dep where id=3;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db5`.`emp`, CONSTRAINT `fk_name` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`))

发现当主表中的值被从表关联时,不允许删除主表中的内容
但是先删除员工表的记录之后,再删除当前部门就没有任何问题

同步删除,同步更新
这样删除表记录的操作比较繁琐,按道理讲,裁掉一个部门,该部门的员工也会被裁掉。其实呢,在建表的时候还有个很重要的内容,叫同步删除,同步更新

重复上面的操作建表
注意:在关联表中加入
on delete cascade #同步删除
on update cascade #同步更新

修改emp表:

create table emp(
id int primary key,
name varchar(20) not null,
age int not null,
dep_id int,
constraint fk_dep foreign key(dep_id) references dep(id)
on delete cascade #同步删除
on update cascade #同步更新
);

接下来的操作,就符合我们正常的生活中的情况了。
再去删被关联表(dep)的记录,关联表(emp)中的记录也跟着删除

mysql> delete from dep where id=3;
Query OK, 1 row affected (0.00 sec) mysql> select * from dep;
+----+-----------+
| id | name |
+----+-----------+
| 1 | IT |
| 2 | 销售部 |
+----+-----------+
2 rows in set (0.00 sec) mysql> select * from emp;
+----+----------+-----+--------+
| id | name | age | dep_id |
+----+----------+-----+--------+
| 1 | tom | 21 | 1 |
| 2 | mike | 22 | 1 |
| 3 | jack | 23 | 2 |
| 5 | alice | 25 | 2 |
+----+----------+-----+--------+
4 rows in set (0.00 sec)

再去更改被关联表(dep)的记录,关联表(emp)中的记录也跟着更改

mysql> update dep set id=222 where id=2;

查看一下两张表是否都被删除了,是否都被更改了

mysql> select * from dep;
+-----+-----------+----------------------+
| id | name | descripe |
+-----+-----------+----------------------+
| 1 | IT | IT技术有限部门 |
| 222 | 销售部 | 销售部门 |
+-----+-----------+----------------------+ mysql> select * from emp;
+----+----------+-----+--------+
| id | name | age | dep_id |
+----+----------+-----+--------+
| 1 | tom | 21 | 1 |
| 2 | mike | 22 | 1 |
| 3 | jack | 23 | 222 |
| 5 | alice | 25 | 222 |
+----+----------+-----+--------+

day04-完整性约束的更多相关文章

  1. mysql 完整性约束

    mysql 完整性约束 数据的完整性概述根据完整性实施的方法将完整性约束分为四类:1.实体完整性 实体完整性的实现:通过在表中设置主键约束.唯一约束或标识列来实现 主键约束:应用于表列的一个约束 用法 ...

  2. SQL基础--完整性约束

    完整性约束是保证用户所做的修改不会破坏数据的一致性,是保护数据正确性和相容性的一种手段. 常见的5种约束: NOT NULL           非空约束C     指定的列不允许为空值 UNIQUE ...

  3. Spring day04笔记(SVN讲解和回顾昨天知识)

    spring day03回顾 事务管理 基于xml配置 1.配置事务管理器 jdbc:DataSourceTransactionManager hibernate:HibernateTransacti ...

  4. sql server 2008 数据库的完整性约束

    一.数据库完整性概述   1.数据库的完整性:   ①数据库的完整性是指数据的正确性和相容性 ②数据库完整性是防止不合语义或不正确的数据进入数据库 ③完整性体现了是否真实地反映现实世界   例:  学 ...

  5. SQL复习四(完整性约束)

    完整性约束是为了表的数据的正确性.主要有主键,外键的约束. 1 主键 当某一列添加了主键约束后,该列的数据就不能重复出现.这样每行记录中其主键列就能唯一的标识着以行.如学生可以用学号作为唯一的标识. ...

  6. MySQL中的完整性约束

    对于已经创建好的表,虽然字段的数据类型决定所能存储的数据类型,但是表中所存储的数据是否合法并没有检查. MySQL支持的完整性约束: NOT NULL                 约束字段的值不能 ...

  7. MySQL:表的操作 知识点难点总结:表完整性约束及其他常用知识点二次总结🙄

    表操作 一 : 修改表表表表表表表表表: ALTER TABLE 语法 1. 改表名rename alter table 表名 rename 新表名 2. 增加字段add alter table 表名 ...

  8. day04 Java Web 开发入门

    day04 Java Web 开发入门 1. web 开发相关介绍 2. web 服务器 3. Tomcat服务器启动的问题 4. Tomcat目录结构 5. Web应用程序(虚拟目录映射,缺省web ...

  9. SQL Server 表的管理_关于完整性约束的详解(案例代码)

    SQL Server 表的管理之_关于完整性约束的详解 一.概述: ●约束是SQL Server提供的自动保持数据库完整性的一种方法, 它通过限制字段中数据.记录中数据和表之间的数据来保证数据的完整性 ...

  10. 存储引擎和表的操作(mysql中的数据类型、完整性约束)

    一.存储引擎 .概念 MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力. 通过选择不同的技术 ...

随机推荐

  1. java 1.8新特性(二) 关于 function 接口的使用

    需求1:从user集合中 找出age=15的用户  传统方法 就不说了 举例明一下 java1.8 使用Predicate接口解决该需求: @FunctionalInterface public in ...

  2. 服务网关zuul之三:zuul统一异常处理

    我们详细介绍了Spring Cloud Zuul中自己实现的一些核心过滤器,以及这些过滤器在请求生命周期中的不同作用.我们会发现在这些核心过滤器中并没有实现error阶段的过滤器.那么这些过滤器可以用 ...

  3. jquery中each()的三种遍历用法

    1.选择器+遍历 $('div').each(function (i){ i就是索引值 this 表示获取遍历每一个dom对象 }); 2.选择器+遍历 $('div').each(function  ...

  4. linux一些基本知识

    一.linux i386是32位的,amd64是64位(一般情况不限intel或者amd)       server是服务器版,desktop是桌面版 Desktop是社区开源版,拥有一些新功能新软件 ...

  5. [UE4]工程设置:自动捕获鼠标、通过代码设置鼠标显示隐藏、输入模式、编译时自动保存

    一.在4.20版本中运行游戏,在没有进行任何设置的情况下,游戏不会自动捕获鼠标,游戏不会接受输入,需要手动点一下游戏界面才行.如果要跟老版本一样运行游戏自动捕获鼠标,需要进行设置 二.也可以通过代码的 ...

  6. Spring AOP详解和实现方式

    一.什么是AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善. ...

  7. WordPress整站轻松开启HTTPS

    近两年来HTTPS取代HTTP已经成为大势所趋.早在2014年google Chromium安全团队提议将所有的HTTP协议网站标注为不安全.现在,Chrome浏览器已经开始执行这一标准了.从 Chr ...

  8. (转)C# WebApi 跨域问题解决方案:CORS

    原文地址:http://www.cnblogs.com/landeanfen/p/5177176.html 阅读目录 一.跨域问题的由来 二.跨域问题解决原理 三.跨域问题解决细节 1.场景描述 2. ...

  9. css实战——第一天

    1.  开发前的准备 1.1配置开发环境   sublime  webstorm  vscode  Hbuilder  atom 1.2建立项目文件夹 主页或是首页    index.html   d ...

  10. solr7.4 安装与使用

    1.solr7环境要求 solr7需要java8环境,且需要在环境变量中添加 JAVA_HOME变量. 2.solr 安装 下载地址 https://lucene.apache.org/solr/mi ...