我有一个用于存储“任务”的表。任务可以是父项和/或子项。我使用“ ParentID ”作为 FK 引用同一张桌子上的 PK。它是 NULLABLE,所以如果它是NULL它没有父任务。
示例是下面的屏幕截图...
在我的团队中,有人认为创建一个单独的表来存储 ParentID 会更好(对于规范化/最佳实践),从而避免表中出现 NULL 并导致更好的规范化设计。
这会是一个更好的选择吗?或者查询会更困难并导致性能问题?
我们只想从一开始就做好设计,而不是以后再发现问题。
现有表的 SQL-DDL 代码:
CREATE TABLE [Tasks].[TaskDetail]
(
[TaskDetailID] [int] IDENTITY(1,1) NOT NULL,
[TaskName] [varchar](50) NOT NULL,
[TaskDescription] [varchar](250) NULL,
[IsActive] [bit] NOT NULL CONSTRAINT [DF_TaskDetail_IsActive] DEFAULT ((1)),
[ParentID] [int] NULL,
CONSTRAINT [PK_TaskDetail_TaskDetailID] PRIMARY KEY CLUSTERED ([TaskDetailID] ASC),
CONSTRAINT [FK_TaskDetail_ParentID] FOREIGN KEY([ParentID]) REFERENCES [Tasks].[TaskDetail]([TaskDetailID])
);
Run Code Online (Sandbox Code Playgroud) 我有一个包含 321 行的表(在下面创建)。
我希望下面的最后一个查询使用非聚集索引,然后使用键查找。但是,它使用聚集索引扫描。仅按预期返回单行。
为什么它执行扫描而不是使用非聚集索引?是不是因为表只包含 321 行?
CREATE TABLE dbo.TestIndexSample
(
Code char(4) NOT NULL,
Name nvarchar(200) NOT NULL,
ModifiedDate datetime NOT NULL CONSTRAINT [DF_TestIndexSample_ModifiedDate] DEFAULT GETDATE(),
CONSTRAINT [PK_TestIndexSample_Code] PRIMARY KEY CLUSTERED(Code)
);
GO
CREATE NONCLUSTERED INDEX IX_TestIndexSample_Name
ON dbo.TestIndexSample(Name);
GO
INSERT INTO dbo.TestIndexSample(Code, Name)
select CodeName, FullName
from dbo.SourceTest
GO
SELECT * FROM dbo.TestIndexSample
SELECT * FROM dbo.TestIndexSample where Code = 'X132EY'
SELECT * FROM dbo.TestIndexSample where Name = 'User A'
Run Code Online (Sandbox Code Playgroud) sql-server sql-server-2008-r2 index-tuning nonclustered-index