Forum Webscript.Ru

Общие => Базы данных => Тема начата: listopad от 19 Августа 2002, 17:16:18

Название: Задачка не для слабых ....
Отправлено: listopad от 19 Августа 2002, 17:16:18
Есть база данных MySQL , в ней девять таблиц , в каждой таблице есть столбец вида
zodiac enum(\\"0\\",\\"1\\",\\"2\\",\\"3\\",\\"4\\",\\"5\\",\\"6\\",\\"7\\",\\"8\\",\\"9\\",\\"10\\",\\"11\\",\\"12\\")(на слеши не обращайте внимания , Php виновата)-т.е имеется виду 12 знаков зодиаков и один пустой, и соответственно пользователь добавляет свое имя и указывает свой знак зодиака... т. е. получается запись вида
сергей-7 (оба значения в разных столбцах конечно, 7 -иммеется в виду "скорпион") но дело не в этом..... здесь все как обычно и все понятно...
Но надо создать такой запрос который показывал бы сколько записей соответсвуют каждому знаку зодиака из всех девяти таблиц.....
$sql="
SELECT zodiac,COUNT(*) AS count FROM tabl1
GROUP BY zodiac ORDER BY count  ASC";
- нодо что-то наподобие этого запроса , но сразу по 9 таблицам:insane:
Название: Задачка не для слабых ....
Отправлено: fidget от 19 Августа 2002, 17:25:07
listopad
боюсь что одним запросом не обойдешься :(
Делай выборку из таблиц и записывай во временную, а потом результирующую выборку сделаешь по временной таблице.
Название: Задачка не для слабых ....
Отправлено: Ganer от 20 Августа 2002, 10:22:44
А что у тебя все 9 таблиц одного формата ???? Интересно бы услышать причину (она наверника веская ;) )

А в MySQL нельзя так писать ?

select count(*)  from (
     select ...
     UNION
     select ...
     UNION
) group by ...
Название: Задачка не для слабых ....
Отправлено: Alexandr от 20 Августа 2002, 10:45:52
Цитировать
А в MySQL нельзя так писать ?

Только в 4, а о нём с пол-годика мона не вспоминать.
Название: Задачка не для слабых ....
Отправлено: fidget от 20 Августа 2002, 11:26:25
Ganer
UNION есть в 4.0, только  насколько я помню по стандарту SQL 99 GROUP BY на всё выражение там кажется не применяется, только на каждый из SELECT\'ов
так что наверное UNION все равно не подойдет :-)
Название: Задачка не для слабых ....
Отправлено: Oak от 21 Августа 2002, 01:17:02
А зачем вам вообще это в запросе делать?
Выбрать все(только этот слолбец) и посчитать скриптом :)
Надеюсь там не миллион записей?

Или 12 запросов. - посмотри что по времени быстрее
Название: Задачка не для слабых ....
Отправлено: listopad от 21 Августа 2002, 12:03:32
Временная таблица это конечно хорошо, вот что у меня получается ......
zodiac   count
0---------25
0---------14
4---------8
6---------14
6---------4
9---------9
10-------85
10-------64
10-------12
11-------6
12-------1

Но а как теперь сделать результирующую выборку.......по знаку зодиака... ???
Название: Задачка не для слабых ....
Отправлено: fidget от 21 Августа 2002, 12:11:18
select zodiac, sum(count) from table_name group by zodiac

на практике не проверяла, но должно работать :)
Название: Задачка не для слабых ....
Отправлено: listopad от 21 Августа 2002, 12:28:28
Все работает......... Спасибо !!!
Название: Задачка не для слабых ....
Отправлено: Меняздесьдавнонет от 21 Августа 2002, 12:29:28
Вообще-то Ганер еще неделю назад сказал решение.
сделать вместо 9 таблиц - одну.
Но мы ведь не ищем легких путей.
Название: Задачка не для слабых ....
Отправлено: Alexandr от 21 Августа 2002, 12:36:08
Цитировать
сделать вместо 9 таблиц - одну.

Не всегда есть такая возможность.
Название: Задачка не для слабых ....
Отправлено: listopad от 21 Августа 2002, 12:50:43
Все дело в скорости......
Дело в том что все пользователи делятся на 9 типов........и засовываются в соответствующую таблицу....., и в последствие , если надо отобрать участников одного типа сразу выбирается конкретная таблица , а  не насилутся одна оператором WHERE  .......--- это приводит к дополнительным запросам...... , а главное СКОРОСТЬ  !!!!
Но может ....я в чем то и не прав....
Другое дело что все эти девять можно засунуть в одну временную...... а  потом ее обработать..... Но опять проблема с памятью , если будет несколько тысяч записей в итоге.....
Название: Задачка не для слабых ....
Отправлено: fidget от 21 Августа 2002, 13:10:47
listopad
ты можешь создать одну таблицу со всеми типа и в таблице гороскопов будет просто еще один столбец, где будет указан к какому типу пользователей относится ...
если у тебя этот столбез будет проиндексирован, то WHERE index_field=constant работает _очень_ быстро.

