使用相同SQL表的一对多关系

时间:2010-02-01 05:20:49

标签: sql database-design one-to-many

我正在设计我的数据库,其中一个表(任务)需要能够与自己建立一对多的关系。这是因为任务可以有许多具有相同数据的子任务(很像SO上的问题和答案)。

由于我不是非常强大的SQL,我只是有点困惑,如何在同一张桌子上制作一对多。

目前我有这些行:

  

TaskId(uniqueidentifier)
  aspnet_OwnerUserId(uniqueidentifier)
  标题(nvarchar(50))   描述(nvarchar(MAX))
  StartDate(smalldatetime)
  DueDate(smalldatetime)

4 个答案:

答案 0 :(得分:4)

虽然我不太确定你要实现什么,但是根据你给出的表字段,我认为与表本身的一对多关系更合适。

TaskId (integer *Primary Key)
Ref_Id (integer *Foreign Key references to TaskId above)
ASPNet_OwnerUserId (integer)
Title (varchar/text)
StartDate (Date/Timestamp)
DueDate (Date/Timestamp)

如果你想让一个子任务有多个父任务,那么请忘记我所说的。也就是说,可以对某个问题做出一个或多个答案,但不是相反。

编辑: 我想你会有另一个表“aspnet_OwnerUser”,其中包含一些用户信息。如果是这种情况,请查看以下SQL。否则,算了吧。 ;)

CREATE TABLE `aspnet_OwnerUser`
(
    `id` SERIAL PRIMARY KEY
    , `name` VARCHAR(128)
    -- further detail follows
);

CREATE TABLE `task`
(
    `id` SERIAL PRIMARY KEY
    , `ref_id` INTEGER
        CONSTRAINT REFERENCES `task`(`id`)
    , `aspnet_OwnerUserId` INTEGER
        CONSTRAINT REFERENCES `aspnet_OwnerUser`(`id`)
    , `title` VARCHAR(128) NOT NULL
    , `startdate` TIMESTAMP
    , `duedate` TIMESTAMP
);

P.S。上面的SQL是为PostgreSQL编写的,对于其他DBMS,请随时改变它。

答案 1 :(得分:3)

交叉(交叉)表的编码几乎与您期望的一样,只有两个外键指向同一个表。

create table task_subtasks
 ( master_id number not null
   , sub_id number not null
   , constraint task_subtask_pk primary key (master_id, sub_id)
    , constraint task_subtask_master_fk foreign key (master_id)
         references tasks (taskid)
    , constraint task_subtask_sub_fk foreign key (sub_id)
         references tasks (taskid)
    )
/

修改

输入后,我想查询你的数据模型。我可以看到任务可以拥有许多子任务,但我不确定子任务如何属于许多主任务。你确定你真的不想要一对多的关系吗?

编辑2

当我写这篇编辑时,我看到你编辑了你的问题以回答这一点。

create table tasks (
TaskId number not null
, aspnet_OwnerUserId number not null
, subTaskId number
, Title (nvarchar(50))
, Description (nvarchar(MAX))
, StartDate (smalldatetime)
, DueDate (smalldatetime)
, constraint task_pk primary key (taskid)
, constraint sub_task_fk foreign key (subtaskid)
    references tasks (taskid)
)
/

答案 2 :(得分:2)

如果你的类比就像SO上的问答,那么这不是一个多对多的关系,而是一对多的关系。一个问题可能有几个答案,但答案只属于一个问题。映射它的最简单方法是:

表格 - 任务

TaskID uniqueidentifier NOT NULL,
ParentTaskID uniqueidentifier NULL,
(other fields)

然后创建从ParentTaskIDTaskID的自引用外键约束。

假设您出于某种原因确实需要M:M映射。这必须使用映射表来完成;自我引用M:M与涉及两个表的M:M没有任何不同:

表格 - 任务

TaskID uniqueidentifier NOT NULL,
(other fields)

表格 - 子任务

TaskID uniqueidentifier NOT NULL,
SubTaskID uniqueidentifier NOT NULL

在引用TaskID列的SubTaskID表中的SubTasksTasks (TaskID)上放置外键约束。这个和任何其他M:M关系的唯一区别是两个外键约束都指向同一个表(在某些DBMS上,你将无法级联它们)。

答案 3 :(得分:1)

嗯,你可以做多对多,但实际上它更像nested set