MySQL约束条件

约束条件

无符号

unsigned  加在字段类型的后面
	可以取消正负号

零填充

zerofill 
	用零填充
    id int(5) zerofill

非空

 输入的值不能为空  "not null"
 	create table t3(
        id int not null,
        name varchar(32)
    );
  insert into t3(name) values('tank');
#    Field 'id' doesn't have a default value     字段` id `没有默认值
  insert into t3(id) values(1);
+----+------+
| id | name |
+----+------+
|  1 | NULL |
+----+------+
name 为Null 就是空,得知如果不加以限制默认是空
-----------------------------------------------------------------------------------
我们查看该表信息
desc t3;   
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   |     | NULL    |       |
| name  | varchar(32) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
可以看到该表的id的Null显示NO  就是不可以为空

默认值

"default "
create table t1(
	id int default 6,
	name varchar default 'tank');
insert into t1(id) values(1);
insert into t1(name) values('lxj');
insert into t1 values(2,'baba');
+------+------+
| id   | name |
+------+------+
|    1 | tank |
|    6 | lxj  |
|    2 | baba |
+------+------+
可以看出 没有输入的值则会默认使用我们设定的默认值
查看该表信息
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | 6       |       |
| name  | varchar(32) | YES  |     | tank    |       |
+-------+-------------+------+-----+---------+-------+
default 下的默认值从null变成了我们设置的值

唯一值

"单列唯一  unique "
"顾名思义 用该约束条件设置的字段 的数据只能是唯一,不能重复。"
create table t1(
	id int unique,
	name varchar(32) unique);
insert into t1 values(1,'jason');
insert into t1 values(1,'tank');
# 对于键'id',重复条目'1'
+------+------+
| id   | name |
+------+------+
|    1 | tank |
+------+------+
查看 表信息
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  | UNI | NULL    |       |
| name  | varchar(32) | YES  | UNI | NULL    |       |
+-------+-------------+------+-----+---------+-------+
key 下 UNI 唯一
====================================================================================
"""多列唯一
 对于使用约束条件unique 的字段组合在一起的结果 不能重复 """
create table t1(
    id int,
    name varchar(32),
    ip varchar(32),
    port int,
    unique(ip,port));  # ip与端口号 组合 约束
 insert into t1 values(1,'tank','192.168.1.88',1433);
 insert into t1 vaalues(2,'jack','192.168.1.88',1433);
 # 报错 
 insert into t1 values(2,'jack','192.168.1.87',1433);
+------+------+--------------+------+
| id   | name | ip           | port |
+------+------+--------------+------+
|    1 | tank | 192.168.1.88 | 1433 |
|    2 | jack | 192.168.1.87 | 1433 |
+------+------+--------------+------+
查看表信息
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(32) | YES  |     | NULL    |       |
| ip    | varchar(32) | YES  | MUL | NULL    |       |
| port  | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
  key 下 MUL 多列唯一

*主键

primary key
	1.但从约束层面上讲 主键相当于not null + unique 非空且唯一
create table t1(
	id int primary key,
  	name varchar(32));
查看表信息
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   | PRI | NULL    |       |
| name  | varchar(32) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
null 为NO 非空, PRI 主键必须是唯一。
====================================================================================
2.是InnoDB存储引擎规定的一张表有且必须要有一个主键
  	(主键是组织数据的重要条件并且主键可以加快数据的查询速度)
  	  	如果创建表创建的时候没有设置主键也没有其他的键 InnoDB会采用一个隐藏的字段作为表的主键 隐藏意味着无法使用 基于该表的数据查询只能一行行查找 速度很慢
  	如果没有主键但是有非空且唯一的字段 那么会自动升级成主键(从上往下的第一个)
	create table t1(
    	id int,
    	name varchar(32) not null unique,
       phone bigint not null unique
    );
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(32) | NO   | PRI | NULL    |       |
| phone | bigint(20)  | NO   | UNI | NULL    |       |
+-------+-------------+------+-----+---------+-------+
可以看出 name 被升级成了主键

