Forum Webscript.Ru
Общие => Базы данных => Тема начата: 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:
-
listopad
боюсь что одним запросом не обойдешься :(
Делай выборку из таблиц и записывай во временную, а потом результирующую выборку сделаешь по временной таблице.
-
А что у тебя все 9 таблиц одного формата ???? Интересно бы услышать причину (она наверника веская ;) )
А в MySQL нельзя так писать ?
select count(*) from (
select ...
UNION
select ...
UNION
) group by ...
-
А в MySQL нельзя так писать ?
Только в 4, а о нём с пол-годика мона не вспоминать.
-
Ganer
UNION есть в 4.0, только насколько я помню по стандарту SQL 99 GROUP BY на всё выражение там кажется не применяется, только на каждый из SELECT\'ов
так что наверное UNION все равно не подойдет :-)
-
А зачем вам вообще это в запросе делать?
Выбрать все(только этот слолбец) и посчитать скриптом :)
Надеюсь там не миллион записей?
Или 12 запросов. - посмотри что по времени быстрее
-
Временная таблица это конечно хорошо, вот что у меня получается ......
zodiac count
0---------25
0---------14
4---------8
6---------14
6---------4
9---------9
10-------85
10-------64
10-------12
11-------6
12-------1
Но а как теперь сделать результирующую выборку.......по знаку зодиака... ???
-
select zodiac, sum(count) from table_name group by zodiac
на практике не проверяла, но должно работать :)
-
Все работает......... Спасибо !!!
-
Вообще-то Ганер еще неделю назад сказал решение.
сделать вместо 9 таблиц - одну.
Но мы ведь не ищем легких путей.
-
сделать вместо 9 таблиц - одну.
Не всегда есть такая возможность.
-
Все дело в скорости......
Дело в том что все пользователи делятся на 9 типов........и засовываются в соответствующую таблицу....., и в последствие , если надо отобрать участников одного типа сразу выбирается конкретная таблица , а не насилутся одна оператором WHERE .......--- это приводит к дополнительным запросам...... , а главное СКОРОСТЬ !!!!
Но может ....я в чем то и не прав....
Другое дело что все эти девять можно засунуть в одну временную...... а потом ее обработать..... Но опять проблема с памятью , если будет несколько тысяч записей в итоге.....
-
listopad
ты можешь создать одну таблицу со всеми типа и в таблице гороскопов будет просто еще один столбец, где будет указан к какому типу пользователей относится ...
если у тебя этот столбез будет проиндексирован, то WHERE index_field=constant работает _очень_ быстро.
а вобще все зависит от твоих запросов, частоты и т.д.
-
Все дело в скорости......
Верняк.
если у тебя этот столбез будет проиндексирован, то WHERE index_field=constant работает _очень_ быстро.
Не верно. Вернее не всегда.
а вобще все зависит от твоих запросов, частоты и т.д.
Верняк.
-
Гы!
Он делает временную таблицу и говорит о скорости! :-))))
Оператор where не насилует таблицу.
Это все равно, что сказать, что ложка насилует тарелку.
Ты бы хоть померил скорость, прежде, чем писать глупости. или книжку какую умную прочел.
-
listopad
Имей в виду, что fidget - модератор этого форума, и кое-что в базах данных понимает.
А Alexandr - новичок. Достаточно почитать его ответы в соседних ветках.
Это тебе так, для информации.
-
Пример.
Только дикарь, который вообще не представляет себе, как обращаться с базой данных, способен на ТАКОЕ:
ALTER TABLE DROP id
...
INSERT .....
ALTER TABLE ADD id mediumint NOT NULL auto_increment UNSIGNED
-
Не верно. Вернее не всегда.
Допустим для его подсчетов по знакам зодиака он будет использоваться ;)
listopad
а тебе нужно проанализировать свои запросы, посмотреть чаще ты обращаешься к отдельной группе пользователей или таки к нескольким. Как много данных у тебя всего и на каждую группу пользователей, если у тебя общая таблица пользователей будет в пределах десятков тысяч, то это смешной объем, что бы делить его на несколько таблиц.
Кстати пока писала мне тут в голову пришла еще одна идея :)
я так понимаю, что ты используешь таблицы MyISAM и все твои 9 таблиц идентичны, тогда тебе есть смысл использовать MERGE таблицы :)
Это даст тебе возможность использовать таблицы по отдельности и вместе как одну большую таблицу :)
Читать тут:
http://www.mysql.com/doc/en/MERGE.html
тогда ты вполне сможешь обойтитсь одним запросом и без временных таблиц :)
-
RomikChef
Ромик, за "кое-что понимает" конечно спасибо :)
но плз, если переходишь на личности, то во флэйм пожалуста :) или в приват :)
-
fidget
Ок, кое-что исправил.
И все же, хоть merge и решение, но основное правило никто не отменял. Подобные данные должны лежать в одной таблице.
А все эти высосанные из пальца идеи о том, что скорость упадет, надо пресекать в корне.
К тому же, наверняка с merge будут еще проблемы, хотя бы из-за того, что id в ней неуникальный.
Зачем самому себе жизнь портить?
Вся проблема от того, что человек идет не от проектирования базы данных, а от каких-то своих соображений.
проектирование базы данных - это половина дела.
Если ее сделать нормально, то потом проблем возникать не будет.
Мало ли какие выборки ему поднадобятся в будущем? Уже сейчас ему приходится ставить заплаты в виде временных таблиц, на криво спроектированную базу данных.
помещение всез данных в одну таблицу, снимет и текущие, и БУДУЩИЕ проблемы.
-
Подобные данные должны лежать в одной таблице.
угу, в 99% так всегда и делается
хотя было пару случаев, когда мы насильно разделяли на таблицы по 2м причинам:
1. запросов по всем категориям почти не было, основная часть по отдельной категории.
2. Данные очень часто обновлялись и т.к. MyISAM таблицы поддерживают только table locking - это доставляло определенного рода неудобства :(
Хотя после того как перевели базу на InnoDB все данные объединили в одну таблицу и насколько я знаю так оно и работает.
но это был частный случай :)
-
listopad
а что касается того как данные по таблица распихивать, то Ромик уже правильно сказал, что база вначале _проектируется_
и есть еще очень хорошая штука - нормализация
[OFF]к сожалению значительная часть людей, которые базами знанимаются теории реляционных баз данных не знают совершенно :([/OFF]
-
Только дикарь, который вообще не представляет себе, как обращаться с базой данных, способен на ТАКОЕ:
Цитата:
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-м таблицам скорость возросла в десятки раз.
Поэтому и говорю.
Всем пасибо.
-
И ещё. В базах данных нет одного верного, идеального решения на ВСЕ проблемы, всегда бывают отступления от общих правил.
-
Гы!
индекс по полю type_id строить не пробовали?
считать не count(*),а count(id) не пробовали?
Еще раз повторю - проблемы скорости и проблемы разделения таблиц - РАЗНЫЕ.
-
Все понял , всем спасибо......
иду изучать реляционные базы данных
и проектировать свою заново....
-
Гы!
Не ... а так и есть.
индекс по полю 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-е исключает первое, то это зае#@сь.
-
Уважаемые господа, принимавшие участие в данной дискуссии, будьте корректны в выражениях! И старайтесь держаться сути вопроса.
Alexandr, Вам персональное предупреждение.
-
[OFF]Chs
Alexandr, Вам персональное предупреждение.
Не понял.
будьте корректны в выражениях!
Вродь всегда был и всех призывал.
И старайтесь держаться сути вопроса.
Согласен, отшёл малость от сути. Однако сделал это только по одной причине - дабы дать аргументированный ответ некоторому человеку, который как раз
!=
будьте корректны в выражениях
[/OFF]
-
смотря как часто он генерит ту временную таблицу...
если неактульно онлайн, то можно заранее делать раз в день\\час итп...
далее - все таки проще поставить тест, если есть индекс, то время на выборку по индексу мало отличается от выборки подряд, хотя зависит от типа значений.
ЗЫ: ничего я нового и не сказал вроде :)