Table 设计缺陷。如何正确设计
Table design flaw. How to design it properly
我有这些 tables:
Table Source
:
IdSource (PK)
IdCurrentVersion (FK from TableSourceVersions.IdSourceVersion) updated when a new version appears
Value
Table SourceVersions
:
IdSourceVersion (PK)
IdSource (FK)
Value
这两个 table 描述了产品定义及其版本。
现在我有另外两个 tables 可以有定义和版本的任意组合(类似于上面的这两个 tables):
TableX
--------------------
IdX (PK)
IdSource
TableXVersions
--------------------
IdVersion (PK)
IdX (FK)
IdSourceVersion
通常的想法是 Table X 和 TableXVersion 可以有不同的版本(IdSource 和 IdSourceVersion)。
table 设计的解决方案让我望而却步。
我不知道如何保存两者的完整性(IdSource
和 IdSourceVersion
)
在两个 table 中:TableX
和 TableXVersions
,考虑到 TableX
必须定义定义 (idSource
) 和 tableXVersion
许多之一IdSourceVersion
.
那个设计是有缺陷的,因为我可以在另一个定义的 master 和 version 中有 IdSource
....
感谢您的帮助...
我想说设计中的缺陷是将 IDCurrentVersion
存储在 table Source
上,我会用两种方法之一来解决这个问题。
1.使用视图计算当前版本
如果当前版本总是TableSourceVersions
中的最新版本,那么我假设你有一个日期字段来定义最新,那么我会创建一个视图:
CREATE VIEW dbo.LatestTableSourceVersions
AS
SELECT IDSourceVersion,
IDSource,
Value,
CreatedDate
FROM ( SELECT IDSourceVersion,
IDSource,
Value,
CreatedDate,
RowNum = ROW_NUMBER() OVER(PARTITION BY IDSource ORDER BY CreatedDate DESC)
FROM TableSourceVersions
) AS tsv
WHERE RowNum = 1;
GO
这意味着您不需要为每个新版本更新 Source
,视图会自动保持最新。
2。使用flag标记当前版本
如果不能这么简单的计算当前版本,那我还是不把当前版本存入Source
,我会在TableSourceVersions
中加一个位域来标记当前版本,例如IsCurrent
.
ALTER TABLE TableSourceVersions ADD IsCurrent BIT;
您可以确保每个 IdSource
只有一个具有唯一过滤索引的当前版本:
CREATE UNIQUE INDEX UQ_TableSourceVersions__IDSource
ON TableSourceVersions (IDSource)
WHERE IsCurrent = 1;
但是,要真正回答您的问题,使用您当前的 table 结构,您可以通过在 TableSourceVersions
:
上创建唯一索引来保持完整性
CREATE UNIQUE INDEX UQ_TableSourceVersions__IDSourceVersion_IDSource
ON TableSourceVersions (IDSourceVersion, IDSource);
那么您可以使外键引用两列以确保选择了有效版本,而不是使用从 IdCurrentVersion
到 IdSourceVersion
的外键:
ALTER TABLE [Source] ADD CONSTRAINT FK_Source__IdCurrentVersion_IDSource
FOREIGN KEY (IdCurrentVersion, IDSource)
REFERENCES TableSourceVersions (IDSourceVersion, IDSource);
一个选项是重复 IdSource
TableX
--------------------
IdX (PK)
IdSource (PK) (FK)
TableXVersions
--------------------
IdVersion (PK)
IdX (FK1)
IdSource (FK1) (FK2)
IdSourceVersion (FK2)
另一个选项就是没有tableX
那是 table 设计而不是 T-SQL 设计。 T-SQL是查询语言。
我有这些 tables:
Table Source
:
IdSource (PK)
IdCurrentVersion (FK from TableSourceVersions.IdSourceVersion) updated when a new version appears
Value
Table SourceVersions
:
IdSourceVersion (PK)
IdSource (FK)
Value
这两个 table 描述了产品定义及其版本。
现在我有另外两个 tables 可以有定义和版本的任意组合(类似于上面的这两个 tables):
TableX
--------------------
IdX (PK)
IdSource
TableXVersions
--------------------
IdVersion (PK)
IdX (FK)
IdSourceVersion
通常的想法是 Table X 和 TableXVersion 可以有不同的版本(IdSource 和 IdSourceVersion)。
table 设计的解决方案让我望而却步。
我不知道如何保存两者的完整性(IdSource
和 IdSourceVersion
)
在两个 table 中:TableX
和 TableXVersions
,考虑到 TableX
必须定义定义 (idSource
) 和 tableXVersion
许多之一IdSourceVersion
.
那个设计是有缺陷的,因为我可以在另一个定义的 master 和 version 中有 IdSource
....
感谢您的帮助...
我想说设计中的缺陷是将 IDCurrentVersion
存储在 table Source
上,我会用两种方法之一来解决这个问题。
1.使用视图计算当前版本
如果当前版本总是TableSourceVersions
中的最新版本,那么我假设你有一个日期字段来定义最新,那么我会创建一个视图:
CREATE VIEW dbo.LatestTableSourceVersions
AS
SELECT IDSourceVersion,
IDSource,
Value,
CreatedDate
FROM ( SELECT IDSourceVersion,
IDSource,
Value,
CreatedDate,
RowNum = ROW_NUMBER() OVER(PARTITION BY IDSource ORDER BY CreatedDate DESC)
FROM TableSourceVersions
) AS tsv
WHERE RowNum = 1;
GO
这意味着您不需要为每个新版本更新 Source
,视图会自动保持最新。
2。使用flag标记当前版本
如果不能这么简单的计算当前版本,那我还是不把当前版本存入Source
,我会在TableSourceVersions
中加一个位域来标记当前版本,例如IsCurrent
.
ALTER TABLE TableSourceVersions ADD IsCurrent BIT;
您可以确保每个 IdSource
只有一个具有唯一过滤索引的当前版本:
CREATE UNIQUE INDEX UQ_TableSourceVersions__IDSource
ON TableSourceVersions (IDSource)
WHERE IsCurrent = 1;
但是,要真正回答您的问题,使用您当前的 table 结构,您可以通过在 TableSourceVersions
:
CREATE UNIQUE INDEX UQ_TableSourceVersions__IDSourceVersion_IDSource
ON TableSourceVersions (IDSourceVersion, IDSource);
那么您可以使外键引用两列以确保选择了有效版本,而不是使用从 IdCurrentVersion
到 IdSourceVersion
的外键:
ALTER TABLE [Source] ADD CONSTRAINT FK_Source__IdCurrentVersion_IDSource
FOREIGN KEY (IdCurrentVersion, IDSource)
REFERENCES TableSourceVersions (IDSourceVersion, IDSource);
一个选项是重复 IdSource
TableX
--------------------
IdX (PK)
IdSource (PK) (FK)
TableXVersions
--------------------
IdVersion (PK)
IdX (FK1)
IdSource (FK1) (FK2)
IdSourceVersion (FK2)
另一个选项就是没有tableX
那是 table 设计而不是 T-SQL 设计。 T-SQL是查询语言。