2

我应该将这些表合并到一张表中吗?有什么棘手的选择吗?

Table Unit for a Template table:


Id (PK)
ParentId
Name
TemplateId (FK)

Table Unit2 for a Testplan table:

Id (PK)
ParentId
Name
TestplanId (FK)

编辑:

为什么不做一张这样的桌子:

[UnitId] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [TemplateId] [int] NULL,
    [TestplanId] [int] NULL,
    [ParentId] [int] NULL,

更新2:

1 Template has N Unit
1 Template has N Testplan
1 Testplan has N Unit

这些是使用一个单元表的关系。但这只能与 Unit 表中的 TemplateId 和 TestplanId 一起使用。

4

6 回答 6

4

不,不应合并相似但不相关的表。

它们在外键列中有所不同。没有简单的方法来制作一个有时指向一个表,有时指向另一个表的外键。

在您的更新中,您通过添加两列(每个外键各一列)处理了这种情况,并且您使它们都可以为空。但是想象一下,您现在想要要求每个模板都只有一个模板 ID。TemplateId在您的原始设计中,您可以通过制作列轻松实现这一点NOT NULL。但是你不能在你的组合表中这样做,因为它会阻止你创建测试计划。

现在想象一下,如果有人添加了一个同时具有 aTestplanId和 a TemplateId... 的项目,这是您想要允许的吗?在您的旧设计中这是不可能的,但在您的组合表中可以做到。

这种情况可以通过添加CHECK约束来处理,但它会增加额外的复杂性,而几乎没有好处。

于 2012-06-20T19:50:28.050 回答
0

不,因为它们存储不相关的信息。
在您的示例中,模板和测试计划是完全不相关的实体,因此不应将它们组合到一个表中。

于 2012-06-20T19:53:47.217 回答
0

您可以轻松地将这两个表组合成一个包含以下列的表:

Id (PK)
ParentId
Name
TemplateId (FK) 
TestplanId (FK)

这是个好主意吗?这取决于。这两个表是否包含本质上相同的实体?如果这个问题很难回答,请考虑是否会在两个表上进行联合以满足查询。

两者都有一个 ParentId 列。父母总是和孩子属于同一类型吗?或者父母完全是另一回事?如果你有一个混合的树结构,那么你会想要一个表中的所有 id。如果您有两个不同的树结构,那么您可能需要两个不同的表。

同样,如果存在同时具有 TemplateId 和 TestplanId 的 id,那么将它们放在同一个表中可能是个好主意。同样,如果有两个都没有的 id,那么将它们全部放在一个表中可能是个好主意。

您可以在原始的两个表上放置外键约束,并坚持该键永远不会为 NULL。在单表版本中,您不能完全做到这一点。您可以添加一个约束,说明两个键中的至少一个(或恰好一个)为 NULL。

于 2012-06-20T19:58:25.040 回答
0

如果您的目标是模拟继承,我建议您先阅读有关鉴别器列的内容,然后相应地更改您建议的表。

如果您的目标是为许多实体提供一个通用的 Unit 表以共享,您可以尝试这样的操作:

create table UnitList (
      Id int not null primary key
)

create table Unit (
      Id int not null primary key
    , ParentId int null
    , Name nvarchar(50) not null
    , UnitListId int not null references UnitList (Id)
)

create table Template (
      Id int not null primary key
    , UnitListId int not null references UnitList (Id)
)

create table Testplan (
      Id int not null primary key
    , UnitListId int not null references UnitList (Id)
)

此时,您可能希望根据您的业务规则在 Unit 表上放置一些独特的约束。如果您希望 Unit 表中没有重复项,但希望允许一个单元出现在多个列表中,您也可以创建一个 UnitToList 联结。

于 2012-06-20T20:10:38.527 回答
0

即使两个表看起来非常相似且重复,我认为您不应该合并它们。虽然它们没有以任何方式连接,但它们意味着保持不同的表。

于 2012-06-20T20:25:55.483 回答
0

根据有问题的评论:

试图减少表的数量会混淆它们的预期目的。当你试图设计一个对象的关系数据库时,问自己两个关于每个关系的问题。AB吗?AB吗?

http://en.wikipedia.org/wiki/Is-a

http://en.wikipedia.org/wiki/Has-a

你有一系列的has-a关系。(具体来说,has-many)模板有单位。模板有测试计划。测试计划有单位(但是,正如您将看到的,不同的单位)

对于每一个has-many 关系,您将在属性表​​中添加一个外键列,例如,该单元将具有一个template_id。

Template
----------
id
<other columns>

TemplateUnit
----------
id
template_id (FK)
parent_id (FK) -- references same table?
name
<other columns>

Testplan 
----------
id
template_id (FK)
<other columns>

TestplanUnit
---------
id
testplan_id (FK)
parent_id (FK)
name
<other columns>

有了这样的模式,就不会混淆哪些表和哪些列与哪些其他对象相关。这也使查询变得非常容易。

SELECT *
FROM Template a
JOIN TemplateUnit b
    ON a.id = b.template_id
JOIN Testplan c
    ON a.id = c.template_id
JOIN TestplanUnit d
    ON c.id = d.testplan_id

现在您知道所有b列都是模板单元,所有d列都是测试计划单元。十分简单。

于 2012-06-21T18:08:26.380 回答