Отношение один ко многим с использованием одной и той же таблицы SQL - PullRequest
2 голосов
/ 01 февраля 2010

Я нахожусь в процессе проектирования своей базы данных и одной из таблиц (задач), должна быть возможность иметь отношения один-ко-многим с самим собой. Это связано с тем, что в задаче может быть несколько подзадач с одинаковыми данными (очень похоже на вопрос и ответ по SO).

Я просто немного запутался из-за того, что у меня не очень сильный SQL, о том, как сделать один-ко-многим на одной и той же таблице.

В настоящее время у меня есть эти строки:

TaskId (уникальный идентификатор)
aspnet_OwnerUserId (уникальный идентификатор)
Название (nvarchar (50)) Описание (nvarchar (MAX))
StartDate (smalldatetime)
DueDate (smalldatetime)

Ответы [ 4 ]

4 голосов
/ 01 февраля 2010

Хотя я не совсем уверен, что вы собираетесь достичь, но в зависимости от того, что вы указали в качестве полей таблицы, я думаю, что отношение один ко многим с самой таблицей более уместно.

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)

Если вы хотите, чтобы подзадача имела несколько родительских задач, тогда, пожалуйста, забудьте о том, что я сказал. Тем не менее, один или несколько ответов могут быть даны на определенный вопрос, но не наоборот.

EDIT: Я бы предположил, что у вас будет другая таблица «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, для других СУБД, пожалуйста, не стесняйтесь изменять его.

3 голосов
/ 01 февраля 2010

Таблица пересечений (соединений) закодирована почти так же, как и следовало ожидать, только с двумя внешними ключами, указывающими на одну и ту же таблицу.

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 голосов
/ 01 февраля 2010

Если ваша аналогия похожа на вопрос и ответ по 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 состоит в том, что оба ограничения внешнего ключа указывают на одну и ту же таблицу (а на некоторых СУБД вы не сможете каскадировать их обе).

1 голос
/ 01 февраля 2010

Ну, вы можете сделать это как многие ко многим, но на самом деле это больше похоже на вложенный набор .

...