表设计缺陷。如何正确设计

时间:2015-01-20 12:00:09

标签: sql sql-server tsql

我有这些表:

Source

IdSource (PK)
IdCurrentVersion (FK from TableSourceVersions.IdSourceVersion) updated when a new version appears
Value

SourceVersions

IdSourceVersion (PK)
IdSource (FK)
Value

这两个表描述了产品定义及其版本。

现在我有两个其他表可以有定义和版本的任意组合(类似上面这两个表):

TableX
--------------------
IdX (PK)
IdSource

TableXVersions
--------------------
IdVersion (PK)
IdX (FK)
IdSourceVersion

通常,我们的想法是Table X和TableXVersion可能有两个版本(IdSource和IdSourceVersion)。

桌子设计的解决方案让我不知所措。

我不知道如何保存两者的完整性(IdSourceIdSourceVersion) 在两个表中:TableXTableXVersions,考虑到TableX必须定义定义(idSource)和tableXVersion许多IdSourceVersion中的一个

这种设计存在缺陷,因为我可以在master和版本中使用IdSource ....

感谢您的帮助......

2 个答案:

答案 0 :(得分:2)

一种选择是重复IdSource

TableX
--------------------
IdX      (PK)
IdSource (PK)    (FK)

TableXVersions
--------------------
IdVersion (PK)
IdX      (FK1)
IdSource (FK1)  (FK2) 
IdSourceVersion (FK2)

另一个选择就是没有tableX

那就是桌面设计而不是T-SQL设计。 T-SQL是查询语言。

答案 1 :(得分:1)

我想说设计中的缺陷是将IDCurrentVersion存储在表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。使用标记标记当前版本

如果您无法以这种简单的方式计算当前版本,那么我仍然不会将当前版本存储在Source中,我会向TableSourceVersions添加一个位字段来标记当前版本,例如IsCurrent

ALTER TABLE TableSourceVersions ADD IsCurrent BIT;

您可以确保每个IdSource只有一个当前版本具有唯一的过滤索引:

CREATE UNIQUE INDEX UQ_TableSourceVersions__IDSource 
    ON TableSourceVersions (IDSource)
    WHERE IsCurrent = 1;

但是,要真正回答您的问题,使用当前的表结构,您可以通过在TableSourceVersions上创建唯一索引来保持完整性:

CREATE UNIQUE INDEX UQ_TableSourceVersions__IDSourceVersion_IDSource
    ON TableSourceVersions (IDSourceVersion, IDSource);

然后,您可以使外键引用两列确保选择有效版本,而不是使用IdCurrentVersionIdSourceVersion的外键。

ALTER TABLE [Source] ADD CONSTRAINT FK_Source__IdCurrentVersion_IDSource
    FOREIGN KEY (IdCurrentVersion, IDSource)
    REFERENCES TableSourceVersions (IDSourceVersion, IDSource);