Наследование данных или иерархический справочник неограниченной глубины, который всегда возвращает значение…

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Без справочников не обходится ни одна информационная система. Как правило, такие справочники представлены в виде одной либо нескольких таблиц, иногда связанных между собой. Одной из проблем является "неполнота" данных, когда справочник не заполнен по определенным позициям.

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

Пример подобной структуры:

|Id | ParentId | Name | Value | ,

где ParentId - ссылка на вышестоящий узел.

Глубина иерархии такого справочника не ограничена, так-же возможно неограниченное разветвление дерева.

Рассмотрим справочник адресов почты сотрудников предприятия.

|Id | ParentId | Name        | Value        |

|1  | null     | Предприятие | Наше предприятие |

|2  |  1       | E-mail      | factory@mail.ru |

Условный запрос вида Get({Предприятие="Наше предприятие"}, E-mail) выдаст значение "factory@mail.ru".

Добавим узел дерева справочника - Подразделение="Отдел ИТ" и к нему еще один узел

E-mail="it@mail.ru"

Теперь запрос Get({Предприятие="Наше предприятие", Подразделение="Отдел ИТ"}, E-mail) выдаст значение "bskb@mail.ru". Однако, если нет узла "Подразделение", либо значение не заполнено - значение будет взято из вышестоящего узла.

Если добавить узел дерева "Служба поддержки" и значение support@mail.ru со ссылкой на узел "Подразделение"="Отдел ИТ" - получим адрес службы поддержки, если он не существует - адрес отдела, и так далее выше по иерархии.

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

Второй пример - интернационализация приложения.

Для интернационализации приложения предлагается следующий подход:

  • в базе данных хранятся значения Caption и Hint для всех компонентов, используемых в приложении;

  • при запуске приложения они считываются из БД и заполняются соответствующие свойства компонентов;

  • для получения значения Caption и Hint запрос к БД делается в виде .

    ..;

  • для хранения Caption и Hint используется иерархическая структура справочника, который выдает значение "всегда", если нет значения в запрашиваемом узле справочник - будет выдано значение из вышестоящего уровня иерархии. Глубина иерархии такого справочника не ограничена, так-же возможно неограниченное разветвление дерева.

    Пример: Запрос Get(Application.Form1.Component2.Property3) выдаст значение из узла "Application", если нет значений для нижестоящего уровня иерархии,
    выдаст значение из узла "Form1" - если есть значение для этого уровня иерархии, и так далее.
    Таким образом можно, например, ввести значение Caption="Поиск" для кнопки с Origin="Find" для всего приложения, но для кнопки на форме "Form2" - использовать значение "Искать", а для кнопки "btnFindAll" - - использовать значение "Искать везде".
    Такой способ существенно экономит место в БД, так как хранится всего одно общее значение и исключения от него.

Структура таблицы:

CREATE TABLE t_caption_ru (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INT NULL DEFAULT '0',
owner VARCHAR(255) NOT NULL,
origin VARCHAR(255) NOT NULL,
caption VARCHAR(255) NOT NULL,
hint VARCHAR(255) NOT NULL,
INDEX Индекс 1 (id)
)
ENGINE=InnoDB
AUTO_INCREMENT=1;

Запрос для получения данных:

SET @origin='Find';
SET @LEVEL1='Application';
SET @LEVEL2='Form1';
SET @LEVEL3='btnFind';
/* Выдает первое значение, которое не NULL, то есть значение будет всегда, но с разных уровней иерархии */
SELECT COALESCE(t3.caption, t2.caption, t1.caption)
FROM t_caption_ru t1
LEFT JOIN t_caption_ru t2 ON (t2.parent_id=t1.id AND t2.owner @LEVEL22)
LEFT JOIN t_caption_ru t3 ON (t3.parent_id=t2.id AND t3.owner @LEVEL33)

WHERE
(t1.owner = @LEVEL1 AND t1.origin = @origin) or
(t2.origin = @origin) or
(t3.origin = @origin)

Источник: https://habr.com/ru/post/716462/


Интересные статьи

Интересные статьи

Особенность архитектуры 1С-Битрикс предполагает наличие контента как в базе (например: инфоблоки), так и непосредственно в статических файлах проекта.Данный формат создавал проблемы при совместной р...
Работая над различными интересными задачами, мне только и приходилось слышать о существовании программ, которые работают с большими данными (в области действия одного сервера). И вот настал тот день...
В данной статье рассматриваются данные о производстве, эксплуатации и продажах продукции производителя подключенных транспортных средств. Эти данные проходят разные этапы...
Тестирование как универсальный принцип Уже почти четверь века празднуем миллениум, а тестирование ещё только входит в нашу жизнь… Сложно убедить начинающих разработчиков использовать эту потряса...
Рассказываем об инструменте, который позволяет настроить API для работы с запросами PostgreSQL. Говорим о возможностях, достоинствах и недостатках утилиты, а также об альтернативных решениях. ...