db design question

User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

db design question

Post by Sabina »

Помогите развеять сомнения..
На готовую базу работающего продукта просят добавить такую таблицу, которая будет определять зависимость ProjectTasks друг от друга. То есть хотят упорядочить какая задача должна выполняться сначала и какая потом.
Для этих целей вводят новую таблицу ProjectTaskPredecessor.
Здесь на картинке понятнее нарисовано
Image

Колонка predecessor - это те же taskID. То есть таблица ProjectTaskPredecessor определяет какие задачи должны быть выполнены (predecessors) до того как сама задача (taskID) начнет выполняться.
Получается 2 foreign keys из этой таблицы и оба к taskID таблицы ProjectTask.

По моему мнению введение такой таблицы в схему внесет кучу проблем из-за этих двух foreign keys, ведь весь софт написан без учета этих constraints, то есть он начнет валиться то там то здесь, а projectTask - это основная таблица по которой вообще загружается само приложение для данного userProfile ...

Вопроса два:
1) Согласны ли вы со мной?
2) Если да, не подкинете еще аргументов в защиту моей точки зрения.

Спасибо,
Сабина
testuser
Уже с Приветом
Posts: 1071
Joined: 18 Nov 2003 22:53
Location: MA

Post by testuser »

Потенциальные проблемы могут возникнуть, если будет зацикливание. При Insert или Uodate нужно проверять, чтобы этого зацикливания не было.

В принципе, такая технология применяется и является довольно гибкой, единственный недостаток - сложность построения запросов и долгое их выполнение. Но и достоинства на лицо - нет необходимости держать весь путь и обновлять его в случае изменений.
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

testuser wrote:Потенциальные проблемы могут возникнуть, если будет зацикливание. При Insert или Uodate нужно проверять, чтобы этого зацикливания не было.

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


А вот скажем такая ситуация. Эта таблица явно введена с целью определить какие-нибуль business rules, типа никто не может начать работать над проектом XX до тех пор, пока все predecessors не завершены.
А приложение работает так, что при каждом запуске, идет чтение из ProjectTask, а может быть и task re-assignment. А вдруг эти business rules будут держать таблицу?

Just a thought,
Sabina
testuser
Уже с Приветом
Posts: 1071
Joined: 18 Nov 2003 22:53
Location: MA

Post by testuser »

да, кстати, это все можно сделать в одной таблице, predecessor как отдельное поле.
В реляционных БД, к сожалению, нет понятия порядка, в котором идут данные, порядок определяется только значением полей. Так что вам в любом случае порядок нужно как-то определить. Это можно сделать связанным списком (как в предлагаемом решении) либо ввести дополнительное поле - порядок в проекте. Но с этим может быть проблема, когда нужно вставить запись
testuser
Уже с Приветом
Posts: 1071
Joined: 18 Nov 2003 22:53
Location: MA

Post by testuser »

Sabina wrote:А вот скажем такая ситуация. Эта таблица явно введена с целью определить какие-нибуль business rules, типа никто не может начать работать над проектом XX до тех пор, пока все predecessors не завершены.
А приложение работает так, что при каждом запуске, идет чтение из ProjectTask, а может быть и task re-assignment. А вдруг эти business rules будут держать таблицу?

Just a thought,
Sabina


Ну так бизнес-рулз будут скорее всего на чтение, а не на запись, держать таблицу не должны. Т.е. в начале проверяем, можно ли работать над проектом, если да - отдаем.
У меня в одном проекте была подобная система с бухгалтерскими счетами.
Вначале мы имели корень - валюту. Потом разные счета, которые могут иметь в себе либо дерево счетов, либо отдельный счет. Работало все прекрасно, проблем не было.
User avatar
JustMax
Уже с Приветом
Posts: 1476
Joined: 05 Dec 2000 10:01
Location: Vilnius -> Bonn

Post by JustMax »

testuser wrote:
Sabina wrote:А вот скажем такая ситуация. Эта таблица явно введена с целью определить какие-нибуль business rules, типа никто не может начать работать над проектом XX до тех пор, пока все predecessors не завершены.
А приложение работает так, что при каждом запуске, идет чтение из ProjectTask, а может быть и task re-assignment. А вдруг эти business rules будут держать таблицу?

Just a thought,
Sabina


Ну так бизнес-рулз будут скорее всего на чтение, а не на запись, держать таблицу не должны. Т.е. в начале проверяем, можно ли работать над проектом, если да - отдаем.
У меня в одном проекте была подобная система с бухгалтерскими счетами.
Вначале мы имели корень - валюту. Потом разные счета, которые могут иметь в себе либо дерево счетов, либо отдельный счет. Работало все прекрасно, проблем не было.


Я бы сделал еще одну колонку с fk на parent id а потом

select * from task connect by prior childid = parentid start with ?

и вы получите сразу всю иерархическую цепочку задач.
Причем если нужно отслеживать на незацикливаемость и уникальность прохода по таскам - могу подарить триггер - котроый это отслеживает :)
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

