LINUX.ORG.RU

Реляционные БД и нормализация

 , ,


0

0

Привет, ЛОР.
Сегодня я хочу оторвать тебя от традиционных срачей про функциональщину и все остальное, от бесчисленных тем про проблемы написания и сборки приложений на С и С++. Я хочу поговорить с тобой о базах данных, в частности о реляционной модели, нормализации, и о том, как все это применять в реальной жизни.

Начну сразу с примера. Он основан на реальном проекте, разве что имена действующих лиц несколько изменены.
Предположим, что у меня есть набор компаний. Каждая компания владеет несколькими заводами. Каждый завод выпускает некоторое количество видов товаров. Компании могут оставлять заявки на закупку товаров у других компаний. Для упрощения, в одной заявке можно указать только один вид товара.

Возьмем компанию Х. Для нее нужно вывести два простых списка:
1. Список заявок на закупку товаров у компании Х. В списке должны фигурировать, как минимум, название товара и компания-контрагент.
2. Список заявок на закупку товаров самой компанией Х у других. Требования аналогичные.

Согласно реляционной модели, здесь выделяются сущности: Компания, Завод, Товар, Заявка. Между ними есть связи: Компания -< Завод, Завод -< Товар, Товар -< Заявка, Компания -< Заявка, где -< обозначает связь один ко многим.

Это приводит нас к весьма нетривиальным запросам вида

SELECT <some shit> FROM Factories, Products, Orders, Companies, WHERE Factories.company_id = $1 AND Products.factory_id = Factories.id AND Orders.product_id = Products.id AND Companies.id = Orders.company_id;

- это запрос на выдачу первого списка, всего-то соединение четырех таблиц, пусть и по ключам, пусть и с индексами. Насколько я знаю, соединение - тяжелая операция и меня терзают смутные сомнения, что уже на десятках тысяч товаров и заявок в БД, допустим, такие запросы будут тупить-тормозить (если речь идет о веб-сервисе, для которого приемлемое время ответа под нагрузкой - ну пусть полсекунды, хотя и это - много).

Неужели люди реально вот с этим всем живут? Что предлагается делать в таких случаях? Партиционирование, чтобы всякие архивные заявки и ныне не выпускаемые товары задвигать подальше, т.к. они нужны раз в год? Место действия - postgresql, если это важно.

Я понимаю, что нормализация - она совсем не учитывает производительность, ок, какой разумный вариант денормализации можно предложить для такого случая? С одновременным минимумом шансов прострела ноги и ощутимым упрощением запросов.

Вопрос на закуску. Помогут ли в данном случае какие-либо NoSQL-решения? Я думал об этом, но реальных плюсов от использования тех же документо-ориентированных БД для данного случая не нашел.

-- Да, заранее отвечаю на потенциальные вопросы: нет, это НЕ студенческая лаба, к большому сожалению и ДА, я не работаю архитектором баз данных и имею довольно фрагментарные сведения о данной области.

★★★

Последнее исправление: unikoid (всего исправлений: 1)

А всё так хорошо начиналось. Описание модели, я думал сейчас ты будешь про нормальные формы интересоваться. Ан-нет. Пример sql запроса который никому не нужнн (лучше бы ER диаграму нарисовал) и скатился аж до NoSQL.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)

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

pi11 ★★★★★
()
Ответ на: комментарий от invy

про нормальные формы интересоваться

Про нормальные формы, как ты мог догадаться, я уже поинтересовался. Теперь вот интересуюсь, кто и как применяет их к реальной жизни. Стилизованная ER-диаграмма там тоже есть, если ты не заметил.

Пример sql запроса который никому не нужнн

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

unikoid ★★★
() автор топика
Последнее исправление: unikoid (всего исправлений: 1)
Ответ на: комментарий от pi11

Таблицы компания и заводы будут милипиздрические.

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

unikoid ★★★
() автор топика

Сделай модель таблиц, сделай индексы и покажи EXPLAIN. Я уверен, что при правильных индексах в том, что описано никаких тормозов не будет. Данный запрос полностью оптимизируется. Грубо говоря соединяются не сами таблицы, а только крохотные выборки по индексам. На самом деле очень быстрая операция.

surefire ★★★
()

что уже на десятках тысяч товаров и заявок в БД

Ничего не случится. Тем более у тебя почти все таблички это сраные справочники, которые все равно всегда в памяти будут или вычитываются за несколько страниц.

anonymous
()

а теперь подумай как этим списком пользоваться?
1. полюбому же будут добавляться фильтры и количество данных сократится
2. если одиночные заказы, так вообще делать отдельные запросы по внешним ключам
3. если таки не получается 1 и 2, то можно кешировать и денормализировать где это нужно

kiotoze ★★★★
()

Насколько я знаю, соединение - тяжелая операция

Месье был покусан MySQL 3.3?

Когда проектируют схему, то исходят из третьей нормальной формы. Потом (я подчеркиваю - потом, не сразу) участки, на которых возникают серьезные нерешаемые (я подчеркиваю - серьезные и нерешаемые) проблемы с производительностью, денормализуют.

В твоем случае транзакционная таблица только одна - это ORDERS. Если все правильно проиндексировано и оптимизатор в базе не полный лох (а он даже в мусколе не лох), то все у тебя будет ок. Если таки лох - похинтуй запросы руками, хотя я последний хинт писал еще для девятого Оракла, начиная с десятки CBO сам нормально допетривает, если ты запросы руками пишешь, конечно, а не жопой.

Если у тебя заказов десятки миллионов в неделю (в чем я лично сомневаюсь), то можешь подумать о разных способах оптимизации, например о секционировании этой таблицы.

NoSQL твою проблему не решит: проблема, скорее всего, у тебя в голове (если у тебя не десятки миллионов заказов в неделю).

Не выдумывай проблемы там, где их нет.

alex_the_v ★★★
()
Последнее исправление: alex_the_v (всего исправлений: 2)

я не работаю архитектором

Извини тогда за мой напыщеный тон. Я сначала прочитал как «ДА, я работаю архитектором» и подумал - ни фига себе архитекторы пошли.

Но смысл сказаного все равно не меняется.

alex_the_v ★★★
()

весьма нетривиальным запросам

Запрос тривиальнейший.

такие запросы будут тупить-тормозить

Пусть тупят, офисный клерк подождет уведомления и скачает отчет. Важно чтобы master при этом не подвисал. Ты сильно Pg (в умелых руках, на хорошем железе) недооцениваешь.

Помогут ли в данном случае какие-либо NoSQL-решения?

Да, помогут. Возможно какие-то хадупы и прочие фреймворки для процессинга данных.

нужны раз в год

За год можно подготовиться к чему угодно.

outtaspace ★★★
()

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

unikoid ★★★
() автор топика

это запрос на выдачу первого списка, всего-то соединение четырех таблиц, пусть и по ключам, пусть и с индексами. Насколько я знаю, соединение - тяжелая операция и меня терзают смутные сомнения, что уже на десятках тысяч товаров и заявок в БД, допустим, такие запросы будут тупить-тормозить (если речь идет о веб-сервисе, для которого приемлемое время ответа под нагрузкой - ну пусть полсекунды, хотя и это - много).

Индексы творят чудеса. Не так всё страшно.

hobbit ★★★★★
()

нетривиальным запросам

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

winlook38 ★★
()

Поддерживаю предыдущих ораторов - да, всё будет нормально.

den73 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.