Comments 28
Кстати, с in-memory database вопрос денормализации обычно не стоит. Исполнение JOIN суть разыменование указателей в памяти, эта операция тоже чего-то стоит, но безобразно дёшева в сравнении с disk-based JOIN-ами. Я конечно понимаю, big data и все дела, данные не влезают в память. Но во многих бизнес-приложениях «большая база» — это 50-80 Гб. Это уже всё влезает спокойно. 128 Gb сервер совершенно нормально. Ну и опять же, окей, положите своп на быстрый SSD и дайте ей туда немного залезть, тоже ничего страшного. В таком случае, вместо того чтобы кушать кактус и денормализовывать / избыточно материализовать таблицы, проще перейти на true in-memory и получить возможность быстренько все эти данные запрашивать на чтение вдоль и поперёк, и одновременно работая с ними на запись, всё в одном флаконе.
Так почти все базы пытаются держать все в памяти, если возможно
Это верно, но это не одно и то же. Алгоритмика очень разная. Можно запустить тест, скажем, на агрегацию и простеньким джойном, с классическим MS Sql Server и рядом с чем-нибудь типа MemSQL или VoltDB, и посмотреть. Памяти там много не потребуется, даже на 100 Мб данных разница будет разы или десятки раз. При разрастании числа джойнов это дело уйдёт в сотни раз разницы. Дело не в объёме памяти, а в том, как база работает с хранилищем. После можно попробовать другое упражнение, написать это в хранимке на Ms Sql Server 2014-2016 Hekaton (in-memory table). Hekaton закомпилит это дело и исполнит как нативную DLL внутри процесса in-memory таблицы. В сравнении с обычной Ms Sql Server таблицей разница будет очень заметна. Если бы всё было так просто с памятью и классической БД, то и никакого Hekaton Microsoft не стал бы добавлять в продукт.
ZOXEXIVO развёрнутый ответ на вашу точку зрения из современного курса по базам данных от создателя H-Base, маэстро Andy Pavlo:
Ручная денормализация — почти всегда крайне плохая идея.
В РСУБД есть механизмы материализованных представлений, вычисляемых столбцов и индексов, по ним и другие способы выполнить расчеты в момент записи, а не в момент запроса.
Что касается прав доступа, то обычно права ("утверждения", claims) пользователя кешируется в приложении и проверяются простыми предикатами. Денормализовывать их — плохая идея, особенно есть рекурсия групп.
Согласен, materialised view в теории должен решать означенные в статье проблемы. Если это read-only views — всё тип-топ на самом деле. Если же надо писать туда, на практике выходит, что реализации updatable views имеют много тонкостей, с которыми надо жить.
А зачем апдейтить материализованные представления? Они сами обновляются (или командой в Postgres) при обновлении данных.
имеется в виду, что insert/update идут в тот же вид, из которого было чтение, а не в нормализованные таблицы.
А зачем такое?
Если не надо инкапсулировать нормализованное представление и все части приложения знают всё о базе данных (обернули в один большой Repository и подобные паттерны) — то вроде и не требуется.
А зачем может понадобится инкапсулировать материализованное представление?
Например, несколько систем, разработанных различными группами, будучи установленными, используют одну базу. Внутри этой базы сидит нормализованное представление, разработанное главным БД архитектором. Однако же системы обращаются с данными исключительно через VIEWs. Тем самым достигается decoupling между приложениями и архитектурой базы. Можно не менять приложения и VIEWs, но постоянно работать над внутренним нормализованным представлением и мигрировать его через версии схемы. Separation of concerns на уровне БД.
Еще раз — зачем писать в ДЕНОРМАЛИЗОВАННОЕ представление?
Зачем писать в нормализованное и так понятно.
В случае если денормализованное представление — это единственное представление, в которое можно писать. Ну не знают модули о нормализованном представлении, оно инкапсулировано как раз-таки через VIEWs. Оно не обязательно, на самом деле, просто денормализованное — оно просто другое, «фасет» если хотите.
В постгресе сейчас нет инкрементального обновления мат. представлений, недавно только завезли конкурентное.
В статье прямо говорится, что инструмент требует взвешенного подхода. Например, у нас денормализация работает вопреки вашим предостережениям.
В статье прямо говорится, что инструмент требует взвешенного подхода. Например, у нас денормализация работает вопреки вашим предостережениям.
у материализованных представлений слишком много проблем с перформансом. Как только объемы превышают определенныйц порог и не прокатывает полная перестройка матвью — сразу же на практике от матвью преходится отказываться.
Еще в интернет-магазине, где по сути товар создается один раз, но для вывода страниц требуется получать главные картинки товаров в категории, проще имена главных картинок еще одним полем хранить, чем джоином еще одну таблицу цеплять ради такого, а еще в заказах хранить нужно цену на момент покупки и товары (как минимум названия), даже если товар удаляется — древние заказы можно поднять и понять что там было заказано.
В оригинальной статье принципы денормализации изложены неплохо. Но вот пример с остатками товара совершенно оторван от жизни и неуместен. В реальных системах никто не станет хранить остатки в таблице Product. (Ну разве что студенты, писавшие на коленке за еду).
P.S. Самое интересное, о чем я узнал из статьи — об онлайн редакторе моделей от Vertabelo. :)
Мы в Латере много занимаемся оптимизацией производительности нашей биллинговой системыВот и написали бы статью на своих примерах, всесто того, чтобы переписывать с чужого блога.
P.S. Самое интересное, о чем я узнал из статьи — об онлайн редакторе моделей от Vertabelo. :)
Поэтому у нас API предоставляется в виде хранимых процедур. А тому, кто ручками что-то апдейт в базе, мы ручки укорачиваем.
про олд-стайл джоин на порядок быстрейший — это какая байка. Т.к. либо у них одинаковый план — и они тогда работают одинаково, либо у них разных план- и значит это разные запросы вообще. (Ну или просто оптимизатор туповат — и тогда это не фича, а баг, и тогда уже хинтами можно получить одинаковый план)
удалено.
Хорошо бы иметь специальное соглашение по именованию дополнительных денормализованных полей или таблиц. В примерах в статье такие поля ничем не отличимы от остальных, и это впоследствии может привести к ошибке, потому что отношение к нормальным данным и избыточным должно быть разное, как раз чтобы поддерживать целостность. Можно добавлять префикс какой-нибудь, или суффикс.
Что касается большинства веб-проектов, то денормализация там отлично применяется и используется по назначению. Собственно, расцвет nosql-хранилищ, это не что иное как осознанный отказ от преимуществ нормализованных строгих данных в сторону быстрых, но ненормализованных.
Не раз приходилось сталкиваться с сайтиками, в которых «правильная» структура данных создавала массу неудобств и трудностей, при отсутствии видимых преимуществ (мало по-настоящему сложных зависимостей, статичность данных и проч.) Я бы даже сказал, что стремление нормализовать данные — это вторая наиболее распространённая причина оверинжиниринга веб-проектов.
Что касается большинства веб-проектов, то денормализация там отлично применяется и используется по назначению. Собственно, расцвет nosql-хранилищ, это не что иное как осознанный отказ от преимуществ нормализованных строгих данных в сторону быстрых, но ненормализованных.
Не раз приходилось сталкиваться с сайтиками, в которых «правильная» структура данных создавала массу неудобств и трудностей, при отсутствии видимых преимуществ (мало по-настоящему сложных зависимостей, статичность данных и проч.) Я бы даже сказал, что стремление нормализовать данные — это вторая наиболее распространённая причина оверинжиниринга веб-проектов.
Sign up to leave a comment.
Зачем нужна денормализация баз данных, и когда ее использовать