testuser wrote:Ну так бизнес-рулз будут скорее всего на чтение, а не на запись, держать таблицу не должны. Т.е. в начале проверяем, можно ли работать над проектом, если да - отдаем.
У меня в одном проекте была подобная система с бухгалтерскими счетами.
Вначале мы имели корень - валюту. Потом разные счета, которые могут иметь в себе либо дерево счетов, либо отдельный счет. Работало все прекрасно, проблем не было.


Спасибо, развеяли мои сомнения. А то я уже начала было нервничать, что опять очередной грех на свою душу повесила. Не люблю я эти все db schema changes, особенно после нормально работающей беты. А может так оно и происходит в большинстве случаев :(

Сабина
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

JustMax wrote:Я бы сделал еще одну колонку с fk на parent id а потом


В смысле внутри самой таблицы Predecessor fk c taskID на predecessor?

JustMax wrote:select * from task connect by prior childid = parentid start with ?
и вы получите сразу всю иерархическую цепочку задач.


А это что за синтаксис? Не нашла я такого "connect" в Transact_SQL :oops:

JustMax wrote:Причем если нужно отслеживать на незацикливаемость и уникальность прохода по таскам - могу подарить триггер - котроый это отслеживает :)


Ну как я могу отказаться от такого сооблазнительного предложения :lol:
nsabinaЭТsbcglobalДОТnet

Сабина
testuser
Уже с Приветом
Posts: 1071
Joined: 18 Nov 2003 22:53
Location: MA

Post by testuser »

Sabina wrote:Спасибо, развеяли мои сомнения. А то я уже начала было нервничать, что опять очередной грех на свою душу повесила. Не люблю я эти все db schema changes, особенно после нормально работающей беты. А может так оно и происходит в большинстве случаев :(

Сабина


Рефакторинг как правило приводит к лучшему дизайну и более надежно работающему приложению. Так что переделок не нужно бояться, главное чтобы они были в правильном направлении.
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

testuser wrote:Рефакторинг как правило приводит к лучшему дизайну и более надежно работающему приложению. Так что переделок не нужно бояться, главное чтобы они были в правильном направлении.


Ха! Не путайте рефакторинг с изменением функционала
Обычно изменение даже одного столбца в базе приводит к болезненному перелопачиванию stored procedures
Никакой разрухи нет. (с) Проф. Преображенский.
Lazy44
Уже с Приветом
Posts: 525
Joined: 01 May 2002 20:29
Location: CT->MA->TX->UT

Post by Lazy44 »

Я бы добавил одну колонку predcessor в таблицу ProjectTask и сделал эту колонку FK на TaskID. Тогда вторая таблица ProjectTaskPredcessorстанет не нужна.Получится обычная иерархия.
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

testuser wrote:да, кстати, это все можно сделать в одной таблице, predecessor как отдельное поле.


А это как раз может поломать приложение
А в схеме с 2-мя таблицами приложение будет продолжать работать по мере добавления функциональности
Но с точки зрения дизайна лучше конечно одна таблица
Никакой разрухи нет. (с) Проф. Преображенский.
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

Strannik223 wrote:
testuser wrote:Рефакторинг как правило приводит к лучшему дизайну и более надежно работающему приложению. Так что переделок не нужно бояться, главное чтобы они были в правильном направлении.


Ха! Не путайте рефакторинг с изменением функционала
Обычно изменение даже одного столбца в базе приводит к болезненному перелопачиванию stored procedures


Вот-вот Strannik, потому и не люблю все эти "моча в голову ударила базу поменять", особенно по нескольку раз в неделю. "Сразу надо было думать" (С)
С точки зрения процедур, наверное хорошо, что это все в отдельной таблице. Чтобы если что пойдет не так, убирать легче было.

Сабина
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

Lazy44 wrote:Я бы добавил одну колонку predcessor в таблицу ProjectTask и сделал эту колонку FK на TaskID. Тогда вторая таблица ProjectTaskPredcessorстанет не нужна.Получится обычная иерархия.


Там relationship one-to-many, то есть у одной task может быть несколько predecessors. То есть тут в одну таблицу не получится.

Сабина
User avatar
JustMax
Уже с Приветом
Posts: 1476
Joined: 05 Dec 2000 10:01
Location: Vilnius -> Bonn

Post by JustMax »

Sabina wrote:В смысле внутри самой таблицы Predecessor fk c taskID на predecessor?


Yep, ето работает только в том случае если у вас отношения One to Many, Many to One. Many to Many только в отдельную таблицу.

Sabina wrote:А это что за синтаксис? Не нашла я такого "connect" в Transact_SQL :oops:


Это Оракл - стандартные иерархические запросы. Я то думал что вы с Oracle работаете :oops: .В MS SQL , насколько я знаю , с этим пока тяжко.

JustMax wrote:Причем если нужно отслеживать на незацикливаемость и уникальность прохода по таскам - могу подарить триггер - котроый это отслеживает :)


Sabina wrote:Ну как я могу отказаться от такого сооблазнительного предложения :lol:
nsabinaЭТsbcglobalДОТnet


Он полностью основан на фишках оракла - plsql tables, иерархические запросы. Если все равно интересно как это в Оракле делаеться - в понедельник вышлю заказным письмом :D

Return to “Вопросы и новости IT”