疫情环境下的网络学习笔记 python 5.5 MYSql 表关系,外键

5.5

昨日回顾

  • 存储引擎

    show engines

  • 创建表的完整语法

    create table t1(
    	name char(4) not null,
    	id int
    )
    
  • 严格模式:使用数据库的时候尽量让数据库少干活

  • 基本数据类型

    • 整型:tinyint,int,bigint,默认都有符号

    • 浮点型:float,double,decimal

      精确度 float < double < decimal

    • 字符类型

      char定长,varchar变长

    • 日期

    • 枚举与集合

今日内容

重要

  1. 约束条件
  2. 表与表之间建立关系(约束)
  3. 修改表的语法
  4. 复制表
  5. 作业:如何判断表关系及建立表关系

约束条件

default 默认值

# 插入数据的时候指定字段
create table t1(id int, name char(8));
insert into t1(name,id) values('aaa',2020);

# 创建表的时候给字段设置默认值
create table t2(id int, name char(8), gender enum('male','female') default 'male');
# 字段类型后面不加逗号,跟默认值

insert into t2(id,name) values(2021,'bbb');
# 这样,默认的gender就是male

unique 唯一

# 单列唯一
create table t3(id int unique, name char(8));

insert into t3 values(1, 'aaa'),(1, 'bbb');
# 报错,显示 id 字段唯一
insert into t3 values(1, 'ccc'),(2, 'ddd');
# 正常添加
# 联合唯一
# 例,ip和端口,单个可以重复,但是加载到以前必须是唯一的
create table t4(
	id int,
	ip char(16),
	port int,
	unique(ip,port)
);
# 在最后,用unique加括号,把联合唯一的字段放进去

insert into t4 values(1, '127.0.0.1', 8080);
insert into t4 values(2, '127.0.0.1', 8081);
insert into t4 values(3, '127.0.0.2', 8080);
# 正常执行
insert into t4 values(4, '127.0.0.1', 8080);
# 报错,ip和端口都与 1 重复

primary key 主键

重要

单从约束效果来看,等价于 not null + unique

# 创建表,id为主键
create table t3(id int primary key);
insert into t5 values(1),(1);
insert into t5 values(null);
# 报错
insert into t5 values(1),(2);
# 正常创建

除了有约束效果以外,他还是innodb存储引擎组织数据的依据,innodb创建表的时候必须要有primary key

类似于书的目录,能够帮助提示查询效率,并且是建表的依据

那之前没有用主键是怎么建表的呢?

  1. 一张表有且只有一个主键,如果没有设置主键,那么回从上往下搜索直到遇到一个非空且唯一的字段,自动将其升级为主键
  2. 如果表中没有主键也没有其他任何的非空且唯一字段,那么innodb会采用自己内部提供的一个隐藏字段作为主键。这个隐藏的字段我们无法使用
  3. 通常一张表应该有一个主键字段,通常叫做id

联合主键:了解

create table t6(
	ip char(16),
	port int,
	primary key(ip,port)
);

以后创建表,都必须给id加上主键

auto_increment 自增

当编号特别多的时候,设置每次新增数据,id自动+1

create table t8(
	id int rimary key auto_increment,
	name char(16)
);
# 创建表,id自增

insert into1 t8(name) vlues('aaa'),('bbb'),('ccc');
# 插入后查看,既有name,又有id
# auto_increment 通常都是加在主键上的,编号序号一类,不能给普通字段加

这个约束条件内部有一个计数器,就算delete from 把数据删掉了,主键的自增序号也不会删除,而是会从当前计数再往下自增

delete from t8; # 删除表中数据,没有删除自增序号
truncate t8; # 清空表数据,并重置自增计数

表与表间建立关系

对普通的表进行拆分,将拆分的表建立联系

表与表之间的关系

# 表与表之间最多只有4种关系
# 1. 一对多关系
# 2. 多对多关系
# 3. 一对一关系

# 在确定表关系的时候要换位思考:在两边的表考虑是对应一个或多个
# 一个部门有多个员工,一个员工只属于一个部门:单向的一对多关系

外键:用来帮助我们建立表与表之间关系的字段:foreign key

一对多关系

foreign key

# 建部门表
create table dep(
	id int promary key auto_increment,
	dep_name char(16)
);