а вобще все зависит от твоих запросов, частоты и т.д.
Название: Задачка не для слабых ....
Отправлено: Alexandr от 21 Августа 2002, 14:06:19
Цитировать
Все дело в скорости......

Верняк.
Цитировать
если у тебя этот столбез будет проиндексирован, то WHERE index_field=constant работает _очень_ быстро.

Не верно. Вернее не всегда.
Цитировать
а вобще все зависит от твоих запросов, частоты и т.д.

Верняк.
Название: Задачка не для слабых ....
Отправлено: Меняздесьдавнонет от 21 Августа 2002, 14:06:24
Гы!
Он делает временную таблицу и говорит о скорости! :-))))

Оператор where не насилует таблицу.
Это все равно, что сказать, что ложка насилует тарелку.
Ты бы хоть померил скорость, прежде, чем писать глупости. или книжку какую умную прочел.
Название: Задачка не для слабых ....
Отправлено: Меняздесьдавнонет от 21 Августа 2002, 14:14:13
listopad
Имей в виду, что  fidget - модератор этого форума, и кое-что в базах данных понимает.
А Alexandr - новичок. Достаточно почитать его ответы в соседних ветках.

Это тебе так, для информации.
Название: Задачка не для слабых ....
Отправлено: Меняздесьдавнонет от 21 Августа 2002, 14:19:43
Пример.
Только дикарь, который вообще не представляет себе, как обращаться с базой данных, способен на ТАКОЕ:
Цитировать
ALTER TABLE DROP id
...
INSERT .....
ALTER TABLE ADD id mediumint NOT NULL auto_increment UNSIGNED
Название: Задачка не для слабых ....
Отправлено: fidget от 21 Августа 2002, 14:22:16
Цитировать
Не верно. Вернее не всегда.


Допустим для его подсчетов по знакам зодиака он будет использоваться ;)

listopad
а тебе нужно проанализировать свои запросы, посмотреть чаще ты обращаешься к отдельной группе пользователей или таки к нескольким. Как много данных у тебя всего и на каждую группу пользователей, если у тебя общая таблица пользователей будет в пределах десятков тысяч, то это смешной объем, что бы делить его на несколько таблиц.

Кстати пока писала мне тут в голову пришла еще одна идея :)
я так понимаю, что ты используешь таблицы MyISAM и все твои 9 таблиц идентичны, тогда тебе есть смысл использовать MERGE таблицы :)
Это даст тебе возможность использовать таблицы по отдельности и вместе как одну большую таблицу :)
Читать тут:
http://www.mysql.com/doc/en/MERGE.html

тогда ты вполне сможешь обойтитсь одним запросом и без временных таблиц :)
Название: Задачка не для слабых ....
Отправлено: fidget от 21 Августа 2002, 14:25:26
RomikChef
Ромик, за "кое-что понимает" конечно спасибо :)

но плз, если переходишь на личности, то во флэйм пожалуста :) или в приват :)
Название: Задачка не для слабых ....
Отправлено: Меняздесьдавнонет от 21 Августа 2002, 14:44:18
fidget
Ок, кое-что исправил.
И все же, хоть merge и решение, но основное правило никто не отменял. Подобные данные должны лежать в одной таблице.
А все эти высосанные из пальца идеи о том, что скорость упадет, надо пресекать в корне.

К тому же, наверняка с merge будут еще проблемы, хотя бы из-за того, что id в ней неуникальный.
Зачем самому себе жизнь портить?

Вся проблема от того, что человек идет не от проектирования базы данных, а от каких-то своих соображений.
проектирование базы данных - это половина дела.
Если ее сделать нормально, то потом проблем возникать не будет.
Мало ли какие выборки ему поднадобятся в будущем? Уже сейчас ему приходится ставить заплаты в виде временных таблиц, на криво спроектированную базу данных.
помещение всез данных в одну таблицу, снимет и текущие, и БУДУЩИЕ проблемы.
Название: Задачка не для слабых ....
Отправлено: fidget от 21 Августа 2002, 15:01:12
Цитировать
Подобные данные должны лежать в одной таблице.

угу, в 99% так всегда и делается
хотя было пару случаев, когда мы насильно разделяли на таблицы по 2м причинам:
1. запросов по всем категориям почти не было, основная часть по отдельной категории.
2. Данные очень часто обновлялись и т.к. MyISAM таблицы поддерживают только table locking - это доставляло определенного рода неудобства :(
Хотя после того как перевели базу на InnoDB все данные объединили в одну таблицу и насколько я знаю так оно и работает.

но это был частный случай :)
Название: Задачка не для слабых ....
Отправлено: fidget от 21 Августа 2002, 15:06:46
listopad
а что касается того как данные по таблица распихивать, то Ромик уже правильно сказал, что база вначале _проектируется_

