#php #mysql #sql #database
#php #mysql #sql #База данных
Вопрос:
Я ищу правильный запрос mysql для моего веб-сайтаhttp://watiseropderadio.nl (на голландском языке). Это веб-сайт, позволяющий узнать, какие песни звучали на популярном радио в Голландии.
Я хочу сделать запрос, который возвращает 13 строк для каждой радиостанции. Существует 8 разных радиостанций.
Это моя таблица:
id | radioname | time | artist | song
--------------------------------------------------------------
23421 | radio 538 | 19:34 | Queen | Bohemian
23422 | radio veronica | 19:35 | Rammstein | Blablabla
23423 | slam fm | 19:34 | Roxette | Blablabla
23424 | 3fm | 19:34 | Blabla | Blablabla
....
Это таблица с более чем 3 000 000 записей и с этими ключами:
PRIMARY PRIMARY 3083007 id
radioname INDEX 8 radioname
track with artist INDEX 23715 artist
song
Это то, что я хочу получить на выходе:
id | radioname | time | artist | song
--------------------------------------------------------------
23455 | radio 538 | 19:30 | Blabla | Blablabla
23470 | radio 538 | 19:33 | Blabla | Blablabla
23484 | radio 538 | 19:36 | Blabla | Blablabla
23498 | radio 538 | 19:38 | Blabla | Blablabla
total 13 x ....
23456 | radio veronica | 19:29 | Blabla | Blablabla
23476 | radio veronica | 19:32 | Blabla | Blablabla
23483 | radio veronica | 19:36 | Blabla | Blablabla
23495 | radio veronica | 19:39 | Blabla | Blablabla
total 13 x ....
Порядок результата не имеет значения, и запрос должен быть быстрым. Мне нравится пробовать это самому, но для меня это слишком много.
Я не знаю, используются ли ключи для этой работы, может кто-нибудь дать какой-нибудь совет?
Комментарии:
1. Помимо вашего вопроса: я бы использовал числовой идентификатор радиостанции вместо того, чтобы каждый раз сохранять полное название.
2. @abaumg Я собираюсь это сделать, спасибо. Сэкономит ли это много времени? Потому что время загрузки записей за последние 2 часа составляет 3 (!) секунды.
3. Я не гуру MySQL и не знаю, сколько времени это сэкономит, но это сэкономит некоторое время. И это хороший дизайн базы данных.
4. Это сэкономит некоторое время, но не ожидайте чего-то огромного. Более важная причина заключается в том, чтобы избежать проблем с правописанием: если один пользователь вводит станцию как «slam fm», а кто-то другой вводит ее как «Slam FM» или просто «Slam» или какой-либо другой вариант, они будут выглядеть как разные станции. С помощью отдельной таблицы станций вы можете заставить их быть согласованными.
5. Кроме того, без отдельной таблицы, что, если, скажем, вы храните данные только за одну неделю, а затем станция отключается от эфира на неделю? Вы теряете все записи о существовании этой станции. Это называется «аномалией удаления» и является проблемой при нормализации. Могу ли я подключить свою книгу? «Разумный подход к проектированию базы данных», обсуждается это. Я уверен, что множество других хороших источников делают то же самое.
Ответ №1:
Это сложно, потому что, хотя есть способы сказать «получите мне только 13 записей для этого запроса», насколько мне известно, нет способа напрямую сказать «получите мне только 13 записей для каждого значения поля x».
Единственный способ, который я могу придумать, чтобы сделать это, это добавить поле «номер воспроизведения» к записи или создать другую таблицу для хранения этого номера, если вы не можете или не хотите изменять запись «сыгранная песня». Затем, когда записи будут добавлены в таблицу, дайте каждой следующий доступный номер для этой радиостанции. (На самом деле в MySQL есть функция, позволяющая делать это автоматически.) Тогда ваш запрос мог бы искать этот индекс <=13, или, если записи могут быть удалены, иметь внутренний запрос, который выполняет «выберите станцию, max (play) как maxplay group by station», тогда внешний запрос мог бы выбрать «где play> maxplay-13»
Обновить
Чтобы настроить автоматическое увеличение MySQL, смотрите http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html . Обратите особое внимание на обсуждение вокруг предложения: «Для таблиц MyISAM и BDB вы можете указать AUTO_INCREMENT для дополнительного столбца в индексе с несколькими столбцами. В этом случае сгенерированное значение для столбца AUTO_INCREMENT вычисляется как MAX(auto_increment_column) 1, ГДЕ prefix=given-префикс. Это полезно, когда вы хотите поместить данные в упорядоченные группы.» (Честно говоря, прошло некоторое время с тех пор, как я использовал это, поэтому я не могу предоставить много деталей.)
Комментарии:
1. Это звучит понятно. Можете ли вы по ссылке объяснить эту функцию ‘На самом деле в MySQL есть функция, позволяющая делать это автоматически’?
2. Или просто с помощью
UPDATE table SET lastplay = lastplay - 1 WHERE radioname = 'radio 538' AND lastplay > 0
?3. @harianus: Смотрите обновление. Если бы я использовал базу данных, отличную от MySQL, в которой нет такой функции «автономера в префиксе», я думаю, я бы, вероятно, написал код для присвоения порядковых номеров или назначил их во время вставки каждой записи. «вставить в список воспроизведения (… независимо …, playnumber) значения (… независимо …, (выберите объединить(max(playnumber),0) 1 из списка воспроизведения, где radioname=<новое radioname>))»
Ответ №2:
Допустимо ли перебирать список радиостанций (поскольку их всего 8) и запускать 8 отдельных запросов? Что-то вроде
<?php
$stations = array('radio 538', 'radio veronica', 'slam fm', '3fm');
foreach ($stations as $station)
{
$query = sprintf('SELECT * FROM table WHERE radioname="%s" ORDER BY time ASC LIMIT 0,13', $station);
// do something
}
?>
[непроверено!]
Комментарии:
1. Это приемлемо, но я надеялся на решение mysql. Но теперь я знаю, что это не так, это сделает свое дело.