Привет, ЛОР.
Сегодня я хочу оторвать тебя от традиционных срачей про функциональщину и все остальное, от бесчисленных тем про проблемы написания и сборки приложений на С и С++. Я хочу поговорить с тобой о базах данных, в частности о реляционной модели, нормализации, и о том, как все это применять в реальной жизни.
Начну сразу с примера. Он основан на реальном проекте, разве что имена действующих лиц несколько изменены.
Предположим, что у меня есть набор компаний. Каждая компания владеет несколькими заводами. Каждый завод выпускает некоторое количество видов товаров. Компании могут оставлять заявки на закупку товаров у других компаний. Для упрощения, в одной заявке можно указать только один вид товара.
Возьмем компанию Х. Для нее нужно вывести два простых списка:
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-решения? Я думал об этом, но реальных плюсов от использования тех же документо-ориентированных БД для данного случая не нашел.
-- Да, заранее отвечаю на потенциальные вопросы: нет, это НЕ студенческая лаба, к большому сожалению и ДА, я не работаю архитектором баз данных и имею довольно фрагментарные сведения о данной области.