我有两个相关的数据库表:
CREATE TABLE [dbo].[TopicKeyword]
(
[Id] SMALLINT NOT NULL,
[Keyword] VARCHAR(100) NOT NULL,
[Volume] INT NOT NULL,
[PageId] SMALLINT NOT NULL,
CONSTRAINT [PK_TopicKeyword] PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[TopicCluster]
(
[KeywordId] SMALLINT NOT NULL,
CONSTRAINT [PK_TopicCluster] PRIMARY KEY CLUSTERED ([KeywordId] ASC),
CONSTRAINT [FK_TopicCluster_TopicKeyword]
FOREIGN KEY ([KeywordId]) REFERENCES [dbo].[TopicKeyword] ([Id])
);
如您所见,使用TopicCluster
的{{1}}引用TopicKeyword
。
但是,我需要确保KeywordId
表的完整性。
TopicCluster
表中的PageID
可以重复多次,但是TopicKeyword
表中每个PageId
只能有一个关键字。
例如:
主题关键字
Id,PageId
TopicCluster
KeywordId
我已经创建了一个解决方案,但是我不是SQL专家,所以我不确定在这种情况下这是否是正确的方法。再次是这些表格,这些表格经过了重新设计以包括新的约束:
TopicCluster
任何建议表示赞赏。
答案 0 :(得分:0)
我清除了您的脚本:
CREATE TABLE TopicKeyword
(
Id smallint NOT NULL,
Keyword varchar(100) NOT NULL,
Volume int NOT NULL,
PageId smallint NOT NULL,
CONSTRAINT PK_TopicKeyword PRIMARY KEY (Id),
CONSTRAINT UK_TopicKeyword UNIQUE (Id, PageId) -- to create FOREIGN KEY in TopicCluster
)
GO
CREATE TABLE TopicCluster
(
KeywordId smallint NOT NULL,
PageId smallint NOT NULL,
CONSTRAINT PK_TopicCluster PRIMARY KEY (KeywordId), -- to exclude duplicates in KeywordId
CONSTRAINT UK_TopicCluster_PageId UNIQUE (PageId), -- to exclude duplicates in PageId
CONSTRAINT FK_TopicCluster_TopicKeyword
FOREIGN KEY (KeywordId, PageId)
REFERENCES TopicKeyword (Id, PageId) -- to prevent pairs of KeywordId&PageId which not in TopicKeyword
)
GO
答案 1 :(得分:0)
您的DDL非常适合您的用例。
如果我有不好的说法,那就是应该仅在TopicKeyword表中出现PageId列(数据重复),您可以在需要时使用SQL JOIN语句获取PageId。
如果我猜对了,您的TopicKeyword表应该每行存储一个(关键字和页面)唯一组合,为此,我将执行以下操作:
CREATE TABLE [dbo].[TopicKeyword]
(
[Id] SMALLINT NOT NULL,
[Keyword] VARCHAR(100) NOT NULL,
[Volume] INT NOT NULL,
[PageId] SMALLINT NOT NULL,
CONSTRAINT [PK_TopicKeyword] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [UQ_TopicKeyword] UNIQUE NONCLUSTERED ([Keyword] ASC, [PageId] ASC)
);
GO
将使用PK作为参考,并且唯一性约束将确保每行(关键字和页面)的唯一组合。
对于第二部分,您要在群集表中存储仅与一个页面相关联的关键字,为此,我将执行以下操作:
CREATE FUNCTION FN_IsPageIdUnique
(
@KeywordId SMALLINT
)
RETURNS BIT
AS
BEGIN
DECLARE @IsPageIdUnique BIT
DECLARE @PageIdCount INT
SELECT @PageIdCount = COUNT(k2.[PageId])
FROM [TopicKeyword] k1
INNER join [TopicKeyword] k2 ON k2.[PageId] = k1.[PageId]
WHERE k1.[Id] = @KeywordId
IF (@PageIdCount = 1)
SET @IsPageIdUnique = 1
ELSE
SET @IsPageIdUnique = 0
RETURN @IsPageIdUnique
END
GO
CREATE TABLE [dbo].[TopicCluster]
(
[KeywordId] SMALLINT NOT NULL,
CONSTRAINT [PK_TopicCluster] PRIMARY KEY CLUSTERED ([KeywordId] ASC),
CONSTRAINT [FK_TopicCluster_TopicKeyword] FOREIGN KEY ([KeywordId]) REFERENCES [dbo].[TopicKeyword] ([Id]),
CONSTRAINT CK_TopicCluster CHECK (dbo.FN_IsPageIdUnique(KeywordId))
);
GO
检查约束将帮助您基于将使用标量函数FN_IsPageIdUnique计算的另一个表数据来增强群集数据的唯一性。