Разработка базы данных для наследования Бизнес-правила - PullRequest
2 голосов
/ 26 октября 2011

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

У нас есть эти таблицы:

  ----------         --------          -------        --------       ----------     
 |Countries| 1---> * |States| 1--->*  |Cities|1 --->* |Offices|1--->*|Employees|
  ---------          --------         --------       ---------       -----------

Менеджер сможет определить максимальный дополнительный рабочий час (бизнес-правило) на каждом уровне (континенты, страны, ...).

Правила будут наследоваться от родителя к ребенку. и ребенок может переопределить это

Например, если менеджер определит, что Страна1 максимальный дополнительный рабочий час будет равен 4, то для всех сотрудников Страны1 их максимальный допустимый дополнительный рабочий час будет 4, и если менеджер определит CityXX, который находится в StateYY, а этот штат находится в Страна1 Макс будет 3, тогда все работники этого города (CityXX) их действительное дополнительное рабочее время будет 3.

Я надеюсь, что смогу разобраться. Мой вопрос: как вы реализуете такую ​​систему, правила которой будут унаследованы?

Edit :

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

Ответы [ 5 ]

1 голос
/ 27 октября 2011

Вы можете использовать материализованный подход на основе пути. Я написал здесь стандартный ответ: Сохраните ваши параметры конфигурации в виде иерархии в базе данных

1 голос
/ 26 октября 2011

Один из вариантов - хранить его только на одном уровне, чтобы он вообще не «наследовал».
Действительно ли это наследуемое имущество на уровне города или офиса или уровня сотрудников?Местное законодательство (например, Директива ЕС о рабочем времени) определяет его, а не менеджер.

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

  • У каждого дочернего элемента есть два столбца: maximumextraworkhour и IsLocalOvertimeRule (бит)
  • Изменения родительского нажатия с помощью триггера, где дочерний элемент IsLocalOvertimeRule = 0
1 голос
/ 26 октября 2011

Опираясь на решение GBN, один уровень будет оптимальным.Иерархия, которую вы описываете, может иметь приоритет по умолчанию, состояние 10, город 20 и т. Д.Пользователи могут переопределить, если необходимо, или, если иерархическое отношение является статическим, его можно просто закодировать в таблицу метаданных (RulePrecedence).

Вот пример запроса:

Select * from Rule Where [What Rule Is Needed] Order by Precedence

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

Я думаю, что это сработает, и схема не будет такой сложной.

Если естьне так много оценок, тогда запрос может быть простым.Если потенциально может быть тысячи «переопределений», то вы можете захотеть что-то вроде этого, чтобы ограничить возвращаемые «Правила»:

Select * from Rule Where Rule.Country = 'US' AND Rule.State = 'MA' And Rule.ID = 'MaxExtraWorkHour' Order By Precedence

Обратите внимание, что эти запросы только для примера.(Выбор * используется только для сохранения набора текста)

0 голосов
/ 27 октября 2011

Простота - это красота жизни, я согласен с ГБН Вы можете хранить MaxExtraHours на офисном столе, так что вам не нужно потрудитесь написать сложный запрос. В любом случае, если вы настаиваете на том, чтобы не изменять структуру, ваш запрос будет работать as coalesce возвращает первое ненулевое выражение среди своих аргументов.

0 голосов
/ 26 октября 2011

Моя первоначальная мысль состояла в том, чтобы иметь поле, которое содержит максимальное количество дополнительных рабочих часов на каждом уровне, а затем позволить соответствующим людям на каждом уровне установить это поле.Затем в соединении ваших таблиц вы должны объединить все свои таблицы и затем использовать COALECSE, чтобы получить первое поле, которое не было нулевым, начиная с самого конкретного и переходя к общему.*

SELECT
   COALECSE(o.MaxExtraHours, t.MaxExtraHours, s.MaxExtraHours, c.MaxExtraHours, 4) as MaxExtraWorkHours
FROM
   Countries c
INNER JOIN
   States s on c.ID = s.CountryID
INNER JOIN
   Cities t on s.ID = t.StateID
INNER JOIN
   Offices o on t.ID = o.CityID

Значение «4» является значением по умолчанию, но вы можете просто оставить его пустым или сохранить значение по умолчанию на каждом уровне, а затем начать переходить к значениям по умолчанию после того, как вы попробуете определенные поля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...