[PHP, Анализ и проектирование систем, SQL] Идеальный каталог, базовая библиотека
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Всем привет.У меня было несколько публикаций по теме Entity Attribute Value, сокращенно EAV (паттерн программирования для хранения произвольных данных). За прошедшее время я допилил библиотеку для работы с EAV, и хотел бы поделиться с вами своими наработками.В библиотеке реализован базовый сценарий:
- Создать сущность
- Создать атрибут
- Задать для сущности определённые атрибуты
- Задать значение для атрибутов (создать предмет)
- Сформировать хранилище для предметов в формате представления, материализованного представления, таблицы
- Вычислить значения фильтров для поиска по предметам
- Выполнить поиск по предметам
- Добавить новый предмет
- Добавить новый атрибут для сущности
- Изменить значение атрибута (изменить характеристику предмета)
Изменения данных в пунктах 8-10, автоматически отражаются в хранилище данных не зависимо от формата выбранного в пункте 5.Если кто то чувствует в себе интерес к этой теме, то предлагаю присоединиться к разработке.Если вам хочется получить опыт в программировании чуть больше чем очередной HellowWord, то для вас тоже можно придумать интересный челендж.Для тех кто не в курсе, EAV это когда нам не надо в ручную проектировать и создавать новую таблицу в БД приложения для хранения информации о новой бизнес сущности, потому что у нас уже есть три таблицы и нам этого хватает для всего. В моей реализации шесть таблиц. Если хочется хранить данные не только как строки, то тогда это будет семь таблиц и плюс по одной таблице на каждый тип данных, но не в этом суть статьи, речь не столько о реализации, сколько о proof of concept , который можно потрогать руками.Предыдущие публикации на эту тему:
- Идеальный каталог, набросок архитектуры
- Идеальный каталог, вариант реализации
- Идеальный каталог, оптимизация выборки данных
Как установитьДля работы библиотеки потребуется СУБД PostgreSQL9+ и PHP7.4+ (в теории код можно упростить до PHP5, но тогда не будет type hitting, что не камильфо)
- Скачать код из репозитория storage-for-all-things
- Развернуть СУБД с помощью sql скрипта из файла configuration/install-tables-and-roles.sql.example
- Настроить соединение с СУБД - отредактировать файл configuration/db_test.php.example
- Переименовать configuration/db_test.php.example в configuration/db_test.php
- Выполнить тест в файле tests/Integration/AutomatedProcessTest.php
Если все тесты прошли успешно, значит вы всё настроили без ошибок.Если какие то тесты упали, то значит мне надо править баги :) Буду благодарен за ваши баг репорты.Как использоватьКак использовать библиотеку вам будет понятно из кода и комментариев теста AutomatedProcessTest.Наружу из библиотеки торчит три ручки, три класса:
- Operator AllThings\ControlPanel\Operator
- Browser AllThings\ControlPanel\Browser
- Schema AllThings\ControlPanel\Schema
Класс Operator работает непосредственно с данными. Класс Browser позволяет просматривать данные. Класс Schema создаёт объект СУБД для хранения данных и для сохранения согласованности данных (обновления по необходимости).О какой согласованности речь ? Собственно данные хранятся в трёх таблицах, но для удобства доступа к данным их можно хранить в трёх разных формах: представление, материализованное представление или таблица. Отсюда возникает задача согласования данных в исходных трёх таблицах и в той форме которая была выбран для хранения.Если, с представлением, синхронизация происходит автоматически на уровне СУБД, то с материализованным представлением и таблицей, необходимы дополнительные действия. За их выполнение отвечает класс Schema.Класс OperatorЭтот класс позволяет:1 Создать сущность (чертёж для создания предметов)
public function createBlueprint(
string $code,
string $storageKind = Storable::DIRECT_READING,
string $title = '',
string $description = ''
): IEssence
2 Создать атрибут (характеристика предмета)
public function createKind(
string $code,
string $dataType,
string $rangeType,
string $title = '',
string $description = ''
): IAttribute
3 Для сущности добавить атрибут
public function attachKind(string $essence, string $kind): Operator
4 Создать предмет
public function createItem(
string $essence,
string $code,
string $title = '',
string $description = ''
): Nameable
5 Задать значение для атрибута (задать значение для характеристики предмета)
public function changeContent(
string $thing,
string $attribute,
string $content
)
6 Добавить предмету новый атрибут (задать значение для новой характеристики предмета)
public function expandItem(
string $thing,
string $attribute,
string $value
): Operator
Используя эти шесть функций, мы можем вести базу данных нашего Универсального каталога, базу данных предметов.Но когда мы затевали наш Универсальный каталог, нашей задаче было не только создание базы данных с характеристиками предметов, прежде всего мы хотим наши данные отдавать на просмотр, в этом нам поможет класс Browser.Класс Browser
- Вычислить параметры поиска
- Выполнить поиск по заданным параметрам
1 Получить фильтры для выполнения поиска
public function filters(string $code): array
Фильтры вернуться в формате массива, который придётся разбирать руками, ни каких DTO для облегчения понимания не было сделано, извините, такие издержки у proof of concept.2 Выполнить поиск по заданным параметрам
public function filterData(string $code, $filters = []): array
Данные вернуться как массив, что делать с этим массивом пусть решает вызывающий код.Фильтры передаются как массив экземпляров классов AllThings\SearchEngine\ContinuousFilter и AllThings\SearchEngine\DiscreteFilter, это ещё два класса которые торчат из библиотеки, можно было конечно обойтись массивом со своей системой индексов, но в этом случае я не поленился и сделал DTO.Как задать параметры фильтрации можно посмотреть в тесте tests/Integration/AutomatedProcessTest.php.Я рассказал о том как задать данные и как их выгрузить, теперь мне осталось рассказать о том как данные быстро выдать и как данные быстро изменить. Всё это задачи класса Schema.Класс SchemaОсновное назначение этого класса, это:
- Создать на основе сущности (на основе атрибутов) объект СУБД для хранения значений
- Обновить значение в объекте СУБД при изменении значения атрибута сущности (конкретного предмета)
1 Создать хранилище для значений атрибутов
public function setup(): Schema
Что будет сделано ? Будет проверено какая форма был выбрана для хранения данных, это может быть:
- Storable::DIRECT_READING - view
- Storable::RAPID_OBTAINMENT - materialized view
- Storable::RAPID_RECORDING - table
Далее будет создан соответствующий объект СУБД, и он будет заполнен данными в соответствии с тремя базовыми таблицами.2 Обновить значение при изменении этого значения в базовой таблице
public function refresh(?ICrossover $value = null): Schema
Тут мы видим ещё один класс, который просочился наружу из нашей библиотеки. ICrossover это интерфейс который хранит значение атрибута для конкретного предмета.Что произойдёт при вызове этого метода ? будет определена форма хранения данных и эти данные будет соответствующим способом обновлены.Если мы хотим что бы было обновлено только это значение, то в ICrossover следует передать новое значение атрибута, если значение не передать, то хранилище значений будет обновлено полностью.Последний нюанс о котором надо обязательно упомянуть, это то как мы сообщаем системе о том в какой форме мы хотим хранить наши данные для быстрого доступа.3 Задать форму хранения данных
public function changeStorage(string $storageKind): Schema
Как было сказано выше, формой может быть одна из следующих:
- Storable::DIRECT_READING - view
- Storable::RAPID_OBTAINMENT - materialized view
- Storable::RAPID_RECORDING - table
О выборе формыВ статье Идеальный каталог, оптимизация выборки данных я приводил показатели быстродействия по всем формам.К этому можно добавить, то что форма представления и материализованного представления возможна только для хранения данных внутри одной БД. В то время как форма таблицы делает возможным хранение данных в отдельной СУБД.Сейчас конечно библиотека не даёт такой возможности, но это только proof of concept, который можно развить как угодно.Замеры производительностиНе будет замеров. Конечно без них статья сильно теряет в ценности. Но что бы написать тесты с профилированием потребуется один полноценный рабочий день и прямо сейчас я не обладаю такой роскошью.Откладывать публикацию очень не хочется и так вся эта история растянулась на три года :)ПланыКак вы могли заметить в статье речь идёт только о добавлении данных: добавить сущность, добавить атрибут, добавить значение, ни разу не было речи о том что бы что то удалить.Удаление на самом деле не реализовано, сделать не долго, но для proof of concept не требуется. Для использования в работе в библиотеке много не хватает, поэтому я для себя не вижу смысла доводить её до ума. Если кому то захочется, то пожалуйста, давайте сделаем. Мне для самого себя это не нужно.Мои контакты у меня в профиле и в репозитории.В будущем возможно соберусь и подробней распишу использование библиотеки с конкретным примером, или напишу тесты и померяю время выполнения операций. Зависит конечно от реакции и выбора сообщества.Спасибо за внимание.
===========
Источник:
habr.com
===========
Похожие новости:
- [Анализ и проектирование систем] Погрузиться в поиск музыкальной информации [MIR] — книги, которые помогут сделать это
- [Анализ и проектирование систем, IT-инфраструктура, Управление проектами, Веб-аналитика, Бизнес-модели] 6 функций, которые нужны интернет-аптеке
- [Информационная безопасность, PostgreSQL, Go] Избавляемся от паролей в репе с кодом с помощью HashiCorp Vault Dynamic Secrets
- [Анализ и проектирование систем, Работа с 3D-графикой, CAD/CAM, Софт] Российские BIM-технологии: проектирование наружных инженерных сетей в Model Studio CS
- [Анализ и проектирование систем, Графические оболочки, CAD/CAM] Анализ внешнего потока в SOLIDWORKS Flow Simulation
- [Анализ и проектирование систем, Управление разработкой, Управление проектами, Карьера в IT-индустрии] Bus-фактор в работе аналитика. Как экстренно погрузиться в проект и не перегореть от объема задач
- [Laravel] Проверка тестов PHP API на соответствие определениям OpenAPI — пример Laravel
- [Настройка Linux, Open source, Виртуализация, Kubernetes] 13 инструментов для разработчиков, шпаргалка по Linux команде apt, вводный курс по Kubernetes Operators и многое другое
- [Анализ и проектирование систем] Как описать архитектуру продукта по нотации C4 (перевод)
- [Программирование, Анализ и проектирование систем, Совершенный код, Проектирование и рефакторинг, ООП] Метрика Cognitive complexity или простой способ измерить сложность кода
Теги для поиска: #_php, #_analiz_i_proektirovanie_sistem (Анализ и проектирование систем), #_sql, #_eav, #_php, #_analiz_i_proektirovanie_sistem (
Анализ и проектирование систем
), #_sql
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 10:56
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Всем привет.У меня было несколько публикаций по теме Entity Attribute Value, сокращенно EAV (паттерн программирования для хранения произвольных данных). За прошедшее время я допилил библиотеку для работы с EAV, и хотел бы поделиться с вами своими наработками.В библиотеке реализован базовый сценарий:
public function createBlueprint(
string $code, string $storageKind = Storable::DIRECT_READING, string $title = '', string $description = '' ): IEssence public function createKind(
string $code, string $dataType, string $rangeType, string $title = '', string $description = '' ): IAttribute public function attachKind(string $essence, string $kind): Operator
public function createItem(
string $essence, string $code, string $title = '', string $description = '' ): Nameable public function changeContent(
string $thing, string $attribute, string $content ) public function expandItem(
string $thing, string $attribute, string $value ): Operator
public function filters(string $code): array
public function filterData(string $code, $filters = []): array
public function setup(): Schema
public function refresh(?ICrossover $value = null): Schema
public function changeStorage(string $storageKind): Schema
=========== Источник: habr.com =========== Похожие новости:
Анализ и проектирование систем ), #_sql |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 10:56
Часовой пояс: UTC + 5