自增

auto_increment
该约束条件配合主键一起使用,不能单独出现。一张表只能出现一次
create table t1(
	id int primary key auto_increment,
	name varchar(32));
insert into t1(name) values('jack');
insert into t1(name) values('tank');
insert into t1(name) values('jerry');
+----+-------+
| id | name  |
+----+-------+
|  1 | jack  |
|  2 | tank  |
|  3 | jerry |
+----+-------+
我们并没有添加id 数据,可以看出 id 是自增的
查看表数据
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(32) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
可以看到 id 后的 Extra属性 auto_increment
'''
 自增不会随着数据的删除而后退,只会从原来在哪就直接在哪开始增加 ,可以手动增加 但是没啥用下次还会从原来的地方开始增加
 如果想重置某张表的主键值 可以使用
		truncate t1;  清空表数据并重置主键
		等于格式化了这个表数据全没了
'''
delete from t1 where id=3;
+----+------+
| id | name |
+----+------+
|  1 | jack |
|  2 | tank |
+----+------+
insert into t1(name) values('zyg');
+----+------+
| id | name |
+----+------+
|  1 | jack |
|  2 | tank |
|  4 | zyg  |
+----+------+
可以看出 并没有按照2开始自增而是从我们删除的3开始自增。

外键简介

外键字段就是用来记录表与表之间的数据的关系
# 外键前戏
  创建一个员工表
 id  name   age  dep_name  dep_desc
  1  owen    20    外交部    搞外交
  2  tom     19    教育部    教学
  3  avin    21    外交部    搞外交
  4  Gavin   24    教育部    教学

# 表格缺陷
  1、表的重点不清晰
    因为这是员工表,你也可以说这是部门表
  2、表中的部门名和职责的数据都一直在重复
    浪费存储空间
  3、表的扩展性极差

# 解决措施
  将表格分为两个
 员工表
id   name    age
  部门表
id   dep_name  dep_desc
# 解决了上面的三个问题,但是有一个致命问题,部门和员工的关系怎么绑定
  措施:
    在员工表中增加一个部门编号字段与部门表中的主键字段对应
 """
   这个字段就是外键字段
     外键字段就是用来记录表与表之间的数据的关系
 """

关系的判断

# 关系种类
 1、一对多
 2、多对多
 3、一对一
 4、没有关系
"""
  关系的判断四字口诀: 换位思考
"""

一对多关系

# 一对多时
1、以员工表与部门表为例
  员工表角度:
       一个员工可以对应多个部门
       不能(比较现实,总不能一个人好几个部门职位)
  部门表角度:
      一个部门能否对应多个员工
       可以
    
 所以关系是"一对多" 部门是"一" 员工为"多"
'''
 关系表达也只能是一对多, 不能用多对一
'''
一对多的关系中,外键字段在"多"的一方

建立外键字段

考虑:
    当我们在建立表时 关联表里有被关联表的主键编号,此时我们在创建的时候就会报错因为含有不存在的数据,因此我们在建立外键字段的时候要遵循:
    1.创建表的时候一定要先创建被关联表(没有外键字段的表)
    2.录入表数据时一定要先录录被关联表(没有外键字段的表)

外键SQL代码

'''
 当表中有外键字段,那么就先编写普通字段,最后在考虑外键字段
'''
create table emp(
	id int primary key auto_increment,
	name varchar(32),
	age int,
	dep_id int,
	foreign key(dep_id) references dep(id)
);

create table dep(
	id int primary key auto_increment,
	dep_name varchar(32),
	dep_desc varchar(64));
# 先给被关联表建立部门
insert into dep(dep_name,dep_desc) values('总装备部','研究装备'),('总政治部','政治委员'),('总参谋部','作战参谋'),('总后勤部','配发物资');
# 再给含有外键字段表增加信息
insert into emp(name,age,dep_id) values('李晓健',18,1),('张洋',19,1),('徐豹',18,1),('坦克',21,2),('破军',23,3),('蛤蟆',19,4);

