五、SQL–索引/约束⑥(外键约束)
引出:
当一些信息在表中重复出现时,就要考虑要将它们提取到新的表中,并在源表中引用新创建的中的数据。
如:很多作者都著有不止一本著作,所以在保存书籍信息的时候,应该把作者信息放到单独的表中,创建表的SQL语句如下:
MYSQL、MSSQLServer:
CREATE TABLE T_AUTHOR(
FId VARCHAR(20) PRIMARY KEY,
FName VARCHAR(100),
FAge INT,FEmail VARCHAR(20));CREATE TABLE T_Book(
FName VARCHAR(100),
FPageCount INT,)
FAuthorId VARCHAR2(20)); Oracle:
CREATE TABLE T_AUTHOR(
FId VARCHAR2(20) PRIMARY KEY,
FName VARCHAR2(100),
FEmail VARCHAR2(20));CREATE TABLE T_Book(
FName VARCHAR2(100),
FPageCount NUMBER (10),
FAuthorId VARCHAR2(20));DB2:
CREATE TABLE T_AUTHOR(
FId VARCHAR(20) NOT NULL PRIMARY KEY,
FName VARCHAR(100),FAge INT,
FEmail VARCHAR(20));CREATE TABLE T_Book(
FId VARCHAR(20) NOT NULL PRIMARY KEY,
FName VARCHAR(100),FPageCount INT,
FAuthorId VARCHAR(20));
插入数据:
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail) VALUES("1","lily",20,"lily@cownew.com");
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail) VALUES("2","kingchou",23,"kingchou@cownew.com");
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail) VALUES("3","stef",28,"stef@cownew.com");
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail) VALUES("4","long",26,"long@cownew.com");
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail) VALUES("5","badboy",31,"badboy@cownew.com");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId) VALUES("1","About Java",300,"1");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId) VALUES("2","Inside Ruby",330,"2");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId) VALUES("3","Inside Curses",200,"5");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId) VALUES("4","Python InAction",450,"4");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId) VALUES("5","WPF Anywhere",250,"1");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId) VALUES("6","C# KickStart",280,"3");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId) VALUES("7","Compling",800,"1");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId) VALUES("8","Faster VB.Net",300,"5");
表T_Book 的FAuthorId字段存储的是代表每个作者的主键值,如果要查询一本书的作者信息,那么只要按照FAuthorId字段的值到T_AUTHOR 表中查询就可了。不过这样的表结构仍然存在问题:1)不能约束表T_Book的FAuthorId字段中存储在表T_AUTHOR中不存在的值。
如:执行下面的SQL语句向T_Book表中插入新数据:
INSERT INTO T_Book(
FId,FName,FPageCount,FAuthorId)
VALUES("9","AboutWinCE",320,"9");
表T_Book中最后一条数据的FAuthorId字段值为9,但是在T_AUTHOR表中却没有主键值为9 的记录,也就是这条记录引用了不存在的作者。
2)不能约束删除T_AUTHOR中已经被T_Book表引用的记录。
如:我们执行下面的SQL语句删除T_AUTHOR表中的部分记录:
DELETE FROM T_AUTHOR WHERE FAge>30
虽然表T_Book中《Inside Curses》这本书还引用着badboy这个作者,但是这个作者仍然被删除了,这样同样造成了T_Book表中引用了T_AUTHOR表中不存在的记录。
如何防止数据表之间的关系被破坏?
外键约束机制可以解决这个问题,它允许指定一个表中的一个列的值是另外一个表的外键,即一个表中的一个列是引用另外一个表中的记录。
例如,可以设定T_Book 表中的FAuthorId 字段是一个依赖于T_AUTHOR表的FId列中存在的主键值。
在创建表时添加外键约束,其定义方式和复合主键类似,语法如下:
FOREIGN KEY 外键字段REFERENCES 外键表名(外键表的主键字段)
如:下面的SQL语句是添加了外键约束的,T_AUTHOR表和T_Book表的创建语句:
MYSQL、MSSQLServer:
CREATE TABLE T_AUTHOR(
FId VARCHAR(20) PRIMARY KEY,
FName VARCHAR(100),FAge INT,FEmail VARCHAR(20));CREATE TABLE T_Book(
FId VARCHAR(20) PRIMARY KEY,
FName VARCHAR(100),FPageCount INT,
FAuthorId VARCHAR(20) ,
FOREIGN KEY (FAuthorId) REFERENCES T_AUTHOR(FId));Oracle:
CREATE TABLE T_AUTHOR(
FId VARCHAR2(20) PRIMARY KEY,
FName VARCHAR2(100),FAge NUMBER (10),
FEmail VARCHAR2(20));CREATE TABLE T_Book(
FId VARCHAR2(20) PRIMARY KEY,
FName VARCHAR2(100),FPageCount NUMBER (10),
FAuthorId VARCHAR2(20) ,
FOREIGN KEY (FAuthorId) REFERENCES T_AUTHOR(FId));DB2:
CREATE TABLE T_AUTHOR(
FId VARCHAR(20) NOT NULL PRIMARY KEY,
FName VARCHAR(100),FAge INT,
FEmail VARCHAR(20));CREATE TABLE T_Book(
FId VARCHAR(20) NOT NULL PRIMARY KEY,
FName VARCHAR(100),FPageCount INT,
FAuthorId VARCHAR(20) ,
FOREIGN KEY (FAuthorId) REFERENCES T_AUTHOR(FId));
插入数据:
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail)VALUES("1","lily",20,"lily@cownew.com");
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail)VALUES("2","kingchou",23,"kingchou@cownew.com");
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail)VALUES("3","stef",28,"stef@cownew.com");
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail)VALUES("4","long",26,"long@cownew.com");
INSERT INTO T_AUTHOR(FId,FName,FAge,FEmail)VALUES("5","badboy",31,"badboy@cownew.com");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("1","About Java",300,"1");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("2","Inside Ruby",330,"2");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("3","Inside Curses",200,"5");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("4","Python InAction",450,"4");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("5","WPF Anywhere",250,"1");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("6","C# KickStart",280,"3");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("7","Compling",800,"1");
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("8","Faster VB.Net",300,"5");
尝试向表中插入违反外键约束的数据,如:
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("9","AboutWinCE",320,"9");
因为表T_AUTHOR 中没有主键值等于9 的记录,所以执行后系统会报出如下错误信息:
INSERT 语句与 FOREIGN KEY 约束"FK__T_Book__FAuthorI__38996AB5"冲突。该冲突发生于数据库"demo",表"dbo.T_AUTHOR", column "FId"。
修改上面的SQL语句,使其FAuthorId字段的值为在表T_AUTHOR中存在的主键值:
INSERT INTO T_Book(FId,FName,FPageCount,FAuthorId)VALUES("9","AboutWinCE",320,"3");
同样,我们不能删除被T_Book表引用的T_AUTHOR表中的数据,比如我们想执行下面的SQL语句将作者long从T_AUTHOR表中删除:
DELETE FROM T_AUTHOR
WHERE FName=" badboy"
因为《Inside Curses》、《Faster VB.Net》这两本书的作者为主键值等于5的作者badboy,所以上面的SQL语句执行后数据库系统会报出如下的错误信息:
DELETE 语句与REFERENCE 约束"FK__T_Book__FAuthorI__38996AB5"冲突。该冲突发生于数据库"demo",表"dbo.T_Book", column "FAuthorId"。
删除一个表中的数据时,若其他表中存在指向这些数据的外键关系,那么删除操作将会失败,除非将所有相关的数据都删除。
如:先执行下面的SQL 语句将作者long 的所有著作删除:
DELETE FROM T_Book
WHERE FAuthorId =5;
然后就可以执行下面的SQL语句将作者long从T_AUTHOR表中删除了:
DELETE FROM T_AUTHOR
WHERE FName="badboy"
若创建表时,未添加外键约束,则可使用ALTER TABLE语句添加外键约束,其语法与添加UNIQUE约束类似。
如:以ALTER TABLE 语句的方式添加外键约束:
ALTER TABLE T_Book
ADD CONSTRAINT fk_book_author
FOREIGN KEY (FAuthorId) REFERENCES T_AUTHOR(FId)
现在可以删除T_AUTHOR表和T_Book表了:
DROP TABLE T_Book;
DROP TABLE T_AUTHOR;
注意:这里的删除顺序是首先删除T_Book,再删除T_AUTHOR,否则会因为违反外键约束而执行失败。
http://www.taodudu.cc/news/show-4362889.html
相关文章:
- 接近8000字的Spring/Spring常用注解总结
- 【cocos2d-x从c++到js】22:使用非侵入方式扩展UI系统接口的举例
- Scala高阶函数操作示例详解
- delphi 调用带有返回值的sql SERver 2008 存储过程
- 达梦8,关于参数CTAB_SEL_WITH_CONS的验证
- 众筹网站项目第五天之用户的增、删、改
- 每天学点clickhouse
- QQ邮箱发送信息
- 接近8000字的Spring/SpringBoot常用注解总结!安排!
- html css 图标生成器
- vue3+ts+element-plus动态图标生成方式
- 如何把阿里图标库的图标生成代码并应用于自己的项目
- iconfont.cn 选择图标生成 scriptUrl 链接
- 字体图标生成网站
- 12款免费图标生成器
- Android 通用图标生成器
- android图标生成网址
- C#:图标生成小工具
- Android Drawable图标生成工具
- iOS开发:图标生成器Prepo 的使用,讲的明明白白
- Android神兵利器之Image Asset Studio
- putchar、getchar 大小写转化
- java字符串大小写转化
- python|简单实现英文单词大小写转化
- c语言大小写字母相互转化,(c语言)字符串的大小写字母转化函数
- perl 大小写转化
- JPA映射数据库mysql表名,字段名大小写转化,下划线分割.
- C语言——大小写字母转换
- 《职业教育研究》(月刊)投稿经验分享
- b站推荐怎么重置_b站手机怎么上传视频
五、SQL–索引/约束⑥(外键约束)相关推荐
- SQL中的外键约束及多表查询
SQL中的外键约束及多表查询 外键约束 foreign key 实体:数据库中的表,就可以看作一个实体,实体和实体之间有一些关系 比如说做一个网上商城的项目,里面有用户表,商品表,订单表 一对多的关系 ...
- mysql 约束基本概念 主键约束 外键约束
constraint 约束数据(对表中数据的限制条件) 四种条件约束:非空 唯一性 主键约束 外键约束 非空约束(not null)约束的字段不能为空值,必须赋具体的数据 CREATE TAB ...
- sql向数据库表中插入列,sql给表的列添加说明,sql添加主外键约束,增加列,增加字段
规则代码 use 数据库名--向表中插入列alter table 表名 add 列名 类型go--给表的列添加说明 execute sp_addextendedproperty 'MS_Descrip ...
- sql 删除所有外键约束,表,存储过程,试图
删除外键约束 --1.删除外键约束 DECLARE c1 cursor for select 'alter table ['+ object_name(parent_obj) + '] drop co ...
- SQL中创建外键约束
alter table 表名 add constraint 外键约束名 foreign key(列名) references 引用外键表(列名) 作者:耑新新,发布于 博客园 转载请注明出处,欢迎邮 ...
- SQL语句 -非空约束 - 唯一约束 - 主键约束 - 默认约束 -外键约束
文章目录 约束 约束介绍和分类 非空约束 唯一约束 主键约束 默认约束 案例练习 外键约束 约束 约束介绍和分类 约束的概念: 约束是作用于表中列上的规则,用于限制加入表的数据 约束的存在保证了数据库 ...
- Oracle定义约束 外键约束
外键约束保证参照完整性.外键约束限定了一个列的取值范围.一个例子就是限定州名缩写在一个有限值集合中,这个值集合是另外一个控制结构--一张父表 下面我们创建一张参照表,它提供了完整的州缩写列表,然后使用 ...
- MySQL数据库约束(主键约束,外键约束详解)
关系型数据库的一个重要功能: 需要保证数据的"完整性",可以通过人工的方式来观察确认数据的正确性,这种方式是可行的,但是不合适,因为人为控制的方式势必会存在疏忽,导致一些错误没有被 ...
- MySQL的约束——外键约束
约束: MySQL的约束的概述: 概念: 约束是作用于表中字段上的规则,用于限制存储在表中的数据 目的: 保证数据库中数据的正确,有效和完整性 分类 1.非空约束 NOT NULL 限制该字段的数据不 ...
最新文章
- php curl errno 3,PHP curl_errno函数
- 使用DOTS制作一款第三人称僵尸射击游戏
- SAP CRM One Order object type in line item - when it is filled
- 使用SpringWebFlux的反应式Web应用程序
- Spring Integration Publisher
- 用了fastapi还需要nginx_nginx 与 fastdfs 的配置过程,已经越过了许多坑,我跪着进入了欢迎页面。。。...
- (81)FPGA复位激励(task)
- 深入解析MVVM架构
- 多线程模拟渡河 C语言 Linux
- 编程语言的通用概念[共同特征]
- 《走出强迫的泥潭——森田疗法指导集锦》
- HTML5分级标题,最佳HTML5结构,其中标题/标题是文章标签外
- 八、JUC强大的辅助类
- endless 题解
- database rough 1
- 如何查看一个人发表的SCI数量
- selenium模拟登录163邮箱,定位账号及密码输入框问题和iframe嵌套
- CISA Exam Prep: Certified Information Systems Auditor
- 在javascript中 setInterval()、clearInterval()、clearTimeout()等等常用的函数的含义
- Python报错ReadTimeoutError
热门文章
- ERROR: Cannot install keras==2.2.0 and tensorflow==1.14.0 because these package versions have confli
- 7.Numpy array 分割(纵向分割/横向分割/错误分割/不等量分割/其他分割)
- iphone开发中的手势操作:Multiple Taps
- 中国量子计算机是什么,中国研发出世界首台量子计算机 什么是量子计算机
- 【元宇宙经济学】元宇宙经济的定义和意义
- 预制菜顶流信良记,小龙虾的生意经难念
- 滴滴出行技术副总裁赖春波:每天发现几十万异常订单,仅有几起为真!
- 在win10上去除移动硬盘的bitlocker
- 红米5 Android 8.0,红米 5 获得 Android 8.0 稳定版更新:修复大量问题
- 读提交和可重复读区别