我应该组合两个只有一个字段有差异的sql表

时间:2012-06-20 19:47:35

标签: sql entity entity-relationship mysql

我应该将这些表合并到一个表中吗?是否有任何棘手的选择?

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,

UPDATE2:

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

这些是使用一个Unit表的关系。但这只适用于Unit表中的TemplateId和TestplanId。

6 个答案:

答案 0 :(得分:4)

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

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

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

现在想象一下,如果有人添加了同时包含TestplanIdTemplateId的项目,那么您想要允许的内容是什么?在您的旧设计中,这是不可能的,但在您的组合表中可以完成。

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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

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

两者都有ParentId列。父母总是和孩子一样吗?或者父母是完全不同的东西?如果你有一个混合树结构,那么你会希望在一个表中的所有id。如果您有两种不同的树结构,那么您可能需要两个不同的表。

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

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

答案 3 :(得分:0)

如果您的目标是模仿继承,我建议先阅读discriminator columns,然后相应地更改您建议的表格。

如果您的目标是为许多实体提供共享的公共单位表,您可以尝试这样的事情:

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连接。

答案 4 :(得分:0)

即使两个表看起来非常相似和重复,我认为你不应该合并它们。虽然它们没有任何联系,但它们意味着保持不同的表格。

答案 5 :(得分:0)

以下评论意见:

尝试减少表的数量会混淆其预期目的。当您尝试设计对象的关系数据库时,请问自己关于每个关系的两个问题。 A B 吗? A 是否有 B

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

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

你有一系列的关系。 (具体来说,有很多)模板有单位。模板有测试计划。测试计划有单位(但是,你会看到,不同的单位)

对于每个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 列都是testplan单位。容易腻。