Эволюционирующая схема БД

43 %
57 %
Information about Эволюционирующая схема БД
Technology

Published on February 16, 2014

Author: interlabs-ru

Source: slideshare.net

Description

Как сделать схему базы данных приложения более универсальной? Что можно сделать на уровне схемы для того, чтобы сделать ее более адаптируемой к изменениям ТЗ по мере развития проекта? Какие стереотипы при при проектировании схемы мешуют достижению этих задач?

Эволюционирующая схема БД Sustainable Database Schema Interlabs 14 февраля 2014 1 / 28

Что мы хотим • единая базовая • • • • • схема для различных проектов компонуемая из отдельных функциональных блоков адаптируемая к особенностям проекта эволюционирующая вместе с проектом эволюционно масштабируемая и оптимизируемая самодостаточная, не требующая для работы дополнительных клиентских средств Sustainable Database Schema 2 / 28

Сферический проект в вакууме • набор различных типов сущностей с собственным • • • • атрибутным составом: продукты, страницы, новости, теги и т.д. семантические связи между сущностями в том числе — таксономия: группы товаров, теговая классификация и т.д. часто — произвольный набор свойств (E.A.V.) для некоторых типов: свойства продуктов, товарных предложений и т.д. различные типовые сервисы: комментарии, рейтинги, контент и т.д. Сущности + связи + таксономия + наборы свойств + общие сервисы 3 / 28

Тривиальная схема Каждая сущность в отдельной таблице с AUTO_INCREMENT. Сущности изолированы внутри таблиц за счет локальности идентификатора. 4 / 28

Проблемы тривиальной схемы • сложность реализации общих универсальных сервисов: комментирование и рейтингование сущностей, поиск по сайту и т.д. • сложность построения связей между разнородными сущностями: с этим товаром покупают, новости о товаре, читай также и т.д. • EAV-поля для разнородного контента (если нужен EAV). Главная проблема: своя последовательность id для каждого типа • нельзя однозначно идентифицировать сущность • нельзя сослаться на произвольную сущность 5 / 28

Глобальный идентификатор • единая последовательность для всех сущностей; • глобальность id определяется алгоритмом генерации • ссылочная целостность — общая таблица сущностей 6 / 28

Таблица сущностей • заполняется автоматически при вставке в частные таблицы • type определяет тип сущности, можно использовать ENUM; • внешние ключи с частных таблиц — каскадное удаление при удалении из общей таблицы; • дополнительные триггеры на удаление из частных таблиц; • если необходимо — дополнительные поля, характеризующие сущность в целом (даты создания и изменения, права доступа и т.д.) Если таблица ведется полностью автоматически, можно использовать даже на legacy-проектах. 7 / 28

Общая структура Общий аспект сущностей = отдельная таблица. 8 / 28

Общая структура • наличие единой последовательности id позволяет легко расширять функциональность сущностей; • у разных видов сущностей могут быть общие аспекты: отображаемый ресурс, результат поиска, категория и т.д.); • факт наличия сущности в таблице определяет наличие у нее соответствующего аспекта; • если необходимо, таблица аспекта может содержать поле с типом сущности для упрощения обработки; • общие сервисы используют общую таблицу сущностей для ссылочной целостности. 9 / 28

Генерация общего id AUTO_INCREMENT в entity • уникален в пределах набора таблиц, последователен • клиент без изменений кроме непосредственно вставки • наиболее подходящий вариант для legacy проектов UUID_SHORT() • • • • • глобально уникален, последователен теоретически подходит для миграции данных можно использовать вообще для всех таблиц необходима поддержка на уровне клиентского кода помним о размерности int на клиенте 10 / 28

AUTO_INCREMENT в entity • перед вставкой в рабочую таблицу — вставка в entity • используем полученный id в качестве первичного ключа для рабочей таблицы Как получить id на клиенте? LAST_INSERT_ID больше не подходит, поэтому либо: • два INSERT со стороны клиента, первый возвращает id • хранимая процедура на сервере, выполняет два INSERT, возвращает id в качестве результирующей выборки. 11 / 28

UUID_SHORT() Триггер BEFORE INSERT в рабочей таблице: IF NOT ‘NEW‘.‘id‘ THEN SET ‘NEW‘.‘id‘ = UUID_SHORT(); INSERT INTO ‘entity‘(‘id‘, ‘type‘) VALUES( ‘NEW‘.‘id‘, ’PRODUCT’); END IF; • на клиенте явно получаем UUID_SHORT() и используем при вставке в рабочую таблицу; • при работе с базой напрямую просто делаем вставку, entity заполняется автоматически. 12 / 28

Связи между сущностями Чем более семантически связен контент, тем больше связей между различными сущностями: товар принадлежит категории, с этим товаром покупают, другие товары бренда, аналоги товара, новости про этот товар и т.д. • максимум возможных связей при минимальной схеме • ссылочная целостность и каскадное удаление для упрощения клиента Нужно описывать связи на общем уровне. 13 / 28

Таблица связей 14 / 28

Таблица связей • type определяет вид связи (проще всего — ENUM) • sourceType и targetType дублируют типы сущностей • внешний ключ по id и типу — ссылочная целостность • поля типов могут быть использованы для контроля допустимости отношения триггером • каскадное удаление отношений при удалении сущностей • наличие таблицы связей не означает, что все cвязи нужно устанавливать через эту таблицу • однако автоматическое дублирование связей вида 1→N может быть полезно, если по мере развития проекта они превращаются в M→N. 15 / 28

