SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 01.11.2010 10:58:02

Avtoritet
Участник
Зарегистрирован: 29.10.2010
Сообщений: 3

Как преодолеть избыточность данных при JOIN?

Хотел бы подискутировать по данной теме, но возможно уже задавали этот вопрос на форуме.
Выдуманный упрощенный пример (пример чуть похож на http://sqlinfo.ru/forum/viewtopic.php?id=3259):
tableA - fields: ida (INT) и еще больше 30 шт. (среди них INT, DATETIME, VARCHAR (!!!), ENUM);
tableB - fields: idb (INT), id_a (INT) и еще больше 30 шт. (tableA -> tableB - один ко многим (причем одной записи с tableA соответствует много записей (строк) с tableB (от одной до бесконечности)));
tableC - fields: idc (INT), id_b (INT) и еще 3шт. (tableB -> tableC - аналогично);
tableD - fields: idd (INT), id_c (INT) и еще 3шт. (tableC -> tableD - аналогично).
Все таблицы типа MyISAM.
Выполняется немножко сокращен запрос (так как используются еще вкладываемые запросы (там где одному запросу всегда соответствует единственная запись из другой таблицы)):


SELECT *
FROM tableA AS a
LEFT JOIN tableB AS b ON a.ida=b.id_a
LEFT JOIN tableC AS c ON b.idb=c.id_b
LEFT JOIN tableD AS d ON c.idc=d.id_c
WHERE a.field<1 AND b.field<2 AND b.field>3 AND b.field LIKE '%test%'
ORDER BY ...;
 

Результат:
ida|...|<--~30шт.-->|...|idb|...|<--~30шт.-->|...|idc|...|<--~3шт.-->|...|idd|...|<--~3шт.-->|...|

123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...| 1|...|<--~3шт.-->|...|346|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...| 1|...|<--~3шт.-->|...|347|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...| 1|...|<--~3шт.-->|...|348|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...| 1|...|<--~3шт.-->|...|349|...|<--~3шт.-->|...|
                                                  ...
                                                  ...
                                                  ...
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...|10|...|<--~3шт.-->|...|433|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...|10|...|<--~3шт.-->|...|434|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...|10|...|<--~3шт.-->|...|435|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...|10|...|<--~3шт.-->|...|436|...|<--~3шт.-->|...|
                         ...
                         ...
                         ...
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...| 5|...|<--~3шт.-->|...|636|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...| 5|...|<--~3шт.-->|...|637|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...| 5|...|<--~3шт.-->|...|638|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...| 5|...|<--~3шт.-->|...|993|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...| 5|...|<--~3шт.-->|...|994|...|<--~3шт.-->|...|
...
...
...
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...| 8|...|<--~3шт.-->|...| 96|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...| 8|...|<--~3шт.-->|...| 97|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...| 8|...|<--~3шт.-->|...| 98|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...| 8|...|<--~3шт.-->|...| 99|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...| 8|...|<--~3шт.-->|...|100|...|<--~3шт.-->|...|
...
...
...
1) Как видно передаются данные (от MySQL сервера) с большой избыточностью. Отсюда, если не учитывать "...", то полезных данных от tableA передается всего навсего 2 строки (все остальное лишнее), от tableB - 3 строки и т.д..
2) Хотя можно предположить, что MySQL сервер передает данные клиенту не в виде реляционной (плоской) таблицы, а в другом собственном формате, который програмный клиент понимает (плюс возможно используется шифрования).
3) Но клиент для обработки данных всеравно выдает результат в виде реляционной таблицы, отсюда большая избыточность данных для клиента (так как выполняется считывание построчно) и соответственно нагрузка на сервер/клиент где обрабатываются данные от MySQL сервера (RAM, CPU.).
4) Не плохо было бы, если результирующая таблица была не просто реляционной, но и показывала, например, количество строк tableB, соответствующую одной строке tableA и при этом бы не использовалась избыточность. Правда это я уже придумал некую напивреляцийну результирующую таблицу, но идея не плохая. Возможно уже есть реализации?
5) Числа нужны для пункта номер 4 возможно можно получить с помощью SQL-запроса (используя GROUP BY, COUNT (), ...) в виде отдельной таблицы (хотя опять не идеально так как ИСПОЛЬЗУЕТСЯ избыточность и дополнительная таблица). Числа можно вписывать в результирующую таблицу и тем самым избавиться от дополнительной таблицы => однако за счет этих чисел растет избыточность (однако не значительно). Мои усилия не привели к нужному SQL-запросу :-( => создал тему http://sqlinfo.ru/forum/viewtopic.php?id=3345
6) Уже и не хочется затронуть тему вывода таблицы (например, в html формате) БЕЗ избыточности (так как нужно использовать систему флагов или считывать одну строку впереди или считывать синхронно с конечной таблицей дополнительно таблицы tableA, tableB, tableC, tableD).
7) Возможно для идеального решения данной задачи не подходят реляционные базы даных?

Прошу помощи, комментариев хотя бы по нескольким из выше указанных пунктах.

Отредактированно Avtoritet (01.11.2010 11:20:00)

Неактивен

 

#2 01.11.2010 15:37:52

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Как преодолеть избыточность данных при JOIN?

А зачем Вам отдельная тема с тем же вопросом? На который я, тем более, ответил
уже в том треде? sad

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson