数据库开发——参照完整性——在外键中使用Delete on cascade选项
2012-10-06 13:03
459 查看
原文:
http://www.mssqltips.com/sqlservertip/2743/using-delete-cascade-option-for-foreign-keys/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_campaign=2012731
参照完整性在设计数据库时需要重视,在我作为DBA的生涯中,看到很多设计走了极端的路子。
在进入DELETE CASCADE选项的详细说明前,先来看看另外一个选项,可以在具有外键的表中设置UDPATE CASCADE选项。在我的工作生涯中,我从来没有遇到过必须通过外键来更新一列或多列。
在运行上面语句之后,可以查询[OrderDetail]表来确认记录是否已经被移除。这是为了了解,我们没有使用DELETE CASCADE选项时,要做什么操作,来确保数据移除,并看到他们的结果:
执行以后可以发现是没有数据的。下面再执行一下语句:
现在让我们运行一下脚本,记住当有DELETECASCADE选项时,我们必须先从[OrderDetail]。中删除记录,想象一下,当我们有5、6个表对一个父表具有外键关联时,删除数据将要单独对每个表进行删除后才能删除父表。
我们可以通过SQL Profiler来监控两个处理方法的性能。你可以看到觉有DELETE CASCADE选项的处理占用的资源更少:
接下来,运行改动后的执行,并监控性能:
从下面的结果可以看到,使用DELETECASCADE选项在多表删除时,性能更好,并且能自动清除子表数据:
http://www.mssqltips.com/sqlservertip/2743/using-delete-cascade-option-for-foreign-keys/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_campaign=2012731
参照完整性在设计数据库时需要重视,在我作为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 |
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 |
DBCC DROPCLEANBUFFERS GO DELETE FROM[OrderDetail] WHEREOrderID=24032 DELETE FROM[Order] WHERE OrderID=24032 GO |
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 |
DELETE CASCADE | CPU (ms) | Reads | Writes | Duration |
Yes | 0 | 300 | 7 | 79 |
No | 0 | 312 | 6 | 64 |
相关文章推荐
- 数据库开发——参照完整性——在外键中使用Delete on cascade选项
- 数据库开发——参照完整性——在外键中使用Delete on cascade选项
- 数据库开发——参照完整性——在外键中使用Delete on cascade选项(转载)
- 数据库开发——参照完整性——在外键中使用Delete on cascade选项
- 使用IntelliJ IDEA开发SpringMVC网站(三)数据库配置
- 使用.NET开发数据库应用程序(2)---给初学者看的文章
- Android 开发中使用 SQLite 数据库
- 数据库使用truncate清理很多表时碰到外键约束时怎么快速解决
- 17.Oracle数据库SQL开发之 使用SELECT查询两个表
- android开发(24)使用SQLiteOpenHelper的onUpgrade实现数据库版本升级
- 在ASP.NET中使用SQL Server作为数据库,DB First方式使用EF(EntityFramework)进行开发和部署时的connectionString
- Visual C# 2008+SQL Server 2005 数据库与网络开发-- 9.3 XML相关的SQL语句使用
- Spring+Hibernate DAO 持久层开发, Spring 用 Hibernate 访问数据库的三种方法.推荐使用回调
- Objective-C ,ios,iphone开发基础:ios数据库(The SQLite Database),使用终端进行简单的数据库操作
- ACCP学习旅程之-----使用C#开发数据库应用程序(第七章 用ADO.NET查询和操作数据库)
- 大家设计数据库时是否使用外键
- vs2013 ef,使用 MySQL来做数据库开发
- Visual C# 2008+SQL Server 2005 数据库与网络开发-- 12.2 在窗体上使用控件
- Android SQLite数据库(事务)的使用,多线程CRUD并发操作(可用于实际开发)
- docker 实战---使用oracle xe作为开发数据库(六)