# 建员工表
create table emp(
	id int promary key auto_increment,
	emp_name char(16),
	gender enum('male','female') default 'male'
	dep_id int,
    foreign key(dep_id) references dep(id)
    # 本表的dep_id字段是外键字段,与dep表的id有联系
);

# 先插入部门数据
insert into dep(dep_name) values('外交部'),('技术部');
# 插入员工数据
insert into emp(emp_name, dep_id) values('aaa',1),('bbb',2);

foreign key 规范

  1. 一对多关系表,外键字段建在 的一边
  2. 在创建表的时候要先建被关联表
  3. 在录入数据的时候必须先录入被关联表
  4. 当约束存在,想要修改被关联的表,不能直接操作,要想实现同步删除或更新,另外声明

修改被关联表

on update cascade

# 1. 先修改关联的数据,再修改被关联的数据:操作太频繁,不用
# 2. 真正做到表间有关系:更新就同部更新,删除就同部删除
# 级联更新,级联删除(同部):在创建表的时候需要声明额外的参数
create table emp(
	id int promary key auto_increment,
	emp_name char(16),
	gender enum('male','female') default 'male'
	dep_id int,
	foreign key(dep_id) references dep(id)
	on update cascade # 同部更新
	on delete cascade # 同步删除
);

# 修改dep表,id变成200
update dep set id=200 where id=2;
select* from dep
select* from emp
# 此时查看emp表,关联了id=2的数据id也变成200了。如果删除id=200,那么员工表关联id=200的也被删除

多对多关系

例:书籍与作者,一本书有多个作者,一个作者不止写一本书,多对多关系

# 创建书籍表
create table book(
	id int promary key auto_increment,
	title varcahr(32),
	price int
);

# 创建作者表
create table author(
	id int promary key auto_increment,
	name varchar(32),
	book_id int,
)
# 创建关系连接表
create table book2author(
	id int promary key auto_increment,
	author_id int,
	book_id int,
	foreign key(author_id) references author(id)
	on update cascade
	on delete cascade,
	# 作者id
	foreign key(book_id) references book(id)
	on update cascade
	on delete cascade
    # 书本id
)

# 按照一对多的思想建表,谁都别想建成,对于这种场景,应该另外建一张表 book2author,专门存储表之间的关系
# 作者与关系表表和书与关系表book2author都是一对多的关系
#

一对一关系

用户独有的属性:昵称,年龄,email;一个用户只能对应一个昵称,一个年龄,同一昵称只对用一个用户:一对一关系

一对一关系外键,建在哪里都可以不过推荐建在查询频率比较高的表中

create table authordetail(
	id int primary key auto_increment,
    phone int,
    addr varchar(64)
);
create table author(
	id int primary key auto_increment,
    name varchar(32),
    age int,
    authordetail_id int unique,
    foreign key(authordetail_id) references authordetail(id) 
    on update cascade  # 同步更新
    on delete cascade  # 同步删除
)

总结

  • 表关系的建立要用到 foreign key
    • 一对多:外键字段建在多的一方
    • 多对多:开设另外一张关系表
    • 一对一:建立在任意以访,推荐建在查询频率高的表中
  • 判断表之间关系的方式:换位思考

修改表

MYSQL不区分大小写

# 1. 修改表名
alter table 表名 rename 新表名;

# 2. 增加字段
alter table 表明 add 字段名 字段类型(宽度) 约束条件; # 默认在最后面添加
alter table 表明 add 字段名 字段类型(宽度) 约束条件 first; # 添加到最前面
alter table 表明 add 字段名 字段类型(宽度) 约束条件 last; # 添加在最后面;

# 3. 删除字段
alter table 表名 drop 字段名;

# 4. 修改字段属性
alter table 表名 modify 字段名 字段类型(宽度) 约束条件;

# 修改字段名
alter table 表名 change 旧字段名 新字段名 字段类型(宽度) 约束条件;

复制表

MYSQL每次查询得到的结果也是一张表:内存中的一张虚拟表

# 1.
create table new_table select * from t1;
# create table 新表名 select * from 旧表名;
# 这样只能复制了表的结构和数据,但是不能复制主键外键索引一类属性
# 如果复制的约束条件结果中没有数据,得到一个没有数据的空表
原文地址:https://www.cnblogs.com/telecasterfanclub/p/12830240.html