Как избежать дублирования данных в отношениях один-ко-многим - PullRequest
0 голосов
/ 16 мая 2019

Рассмотрим следующий случай:

есть таблица Action, в которой есть поля - id, start_time, end_time и group_id.

естьтаблица ActionGroup, в которой есть поля - id, start_time и end_time группы нескольких действий (обратите внимание, что действия выполняются последовательно).

ActionGroup имеет 1-к-много связей с Action.


, например:

, если имеется четыре Action записи,

enter image description here

соответствующая ActionGroup запись будет выглядеть следующим образом:

enter image description here


Кажется, что таблица Action уже содержит данные, которыеActionGroup таблица нуждается, и ActionGroup фактически повторяет ее.

Можно ли запросить время начала и время окончания ActionGroup простым и быстрым способом, без отдельной записи в журнал start_timeи end_time поля внутри ActionGroup?

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

Ответы [ 3 ]

1 голос
/ 16 мая 2019

Начнем с вашего последнего вопроса: дублирование данных плохо в том смысле, что оно создает риск несоответствия, например, если ваш ActionGroup 1 зарегистрирован с end_time из (скажем) 8, а Action с end_time 13. Если ваши данные противоречивы, вы не можете доверять результатам запроса, так как несовместимая логическая система может дать любой результат.

В вашем примере ActionGroup может быть получено из Action с использованием агрегированного запроса (псевдокод реляционной алгебры):

Action group by { group_id } add {
  Min(start_time) start_time,
  Max(end_time) end_time
}
rename { group_id id }

- поэтому вам не нужны эти атрибуты в Action relvar (таблица). Это просто; достаточно ли это быстро, зависит от ваших требований.

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

1 голос
/ 16 мая 2019

Я не думаю, что вам нужна таблица ActionGroup из вашего примера

Из вашего примера Action таблица уже содержит всю информацию для групп действий (group_id, start_time, end_time)

Вы можете просто использовать таблицу Action, чтобы получить min, max из start_time и end_time, но если вам нужно больше полей в ActionGroup и получить start_time и end_time для действий группы, попробуйте что-то вроде этого.

SELECT *
FROM `ActionGroup` as action_group
INNER JOIN (
  SELECT group_id, min(start_time), max(end_time)
  FROM ACTION
  GROUP BY group_id) as action
ON action_group.id = action.group_id

0 голосов
/ 16 мая 2019

Кажется, что таблица Action уже содержит данные, которые нужны таблице ActionGroup, и ActionGroup фактически повторяет ее.

Я думаю, что вы правы, выпросто повторяю это на основе вашего примера.Если вы используете ActionGroup только для хранения самого низкого (0) начального и максимального (13) конечного времени, поскольку Action уже имеет идентификатор_группы, вы можете легко получить начальное / конечное время с помощью

Select start_time in Action where group_id = '1' order by start_time;

Тогда у ActionGroup нет цели вообще, но если вы пытаетесь достичь чего-то большего, то я думаю, что было бы неплохо создать ActionGroup.

Например:

есть таблица ActionGroup, в которой есть поля - id, start_time и end_time группы из нескольких действий (обратите внимание, что действия происходят последовательно).

Если у вас есть действия с start_time: 4, 8, 2, 2, 10. Тогда мы знаем, что 2 будет храниться в ActionGroup, но что это такое Action?Затем вы можете сделать что-то вроде start_time_id вместо start_time.

Вот некоторые материалы для чтения для создания таблиц, которые могут вам помочь:

КАК ДИЗАЙН БАЗЫ ДАННЫХ SQL

Учебное пособие по структуре и дизайну базы данных

...