一。一对多

  在数据库使用数据中经常遇到一对多的情况,以公司员工为例。

  一张完整的员工表有以下字段:

    id  name  gender  dep_name  dep_desc .

  以此建表得:

id        name        gender        dep_name        dep_desc
1 jason male 教学部 教书育人
2 egon male 外交部 漂泊游荡
3 tank male 教学部 教书育人
4 kevin male 教学部 教书育人
5 owen female 技术部 技术能力有限部门

  少数的数据看不出有多大的不合理,但是如果一个公司中频繁有教学部的出现,它和它的描述就要反复写一遍,这种感觉就像一个py文件写下了所有的代码,这本身就是不合理的,为了像模块一样封装代码,我们先将其分成2个表,再使用一对多的关系关联两表:

emp:
id name gender dep_id
1 jason male 1
2 egon male 2
3 tank male 2
4 kevin male 2
5 owen female 3
dep
id dep_name dep_desc
1 教学部 教书育人
2 外交部 漂泊游荡
3 教学部 教书育人
4 教学部 教书育人
5 技术部 技术能力有限部门

  两张表唯一有关系的是dep_id,所以要将dep_id设置成外键。

  设置外键是在表的创建阶段就完成的工作,一般的,我们把外键设置在一对多的多那个表中:

create table dep(
id int primary key auto_increment,
dep_name char(10),
dep_comment char(60)
); create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female') not null default 'male',
dep_id int,
foreign key(dep_id) references dep(id)
);

  在插入记录时,必须先插入被关联的表,也就是dep,在插入emp的数据。

  这样的表当dep中 的数据emp使用时,它的数据是不能被删除的,为了使得两者具有同步性,使用on delete cascade 修饰外键:

create table dep(
id int primary key auto_increment,
dep_name char(10),
dep_comment char(60)
); create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female') not null default 'male',
dep_id int,
foreign key(dep_id) references dep(id)
on update cascade
on delete cascade
);

  如图:

二。多对多

  除了一对多的概念以外,还有多对多,如图书和作者的关系。

  一个作者可以发布多个书。

  一个书可以有多个作者。

  于是根据上述的1对多推理出可以这样建立:

        create table book(
id int primary key auto_increment,
title varchar(32),
price int,
author_id int,
foreign key(author_id) references author(id)
on update cascade # 同步更新
on delete cascade # 同步删除 ); create table author(
id int primary key auto_increment,
name varchar(32),
age int,
book_id int,
foreign key(book_id) references book(id)
on update cascade # 同步更新
on delete cascade # 同步删除
);

  结果肯定是错的,建表book是让关联author,建表author时让关联book,两个谁都不能先建立肯定时不行的。

  所以需要第三张表,来记录它们之间的关系。

    create table book(
id int primary key auto_increment,
title varchar(32),
price int
);
create table author(
id int primary key auto_increment,
name varchar(32),
age int
);
create table book2author(
id int primary key auto_increment,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade,
author_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade
);

  如图:

三。一对一

  一对一的使用场景是当数据库特别庞大时,可以考虑分表。

  分表后使用一对一的关系将其连接起来。

  首先先建立被关联的表,再建立关联表,外键可以设置再任何地方,但一般设置在访问比较的的那个表。

create table authordetail1(
id int primary key auto_increment,
phone int,
addr char(255) );
create table author1(
id int primary key auto_increment,
name char(4),
age int,
authordetail_id int unique,
foreign key(authordetail_id) references authordetail1(id)
on update cascade
on delete cascade
);

四,表修改

# mysql对大小写不敏感!!!
语法:
1. 修改表名
ALTER TABLE 表名
RENAME 新表名;
2. 增加字段
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…],
ADD 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] FIRST;
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;
3. 删除字段
ALTER TABLE 表名
DROP 字段名;
4. 修改字段 # modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
ALTER TABLE 表名
MODIFY 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];

五。表复制

# 查询语句执行的结果也是一张表,可以看成虚拟表

# 复制表结构+记录 (key不会复制: 主键、外键和索引)
create table new_service select * from service; # 只复制表结构
select * from service where 1=2; //条件为假,查不到任何记录 create table new1_service select * from service where 1=2; create table t4 like employees;

day36_8_20数据库3外键的更多相关文章

  1. MySQL数据库建立外键失败的原因总结

    在MySQL数据库创建外键时,经常会发生一些错误,这是一件很令人头疼的事.一个典型的错误就是:Can’t create table... 的错误.在很多实例中,这种错误的发生都是因为mysql一直以来 ...

  2. MySQL数据库有外键约束时使用truncate命令的办法

    MySQL数据库操作中,Delete与Truncate两个命令都可以删除一个数据表中的全部数据,使用办法分别是: DELETE FROM t_question TRUNCATE TABLE t_que ...

  3. 使用Navicat V8.0创建数据库,外键出现错误ERROR 1005: Can’t create table (errno: 121)

    ERROR 1005: Can't create table (errno: 121) errno 121 means a duplicate key error. Probably the tabl ...

  4. mysql数据库导入外键约束问题

    在网站搬迁过程中,很重要一点是数据的迁移.你的数据库可能已经包含了一个设计良好的数据表集合,并且在网站运营过程中,产生了重要的数据.这时你必须做好包含数据表schema以及数据本身的迁移. 完成上述数 ...

  5. 数据库 SQL 外键约束 多表查询

    多表设计与多表查询 1.外键约束        表是用来保存现实生活中的数据的,而现实生活中数据和数据之间往往具有一定的关系,我们在使用表来存储数据时,可以明确的声明表和表之前的依赖关系,命令数据库来 ...

  6. 详解MariaDB数据库的外键约束

    1.什么是外键约束 外键约束(foreign key)就是表与表之间的某种约定的关系,由于这种关系的存在,我们能够让表与表之间的数据,更加的完整,关连性更强. 关于数据表的完整性和关连性,可以举个例子 ...

  7. django2.0变动数据库设置外键报错

    1.报错TypeError: __init__() missing 1 required positional argument: 'on_delete' django2.0以后创建数据库外键的时候必 ...

  8. flask对数据库的外键 主键

    近期一直在学flask框架,后悔当初没有好好学习数据库.一个外键的知识,真的是太....蓝瘦香菇 创建数据库 class Users(db.Model): __tablename__ = 'users ...

  9. sql 删除数据库表 外键

    --/第1步**********删除所有表的外键约束*************************/   DECLARE c1 cursor for select 'alter table ['+ ...

随机推荐

  1. python27期jquery:

    JavaScript:(简称“JS”) 是一种轻量级的编程语言(ECMAscript5或6)是一种解释性脚本语言(代码不进行预编译)主要用来向HTML页面添加交互行为JavaScript 是互联网上最 ...

  2. SpringMVC拦截器(四)

    拦截器,本质类似于AOP,主要的应用场景: 日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV等. 权限检查:如登录检测,进入处理器检测是否登录,没有登录返回登录页面. 性能监控:记录 ...

  3. 【[POI2012]TOU-Tour de Byteotia】

    [[POI2012]TOU-Tour de Byteotia] 洛谷P3535 https://www.luogu.org/problemnew/show/P3535 JDOJ 2193旅游景点(同类 ...

  4. NOIP2007 奖学金 结构体排序

    是结构体排序的练习题,可供选手们巩固结构体排序的一些相关内容. 关于结构体排序 1.结构体定义 struct student { int num,a,b,c,sum; }p[]; 2.结构体初始化 ; ...

  5. 执行flutter doctor后,无任何反应

    flutter运行需要联网,并且由于qiang,会导致访问缓慢,解决办法 export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_ ...

  6. [Algorithm] 1290. Convert Binary Number in a Linked List to Integer

    Given head which is a reference node to a singly-linked list. The value of each node in the linked l ...

  7. xcode静态库调试

    [工程1]:静态库工程,用来生成xxx.a [工程2]:项目工程,需要引入静态库xxx.a 工程2引入静态库的方法是将工程1生成的xxx.a和include头文件目录,加入到工程2中. 而如果需要在工 ...

  8. 【2019.8.8 慈溪模拟赛 T2】query(query)(分治+分类讨论)

    分治 首先,我们考虑分治处理此问题. 每次处理区间\([l,r]\)时,我们先处理完\([l,mid]\)和\([mid+1,r]\)两个区间的答案,然后我们再考虑计算左区间与右区间之间的答案. 处理 ...

  9. 洛谷P3723 [AH2017/HNOI2017]礼物

    吴迪说他化学会考上十分钟就想出来了,太神了%%%不过我也十分钟 但是调了一个多小时啊大草 懒得人话翻译了,自己康吧: 我的室友(真的是室友吗?)最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决 ...

  10. 修改gradle中央仓库,加快jar包下载速度

    打开gradle项目的build.gradle文件 找到repositories,注释掉mavenCentral(),使用阿里云的仓库地址 repositories { //mavenCentral( ...