Задавайте вопросы, мы ответим
Вы не зашли.
Допустим есть две сущности A и B, имеющие отношение один ко многим, которые надо хранить в БД.
Классический подход рекомендует использовать промежуточную таблицу R вида
id_a id_b
R.id_a1 R.id_b1
R.id_a1 R.id_b2
.....
Вынимаем соответственно с помощью объединения трех таблиц
SELECT * FROM A JOIN R ON a.id = R.id_a JOIN B ON b.id = R.id_b WHERE A.id = ...
упрощенно, но думаю понятно.
Возникла мысль для реализации отношений использовать поле таблицы А - id_b - в котором хранить связанные идентификаторы из таблицы B в виде списка, разделенного запятыми и доставать данные так:
SELECT * FROM A JOIN B ON b.id IN (A.id_b) WHERE a.id = ...
Преимущества вижу слудующие
- отстуствие одного JOIN (что по идее повысит производительность)
- такое поле - легко, даже элементарно, программируется и управляется из приложения
Хотел бы понять недостатки такого подхода, если они есть
Коллега сказал, что я извращенец, но аргументов не привел, не считая риторических, типа это не по классике (ну и что с того?, денормализация тоже противоречит классике - зато иногда существенно повышает производительность). Хотелось бы что то посущественнее услышать от специалистов.
Отредактированно Shopen (06.05.2008 19:37:15)
Неактивен
Есть примеры, когда производительность повышается от того, что данные не хранятся в реляционной БД. Пример - прямой и обратный поисковой индекс. Прямой индекс - id документа - список id слов (грубо), обратный - id слова - список id документов. Если это хранить напрямую, то производительность в десятки раз больше, чем если использовать реляционную базу данных и отношение многие ко многим. Причина - JOIN требует читать данные из разных частей жесткого диска, а прямая реализация данный запрос выполняет чтением последовательного куска данных.
Минусы очевидны - теряется гибкость реляционной модели - в Вашем случае невозможно искать наборот по значению из B без перебора таблицы A. Если не нужна гибкость, то Вы можете легко построить данные, работающие хорошо только с конкретными заданными запросами (пример выше).
Неактивен