2012-01-13 41 views
8

我們應該使用軟標記進行軟刪除還是使用單獨的連接器表?哪個更有效率?數據庫是SQL Server。軟刪除 - 使用IsDeleted標誌或單獨的連接器表?

背景信息

前陣子我們有一個DB顧問進來看看我們的數據庫模式。當我們軟刪除一條記錄時,我們會在適當的表上更新一個IsDeleted標誌。有人建議,不要使用標誌,而應將已刪除的記錄存儲在單獨的表中,並使用更好的連接。我已經提出了這個建議,但至少在表面上看來,額外的表和連接看起來比使用標誌更昂貴。

初步測試

我已經建立了這個測試。

兩個表,Example和DeletedExample。我在IsDeleted列上添加了一個非聚集索引。

我做了三次測試,加載一百萬條記錄與下面的刪除/非刪除比率:

  • 刪除/ NonDeleted
  • 50/50
  • 10/90
  • 1/99

結果 - 50/50 50 50

結果 - 10/90 10 90

結果 - 1/99 enter image description here

數據庫腳本,作爲參考,實施例,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, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 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, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

回答

8

數字似乎表明my initial impression是正確的:如果您對該數據庫的最常見查詢是在IsDeleted = 0上進行過濾,那麼使用簡單的位標記會使性能更好,尤其是在您明智地使用索引時。

如果你經常單獨查詢刪除和未刪除的數據,那麼你可以通過具有用於刪除的項目表,另一個未刪除的項目,具有相同的字段中顯示性能增益。但是,像這樣對數據進行非規範化並不是一個好主意,因爲在代碼維護成本中,代碼維護成本往往比在性能提升中獲得更多成本。

+2

很好的答案。還要考慮使用過濾的索引。如果只在記錄未被刪除時按Column1查詢Example表,則索引Column1「WHERE IsDelete = 0」。 – 2012-01-16 16:27:33

1

我不是SQL專家,但在我看來,這一切都取決於數據庫的使用頻率。如果數據庫被大量用戶訪問並且需要高效,那麼單獨使用isDeleted表將會很好。更好的選擇是在生產時間,因爲你可以將所有軟刪除的記錄,請將isDeleted表和清除軟刪除的記錄生產表每日/每週/每月maintanace的一部分使用的標誌。這兩種選擇的混合將是一個很好的選擇。