Связи 1 → N Наличие таблицы связей не означает, что все связи через нее: • постановка предусматривает 1 → N между сущностями — работаем с ссылочным полем • есть шанс, что со временем отношение станет N → M — автоматически дублируем отношение в таблице связей Результат: ничего не теряем с точки зрения сложности клиента, получаем страховку на случай смены ТЗ, иногда выгодно трактовать ссылку как общее отношение. ДА товар → группа товаров. НЕТ товарное предложение → товар. 16 / 28

Таксономия Сущности классифицируются другими сущностями, например: • группы товаров • производители товаров • теги (для всех видов сущностей) и т.д. Много различных вариантов категоризации по мере развития проекта, поэтому реализуем на общем уровне: • • • • • категория — вид сущности (таблицы entity + category) древовидность в таблице category связь N → M через relations категория — аспект сущности принадлежность категории — отношение 17 / 28

Таксономия 18 / 28

Entity Attribute Value • для данных фиксированной структуры всегда используем обычные таблицы, часто выгодно вынести отдельный аспект данных в отдельную таблицу • используем EAV когда это действительно нужно (например, каталог товаров) • не привязываем EAV к конкретному виду сущности — никогда не знаешь, что будет потом • эффективный поиск — с использованием Sphinx EAV — общий сервис для всех сущностей 19 / 28

Универсальный EAV 20 / 28

EAV: атрибуты NUM число, STR строка, DAT дата, REF справочник • четырех типов достаточно, например, для импорта CommerceML • для каждого типа — свое поле для хранения значения • другие поля — для денормализации, если это имеет смысл • атрибуты нужно группировать в наборы для облегчения администрирования • набор атрибутов — категория, отношение «категория → атрибут» — 1 → N или N → M 21 / 28

EAV: ссылочные атрибуты Наличие значения ссылочного атрибута = классификация по этому значению • значение ссылочного атрибута — сущность • значение ссылочного атрибута — категория, привязанная к атрибуту (дополнительное поле в category) • category — справочник атрибутов • установка ссылочного атрибута дублируется в relation Две точки зрения на ссылочный атрибут: значение свойства (attribute_value) и классификация (relation). 22 / 28

Фасетный поиск Таксономия: индекс Sphinx c MVA-атрибутом по таблице relations Атрибуты: индекс Sphinx с JSON-атрибутами по таблице attribute_value • для ссылочных атрибутов можно обойтись одним индексом по relation • числовые атрибуты может быть выгодно преобразовать в ссылочные, разбив значения на диапазоны. Единая трактовка таксономии и ссылочных атрибутов может упростить поиск. 23 / 28

Счетчики и каскад Каскадное удаление существенно упрощает клиент, но нужно использовать осмотрительно, избыточный cascade может вычистить половину базы: delete="cascade" delete="restrict" Для удаления элементов Для запрета удаления сущности: значения атрибутов связанных сущностей: группы сущности, отношения или бренда при наличии сущности. товаров и т.д. Проблема: без дополнительных запросов определить наличие restrict на клиенте, для блокировки действия. 24 / 28

Поле счетчика • должно заполняться автоматически триггерами • для 1 → N есть стандартное расширение в baser: <Table name="comment_reply" comment="Комментарии"> <Column name="thread" type="&id;" comment="Тред"/> <ForeignKey name="thread" table="thread" comment="ссылка на тред" ext:count="numOfReplies" <- триггеры генерируются автоматически > 25 / 28

API схемы База должна быть самодостаточна, поэтому: • типовые операции, не укладывающиеся в одно SQL-выражение, выносим в хранимые процедуры; • периодическое обслуживание базы (архивирование, удаление неактуальных данных и т.д.) выносим в events; • весь хранимый код формирует API схемы, в будущем — документируемый средставами baser; • API — не только для приложения, но и для человека, работающего с базой руками. Иногда реализация хранимой — способ избежать больших изменений на legacy-клиентах (пример с хранимой для создания сущности). 26 / 28

Использование baser • проще писать большое количество хранимого кода • часть хранимого кода и структуры генерируется автоматически расширениями • можно (и нужно!) унифицировать определения типов данных внутри схемы: <!DOCTYPE Schema [ <!ENTITY entities <!ENTITY attributes <!ENTITY id <!ENTITY name ]> ... <Column name="type" <Column name="name" ... "ENUM(’PRODUCT’, ’CATEGORY’, ’FAQ’, ’FILE’, ’NEWS’)"> "ENUM(’NUM’, ’STR’, ’DAT’, ’REF’)"> "MEDIUMINT UNSIGNED"> "VARCHAR(255)"> type="&entities;" ... /> type="&name;" .../> 27 / 28

Итого • небольшой базовый набор концепций, расширяющий традиционную схему, повышает ее приспособляемость к изменениями ТЗ; • AUTO_INCREMENT — удобный антипаттерн; • важно мыслить не сущностями в целом, а суммой их отдельных аспектов; • даже для legacy-проектов можно извлечь выгоду, в частности, при организации поиска; • элементы CMS могут быть реализованы непосредственно в базе без, собственно, CMS. 28 / 28

Add a comment

Related presentations

Related pages

Поддержка идентичности ...

Поддержка идентичностиструктуры БД при ... Эволюционирующая схема ...
Read more

рит2007 оптимизация бд бесков ...

Распределение файлов БД и журналов . Буферы памяти . ... Эволюционирующая схема БД
Read more

БД 43,102,07 - Documents

БД 43,102,07 МОНГОЛ УЛСЫН СТАНДАРТ Ангилалтын код 27.010 Орон сууцны барилгын цахилгааны ...
Read more

DB specific ORM / Страница 72 ...

DB specific ORM / Проектирование БД / Arhat109ViPRos,во, теперь понятно. Большая часть вопросов ...
Read more

Сущность и назначение СППР

+ Системы анализа данных- обеспечивают доступ к БД и ... Эволюционирующая ... схема СППР ...
Read more