и есть еще очень хорошая штука - нормализация


[OFF]к сожалению значительная часть людей, которые базами знанимаются теории реляционных баз данных не знают совершенно :([/OFF]
Название: Задачка не для слабых ....
Отправлено: Alexandr от 21 Августа 2002, 15:33:31
Цитировать
Только дикарь, который вообще не представляет себе, как обращаться с базой данных, способен на ТАКОЕ:

Цитата:
ALTER TABLE DROP id
...
INSERT .....
ALTER TABLE ADD id mediumint NOT NULL auto_increment UNSIGNED

Нууу.... Эт ты погорячился. Базу буду наполнять почти вручную, следовательно путь вполне приемлемый.
[off]
Цитировать
А Alexandr - новичок. Достаточно почитать его ответы в соседних ветках.

Вот уж кто бы говорил. Согласен, что знаю не все, но достаточно сообразителен и обучаем. :-)
[/off]

Цитировать
Подобные данные должны лежать в одной таблице.
угу, в 99% так всегда и делается

Я просто реально столкнулся с этой проблемой:
http://www.autodealer.ru/db_part.php
Раньше была 1 таблица и в ней type_id.
Когда данных увеличилось с 20000 до 250000.
То наступила ошибка max_connections, т.к.
Напр. запрос
SELECT count(*) FROM part WHERE type_id=1;(~249000)
SELECT count(*) FROM part WHERE type_id=2;(~1000)
SELECT count(*) FROM part WHERE type_id=3;(~50)
выполнялся около 1мин.
а про поиск лучше не вспоминать вообще.
Однако после разнесения по 3-м таблицам скорость возросла в десятки раз.
Поэтому и говорю.
Всем пасибо.
Название: Задачка не для слабых ....
Отправлено: Alexandr от 21 Августа 2002, 15:35:32
И ещё. В базах данных нет одного верного, идеального решения на ВСЕ проблемы, всегда бывают отступления от общих правил.
Название: Задачка не для слабых ....
Отправлено: Меняздесьдавнонет от 21 Августа 2002, 16:57:19
Гы!
индекс по полю type_id строить не пробовали?
считать не count(*),а count(id) не пробовали?
Еще раз повторю - проблемы скорости и проблемы разделения таблиц - РАЗНЫЕ.
Название: Задачка не для слабых ....
Отправлено: listopad от 21 Августа 2002, 17:18:50
Все понял , всем спасибо......

иду изучать реляционные базы данных
и проектировать свою заново....
Название: Задачка не для слабых ....
Отправлено: Alexandr от 21 Августа 2002, 17:24:28
Цитировать
Гы!

Не ... а так и есть.
Цитировать
индекс по полю type_id строить не пробовали?

Ес-но. Первое что сделал.
Цитировать
считать не count(*),а count(id) не пробовали?

Юзай EXPLAIN:
Напр.
EXPLAIN SELECT count(*) FROM top WHERE ctg=1;
EXPLAIN SELECT count(id) FROM top WHERE ctg=1;


table type possible_keys key key_len ref rows Extra
top ref ctg ctg 1 const 28 where used; Using index

table type possible_keys key key_len ref rows Extra
top ref ctg ctg 1 const 28 where used

Вишь что в Extra написано.
Цитировать
Еще раз повторю - проблемы скорости и проблемы разделения таблиц - РАЗНЫЕ.

Ес-но, но если 2-е исключает первое, то это зае#@сь.
Название: Задачка не для слабых ....
Отправлено: Chs от 21 Августа 2002, 21:57:45
Уважаемые господа, принимавшие участие в данной дискуссии, будьте корректны в выражениях! И старайтесь держаться сути вопроса.
Alexandr, Вам персональное предупреждение.
Название: Задачка не для слабых ....
Отправлено: Alexandr от 22 Августа 2002, 08:13:29
[OFF]Chs
Цитировать
Alexandr, Вам персональное предупреждение.

Не понял.
Цитировать
будьте корректны в выражениях!

Вродь всегда был и всех призывал.
Цитировать
И старайтесь держаться сути вопроса.

Согласен, отшёл малость от сути. Однако сделал это только по одной причине - дабы дать аргументированный ответ некоторому человеку, который как раз
!=
Цитировать
будьте корректны в выражениях

[/OFF]
Название: Задачка не для слабых ....
Отправлено: dymka от 27 Августа 2002, 20:13:01
смотря как часто он генерит ту временную таблицу...
если неактульно онлайн, то можно заранее делать раз в день\\час итп...
далее - все таки проще поставить тест, если есть индекс, то время на выборку по индексу мало отличается от выборки подряд, хотя зависит от типа значений.
ЗЫ: ничего я нового и не сказал вроде :)