2

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

由于我的 SQL 不是很强大,我只是有点困惑,如何在同一张表上进行一对多。

目前我有这些行:

TaskId (uniqueidentifier)
aspnet_OwnerUserId (uniqueidentifier)
Title (nvarchar(50)) Description (nvarchar(MAX))
StartDate (smalldatetime)
DueDate (smalldatetime)

4

4 回答 4

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
);

ps 以上 SQL 是为 PostgreSQL 编写的,对于其他 DBMS,请随意更改。

于 2010-02-01T05:28:02.280 回答
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)
)
/
于 2010-02-01T05:30:33.117 回答
2

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

表 - 任务

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

ParentTaskID然后从to创建一个自引用外键约束TaskID

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

表 - 任务

TaskID uniqueidentifier NOT NULL,
(other fields)

表 - 子任务

TaskID uniqueidentifier NOT NULL,
SubTaskID uniqueidentifier NOT NULL

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

于 2010-02-01T05:36:40.310 回答
1

好吧,您可以将其作为多对多来执行,但实际上它更像是嵌套的 set

于 2010-02-01T05:24:04.487 回答