索引 – 软删除 – 使用IsDeleted标志还是单独的连接表?

前端之家收集整理的这篇文章主要介绍了索引 – 软删除 – 使用IsDeleted标志还是单独的连接表?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们应该使用标志进行软删除还是单独的连接表?哪个更有效率?数据库sql Server.

背景资料

前段时间我们有一位DB顾问进来查看我们的数据库架构.当我们软删除记录时,我们将更新相应表上的IsDeleted标志.有人建议,不要使用标志,而是将已删除的记录存储在单独的表中,并使用连接,因为这样会更好.我已经把这个建议付诸实践了,但至少在表面上,额外的表和连接看起来比使用标志更昂贵.

初步测试

我已经设置了这个测试.

两个表,Example和DeletedExample.我在IsDeleted列上添加了一个非聚簇索引.

我做了三次测试,加载了一百万条记录,其中包含以下已删除/未删除的比率:

>已删除/未删除
> 50/50
> 10/90
> 1/99

结果 – 50/50

结果 – 10/90

结果 – 1/99

数据库脚本,参考,示例,DeletedExample和Example.IsDeleted的索引

CREATE TABLE [dbo].[Example](
    [ID] [int] NOT NULL,[Column1] [nvarchar](50) NULL,[IsDeleted] [bit] NOT NULL,CONSTRAINT [PK_Example] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF,STATISTICS_NORECOMPUTE  = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS  = ON,ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Example] ADD  CONSTRAINT [DF_Example_IsDeleted]  DEFAULT ((0)) FOR [IsDeleted]
GO

CREATE TABLE [dbo].[DeletedExample](
    [ID] [int] NOT NULL,CONSTRAINT [PK_DeletedExample] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF,ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[DeletedExample]  WITH CHECK ADD  CONSTRAINT [FK_DeletedExample_Example] FOREIGN KEY([ID])
REFERENCES [dbo].[Example] ([ID])
GO

ALTER TABLE [dbo].[DeletedExample] CHECK CONSTRAINT [FK_DeletedExample_Example]
GO

CREATE NONCLUSTERED INDEX [IX_IsDeleted] ON [dbo].[Example] 
(
    [IsDeleted] ASC
)WITH (PAD_INDEX  = OFF,SORT_IN_TEMPDB = OFF,DROP_EXISTING = OFF,ONLINE = OFF,ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

解决方法

您所拥有的数字似乎表明 my initial impression是正确的:如果针对此数据库的最常见查询是对IsDeleted = 0进行过滤,那么使用简单的位标志会有更好的性能,尤其是如果您明智地使用索引.

如果您经常单独查询删除和未删除的数据,则可以通过为已删除项目设置表格以及使用相同字段的未删除项目的另一个表格来查看性能提升.但是像这样对数据进行非规范化很少是一个好主意,因为在代码维护成本方面,它往往会比你在性能提升方面花费更多.

猜你在找的MsSQL相关文章