我正在设计我的数据库,其中一个表(任务)需要能够与自己建立一对多的关系。这是因为任务可以有许多具有相同数据的子任务(很像SO上的问题和答案)。
由于我不是非常强大的SQL,我只是有点困惑,如何在同一张桌子上制作一对多。
目前我有这些行:
TaskId(uniqueidentifier)
aspnet_OwnerUserId(uniqueidentifier)
标题(nvarchar(50)) 描述(nvarchar(MAX))
StartDate(smalldatetime)
DueDate(smalldatetime)
答案 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)
然后创建从ParentTaskID
到TaskID
的自引用外键约束。
假设您出于某种原因确实需要M:M映射。这必须使用映射表来完成;自我引用M:M与涉及两个表的M:M没有任何不同:
表格 - 任务
TaskID uniqueidentifier NOT NULL,
(other fields)
表格 - 子任务
TaskID uniqueidentifier NOT NULL,
SubTaskID uniqueidentifier NOT NULL
在引用TaskID
列的SubTaskID
表中的SubTasks
和Tasks (TaskID)
上放置外键约束。这个和任何其他M:M关系的唯一区别是两个外键约束都指向同一个表(在某些DBMS上,你将无法级联它们)。
答案 3 :(得分:1)
嗯,你可以做多对多,但实际上它更像nested set。