数据库开发——参照完整性——在外键中使用Delete on cascade选项
原文:数据库开发——参照完整性——在外键中使用Delete on cascade选项
原文:
参照完整性在设计数据库时需要重视,在我作为DBA的生涯中,看到很多设计走了极端的路子。
在进入DELETE CASCADE选项的详细说明前,先来看看另外一个选项,可以在具有外键的表中设置UDPATE CASCADE选项。在我的工作生涯中,我从来没有遇到过必须通过外键来更新一列或多列。
创建实例表:
在本例中,创建两个表,并用外键关联起来。主表有99999行记录,子表对于每条父记录,有19条记录。下面是创建语句:
-- Table creation logic --parent table CREATE TABLE[dbo].[Order]( [OrderID] [bigint] NOT NULL, [OrderData] [varchar](10)NOT NULL, CONSTRAINT [PK_Order_1] PRIMARY KEY CLUSTERED ([OrderID]ASC) ) GO -- child table CREATE TABLE[dbo].[OrderDetail]( [OrderDetailID] [bigint] NOT NULL, [OrderID] [bigint] NULL, [OrderData] [varchar](10)NULL, CONSTRAINT [PK_OrderDetail] PRIMARY KEY CLUSTERED ([OrderDetailID]ASC) ) GO -- foreign key constraint ALTER TABLE[dbo].[OrderDetail] WITH CHECK ADD CONSTRAINT[FK_OrderDetail_Order] FOREIGNKEY([OrderID]) REFERENCES [dbo].[Order]([OrderID]) ON DELETECASCADE GO -- data load DECLARE @val BIGINT DECLARE @val2 BIGINT SELECT @val=1 WHILE @val< 100000 BEGIN INSERT INTO dbo.[Order]VALUES(@val,'TEST'+ CAST(@valAS VARCHAR)) SELECT @val2=1 WHILE @val2 < 20 BEGIN INSERT INTO dbo.[OrderDetail]VALUES ((@val*100000)+@val2,@val,'TEST'+ CAST(@valAS VARCHAR)) SELECT @val2=@val2+1 END SELECT @val=@val+1 END GO |
第一个例子:
现在先让我们从[Order]表中移除一条数据,注意,我在每个查询中使用了DBCC DROPCLEANBUFFERS,来确保缓存中没有数据:
DBCC DROPCLEANBUFFERS GO DELETE FROM[Order] WHERE OrderID=24433 GO |
在运行上面语句之后,可以查询[OrderDetail]表来确认记录是否已经被移除。这是为了了解,我们没有使用DELETE CASCADE选项时,要做什么操作,来确保数据移除,并看到他们的结果:
SELECT * FROM orderdetail WHERE orderid=24433 |
执行以后可以发现是没有数据的。下面再执行一下语句:
ALTER TABLE[dbo].[OrderDetail]DROP CONSTRAINT [FK_OrderDetail_Order] GO ALTER TABLE[dbo].[OrderDetail] WITH CHECK ADD CONSTRAINT[FK_OrderDetail_Order] FOREIGNKEY([OrderID]) REFERENCES [dbo].[Order]([OrderID]) GO |
现在让我们运行一下脚本,记住当有DELETECASCADE选项时,我们必须先从[OrderDetail]。中删除记录,想象一下,当我们有5、6个表对一个父表具有外键关联时,删除数据将要单独对每个表进行删除后才能删除父表。
DBCC DROPCLEANBUFFERS GO DELETE FROM[OrderDetail] WHEREOrderID=24032 DELETE FROM[Order] WHERE OrderID=24032 GO |
我们可以通过SQL Profiler来监控两个处理方法的性能。你可以看到觉有DELETE CASCADE选项的处理占用的资源更少:
DELETE CASCADE |
CPU (ms) |
Reads |
Writes |
Duration |
Yes |
281 |
12323 |
2 |
950 |
No |
374 |
24909 |
3 |
1162 |
第二个例子:
其中一个SQLServer最佳实践是在外键列并经常在where子句、join表中出现的字段,加上索引,现在我们对[OrderDetail]表加上索引,然后运行上面的查询,首先先加索引:
CREATE NONCLUSTEREDINDEX IX_OrderDetail_OrderIDON dbo.[OrderDetail](OrderID) GO |
接下来,运行改动后的执行,并监控性能:
DBCC DROPCLEANBUFFERS GO DELETE FROM[OrderDetail] WHEREOrderID=90032 DELETE FROM[Order] WHERE OrderID=90032 GO ALTER TABLE[dbo].[OrderDetail] WITH CHECK ADD CONSTRAINT[FK_OrderDetail_Order] FOREIGNKEY([OrderID]) REFERENCES [dbo].[Order]([OrderID]) ON DELETECASCADE GO DBCC DROPCLEANBUFFERS GO DELETE FROM[Order] WHERE OrderID=90433 GO |
从下面的结果可以看到,使用DELETECASCADE选项在多表删除时,性能更好,并且能自动清除子表数据:
DELETE CASCADE |
CPU (ms) |
Reads |
Writes |
Duration |
Yes |
0 |
300 |
7 |
79 |
No |
0 |
312 |
6 |
64 |
数据库开发——参照完整性——在外键中使用Delete on cascade选项的更多相关文章
- MySQL外键约束_ON DELETE CASCADE/ON UPDATE CASCADE
MySQL通过外键约束实现数据库的参照完整性,外键约束条件可在创建外键时指定,table的存储引擎只能是InnoDB,因为只有这种存储模式才支持外键. 外键约束条件有以下4种: (1)restrict ...
- Oracle开发 之 主-外键约束FK及约束的修改
试验环境: 1)数据库版本:oracle 11.2.0.4 2)建表脚本:以scott的dept及emp表为基础. 父表:dept -- Create table create table DEPT ...
- day38:MySQL数据库之约束&索引&外键&存储引擎
目录 part1:数据类型 part2:约束 part3:主键索引 PRI &唯一索引 UNI &普通索引 MUL part4:外键:foreign key part5:在外键中设置联 ...
- MySQL外键约束On Delete、On Update各取值的含义
主键.外键和索引的区别? 主键 外键 索引 定义: 唯一标识一条记录,不能有重复的,不允许为空 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 主索引(由关键字PRIMARY定义的索引) ...
- MySQL数据库之-foreign key 外键(一对多、多对多、一对一)、修改表、复制表
摘要: 外键 一对多 外键 多对多 外键 一对一 --------------------------------------------------------------------------- ...
- 【Django 2.2文档系列】Model 外键中的on_delete参数用法
场景 我们用Django的Model时,有时候需要关联外键.关联外键时,参数:on_delete的几个配置选项到底是干嘛的呢,你知道吗? 参数介绍 models.CASCADE 级联删除.Django ...
- sql操作数据库(3)-->外键约束、数据库表之间的关系、三大范式、多表查询、事务
外键约束 在新表中添加外键约束语法: constraint 外键约束名称 foreign key(外键的字段名称) references 主表表名(主键字段名) 在已有表中添加外键约束:alter t ...
- python 全栈开发,Day62(外键的变种(三种关系),数据的增删改,单表查询,多表查询)
一.外键的变种(三种关系) 本节重点: 如何找出两张表之间的关系 表的三种关系 一.介绍 因为有foreign key的约束,使得两张表形成了三种了关系: 多对一 多对多 一对一 二.重点理解如果找出 ...
- Oracle数据库添加删除主外键
(一)添加主键 1.表创建的同时,添加主键约束 语法: create table "表名" ( "列名1" 数据类型及长度 constraint "主 ...
随机推荐
- Unity3d socket通信 切换到web版本时报错SecurityException解决办法
原文地址:传送门 今天苦战了一天,就跟一个Unity切换到web平台的socket通信出错苦苦纠缠了一天,问了好多大牛,但他们的回复都是我没搞过web平台下的通信或者我只专研于pc或者移动平台.看来没 ...
- cocos2dx 3.1从零学习(六)——CocosStudio(VS2013project导入及环境设置)
导入libCocosStudio.libExtensions.libGUI 新建的project例如以下图: 加入现有项目 右键解决方式.例如以下操作: watermark/2/text/aHR0cD ...
- Git经常使用命令以及使用方法
一 怎样让单个文件回退到指定的版本号 1. 进入到文件所在文件文件夹,或者能找到文件的路径 查看文件的改动记录 git log MainActivity.java 2. 回退到指定的版本号 ...
- LeetCode: Best Time to Buy and Sell Stock III [123]
[称号] Say you have an array for which the ith element is the price of a given stock on day i. Design ...
- 实现Timeline
Redis实现Timeline 上回写了使用Redis实现关注关系,这次说说使用Redis实现Timeline. Timeline的实现一般有推模式.拉模式.推拉结合这几种.推模式:某人发布内容之后推 ...
- Oracle基本流程语句
====1.IF语句==========
- 中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030
中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030 cp936是微软自己发布的用在文件系统中的编码方式.而bg2312是中国国家标准.我明白mount -t vfa ...
- ORACLE函数之日期时间运算函数
1 ADD_MONTHS 格式:ADD_MONTHS(D,N) 说明:返回日期时间D加N月后相应的日期时间.N为正时则表示D之后:N为负时则表示为D之前.N为小数则会自己主动先删 ...
- Android源代码同步脚本(增加设置线程参数)
#!/bin/sh #Filename: repo_sync.sh count= ret= ] do #输入参数1,用作同步的线程数 #如果什么参数都不输入,默认线程为4 #usage: ./repo ...
- [置顶] 最优间隔分类器、原始/对偶问题、SVM的对偶问题——斯坦福ML公开课笔记7
转载请注明:http://blog.csdn.net/xinzhangyanxiang/article/details/9774135 本篇笔记针对ML公开课的第七个视频,主要内容包括最优间隔分类器( ...