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

发布于 2024-08-20 00:05:04 字数 307 浏览 13 评论 0原文

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

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

目前我有这些行:

TaskId(唯一标识符)
aspnet_OwnerUserId(唯一标识符)
标题 (nvarchar(50)) 描述 (nvarchar(MAX))
开始日期(小日期时间)
DueDate(小日期时间)

I'm in the process of designing my database and one of the Tables (Tasks), needs to be able to have a one-to-many relationship with itself. This is because a task can have a number of sub-tasks that have the same data (much like a question and answer on SO).

I'm just a little confused, due to my not very strong SQL, as to how to make a one-to-many on the same table.

Currently I have these rows:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

放低过去 2024-08-27 00:05:04

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

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,请随意更改。

While I am not very sure what you are going to achieve, but depending on what you've given as the table fields, I think a one-to-many relationship with the table itself is more appropriate.

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)

If you want a subtask to have multiple parent tasks, then please forget what I have said. That said, one or more answers can be made to a certain question, but not the other way around.

EDIT:
I would suppose you are going to have another table "aspnet_OwnerUser" which holds some user info. Please take a look of the follow SQL if that's the case. Otherwise, forget it. ;)

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. the above SQL is written for PostgreSQL, for other DBMS, please feel free to alter it.

对不⑦ 2024-08-27 00:05:04

交集(联结)表的编码与您所期望的非常相似,只是有两个外键指向同一个表。

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

The intersection (junction) table is coded pretty much as you would expect, only with two foreign keys pointing at the same table.

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

edit

Having typed that up, I would like to interrogate your data model. I can see that a task can own many sub-tasks, but I am not sure how a sub-task can belong to many master tasks. Are you sure you don't really want a one-to-many relationship?

edit 2

While I was writing that edit I see you edited your question to answer that point.

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)
)
/
清风挽心 2024-08-27 00:05:04

如果你的类比就像 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

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

If your analogy is like a question and answer on SO then this is not a many-to-many relationship, it is a one-to-many relationship. One question may have several answers, but an answer belongs to one and only one question. The simplest way to map this is:

Table - Tasks

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

Then create a self-referencing foreign key constraint from ParentTaskID to TaskID.

Let's say that for some reason you really do need a M:M mapping. That has to be done using a mapping table; a self-refeferencing M:M isn't really any different from a M:M involving two tables:

Table - Tasks

TaskID uniqueidentifier NOT NULL,
(other fields)

Table - SubTasks

TaskID uniqueidentifier NOT NULL,
SubTaskID uniqueidentifier NOT NULL

Place a foreign key constraint on both TaskID and SubTaskID in the SubTasks table that references the Tasks (TaskID) column. The only difference between this and any other M:M relationship is that both foreign key constraints point to the same table (and on some DBMSes, you won't be able to cascade both of them).

︶葆Ⅱㄣ 2024-08-27 00:05:04

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

Well you could do this as a many-to-many but really its more like a nested set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文