Свяжите много дочерних таблиц с родительской таблицей - PullRequest
1 голос
/ 05 января 2012

Я сделаю все возможное, чтобы изложить это в тексте.По сути, у нас есть приложение, которое отслеживает действия пользователей.Каждое действие имеет свою собственную таблицу, поскольку каждое действие имеет различные параметры, которые необходимо сохранить.Это позволяет нам хранить эти дополнительные атрибуты и довольно легко запускать аналитику для действий нескольких или одного пользователя.Действия на самом деле не связаны друг с другом, кроме того, кем пользователь выполнял эти действия.

Пример:

  • ActionTableA Id |UserId |АтрибутA |Атрибут B
  • ActionTableB Id |UserId |АтрибутC |АтрибутD |АтрибутE
  • ActionTableC Id |UserId |AttributeF

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

Пример: ValueTable: Id |UserId |Значение |ActionType |ActionId

Как лучше всего связать значение в таблице значений с фактическим выполненным действием?Мы знаем тип действия (A, B, C), но с точки зрения разработки SQL я не вижу хорошего способа иметь индексированную связь между значениями действий в ActionsTable и самими действующими действиями.Единственное, что имеет смысл, это изменить ValueTable следующим образом:

ValueTable

Id |UserId |Значение |ActionType |ActionAId (FK Nullable) |ActionBId (FK Nullable) |ActionCId (FK Nullable)

Но проблема, с которой я столкнулся, заключается в том, что только один из 3 столбцов actionTableId будет иметь значение, остальные будут иметь значение Null.Кроме того, по мере добавления типов действий столбцы в таблице значений также будут.Наконец, чтобы программно найти данные, я бы либо: а) должен проверить ActionType, чтобы получить соответствующий столбец для идентификатора, либо б) отсканировать строку и выбрать ненулевой actionId.

Есть ли лучший способ / дизайн или это просто «так, как есть» для этой конкретной проблемы.

РЕДАКТИРОВАТЬ

Прикрепленный являетсядиаграмма вышеупомянутой установки:

enter image description here

Извините за вопросы ясности, ввод вопросов SQL всегда труден.Поэтому я думаю, что ваш комментарий дал мне представление о чем-то ... Я мог бы иметь таблицу SystemActionId, которая по существу имеет автоматически сгенерированное значение

SystemActions : Id |Введите

Затем каждый ActionTable будет иметь дополнительный FK к таблице SystemAction.Наконец, в ValueTable - свяжите его с таблицей SystemActions.Это позволило бы нам привязать ценности к конкретным действиям.Мне нужно было бы присоединить таблицы действий к таблице системных действий, где

JOIN (((SystemActions.Id = ActionTableA.Id) JOIN (SystemActions.Id = ActionTableB.Id)) JOIN (SystemActions.Id = ActionTableC.Id)

дерьмовый быстрый синтаксис sql

Это то, что вы былинамекает на ответ ниже?Снимок того, как это может выглядеть потенциально: enter image description here

Ответы [ 5 ]

1 голос
/ 05 января 2012

У вас есть структура супертипа / подтипа или эксклюзивная дуга. Атрибуты, общие для всех действий, всплывают в супертип (таблица «действия»). Столбцы, уникальные для каждого пузырька подтипа, «опускаются» в отдельные подтипы.

create temp table actions (
  action_id integer not null,
  action_type char(1) not null check (action_type in ('a', 'b', 'c')),
  user_id integer not null, -- references users, not shown.
  primary key (action_id),
  -- Required for data integrity. See below.
  unique (action_id, action_type)
);

create temp table ActionTableA (
  action_id integer primary key,
  -- default and check constraint guarantee that only an 'a' row goes
  -- in this table.
  action_type char(1) not null default 'a' check (action_type = 'a'),
  -- FK guarantees that this row matches only an 'a' row in actions.
  -- To make this work, you need a UNIQUE constraint on these two columns
  -- in the table "actions".
  foreign key (action_id, action_type) 
    references actions (action_id, action_type),
  attributeA char(1) not null,
  attributeB char(1) not null
);

-- ActionTableB and ActionTableC are similar.

create temp table ValueTable (
  action_id integer primary key,
  action_type char(1) not null,
  -- Since this applies to all actions, FK should reference the supertype,
  -- which is the table "actions". You can reference either action_id alone, 
  -- which has a PRIMARY KEY constraint, or the pair {action_id, action_type},
  -- which has a UNIQUE constraint. Using the pair makes some kinds of 
  -- accounting queries easier and faster.
  foreign key (action_id, action_type) 
    references actions (action_id, action_type),
  value integer not null default 0 check (value >= 0)
);

Для округления создайте обновляемые представления, которые объединяют супертип с каждым подтипом, и пусть все пользователи используют представления вместо базовых таблиц.

1 голос
/ 05 января 2012

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

0 голосов
/ 05 января 2012

Если вы хотите, чтобы это работало так, что для каждый раз пользователь выполняет действие A, вы вставляете новую строку в таблицу ActionTableA и строку в ValueTable и связываете их обоих, почему бы не иметьстолбец значений в каждой таблице действий?Это будет работать, только если вы хотите вставлять новую строку каждый раз, когда пользователь выполняет действие, а не если вы хотите обновить значение, если пользователь снова выполняет то же действие.Кажется слишком сложным иметь отдельную таблицу для значений, если она может храниться в столбце.С другой стороны, если «значение» - это набор различных частей данных (или если вы хотите, чтобы все значения были в одном месте), тогда вам нужна дополнительная таблица, но у меня все равно будет столбец внешнего ключа, указывающий на действиетаблицы в таблицу значений.

0 голосов
/ 05 января 2012

Я думаю, вам нужно что-то похожее на Audit Trail.Можем ли мы иметь простой дизайн, чтобы все действия были записаны в одном столе?

enter image description here

0 голосов
/ 05 января 2012

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

Являются ли столбцы атрибутов значимыми в контексте схемы?Не могли бы вы сжать его в столбце хранилища объектов «Атрибуты»?

Actions: actionID, type, attributes
...