image

修改、删除被关联表数据都会出现障碍
 update dep set id=200 where id=2;
delect from dep where id=2;

image

针对修改删除做了优化
 诞生了  级联更新  on update cascade
       级联删除  on delete cascade

        create table emp1(id int primary key auto_increment,
             name varchar(32),
             age int,
             dep_id int,
             foreign key(dep_id) references dep1(id)
             on update cascade
             on delete cascade);

        create table dep1(id int primary key auto_increment,
             dep_name vachar(32),
             dep_desc vachar(64));

image

多对多关系

以图书馆为例
 1.站在图书馆里的书籍表的立场
     一本书是否可以对应对个作者
      可以
 2. 站在作者的立场
	一个作者是否可以对应多本书
    可以
  结论 两个都可以 就是多对多
"""
    我们设想 多对多里数据表与作者表里都有外键字段,那么我们肯定是创建不了的,怎么解决呢
解决方法:新建第三个表 关系表"""	

代码

# 建立书籍表
create table book(
    id int primary key auto_increment,
     title varchar(32),
     price float(5,3));
# 建立作者表
create table author(
	id int primary key auto_increment,
	name varchar(32),
	phone bigint);
#建立关系表
create table book_author(
	id int primary key auto_increment,
	author_id int,
	book_id, int,
	foreign key(author_id) references author(id)
	on update cascade
   on delete cascade,
	foreign key(book_id) references book(id)
   	on update cascade
    on delete cascade
    );
# 给书籍表添加数据
insert into book(title,price) values('极品公子',20),('雪中悍刀行',30),('完美世界',30),('神墓',30),('遮天',30);
# 给作者表添加数据
insert into author(name,phone) values('烽火戏诸侯',110),('辰东',120);
# 给关系表绑定关系
insert into book_author(author_id,book_id) values(1,1),(1,2),(2,3),(2,4),(2,5);

经测试发现自身问题:
1. 删除作者时 关系内关联该作者关系全被删除,但是书籍表没有影响。
2. 删除书籍时 关系内关联该书籍的关系全被删除,但是作者表没有影响。
结论: 
我们在操作被关联表(书籍表)时只能影响到关联表内与之相关的数据  
"因为关系表与它建立了外键"
我们在操作关系表的时候并不能影响到书籍表与作者表
"因为书籍表或作者表并没有外键字段"
意思就是 删除数据只能影响到与含有他外键字段的表

image

一对一关系

# 针对用户信息表,里面的数据可以分为两类
1、热数据:
  经常使用的数据: 电话、姓名、年龄
2、冷数据:
  不经常使用的数据: 出生日期、家庭地址、政治面貌
为了降低资源并 降低数据库压力,将表一分为二
1、用户表
  存使用频率较高的数据字段
2、用户详情表
  存使用频率较低的数据字段
    
# 表与表之间的关系
1、用户表角度
   一个用户数据能否对应多个用户详情数据
   肯定是不能的
2、用户详情表
   一个用户详情数据能否对应多个用户表
   也肯定是不能的
# 两边都不可以,所以有两种可能 
'没有关系'
'一对一的关系'
那肯定是后者  ,那么一对一关系外键字段建在任意一方都可以,推荐建在使用查询频率比较高的一方

代码

create table user1(id int primary key auto_increment,
             name varchar(32),
             age int,
             phone bigint,
             details_id int unique,  # 详细表的编号必须为独一无二
             foreign key(details_id) references details(id)
             on update cascade
             on delete cascade); 
create table details(id int primary key auto_increment,
               birth varchar(32),
               family varchar(64));


image

posted @ 2022-11-24 20:40  李阿鸡  阅读(69)  评论(0编辑  收藏  举报
Title