Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Проблема с ON DUPLICATE KEY
Форумы портала PHP.SU » » Работа с СУБД » Проблема с ON DUPLICATE KEY

Страниц (1): [1]
 

1. Dragon_Knight - 21 Мая, 2012 - 04:25:30 - перейти к сообщению
Всем привет.

Нужно сделать запрос, который будет проверять, если есть запись, то добавить значение одного поля, если нету то создать запись.

Набросал такой код, но он не работает как положено...
CODE (SQL):
скопировать код в буфер обмена
  1. INSERT INTO `" . $MySQL_Table_Data . "` SET `id_url` = '" . $id_url . "', `referer` = '" . $Referer . "' ON DUPLICATE KEY UPDATE `count` = count + 1


Задача создать уникальное поле `referer` при `id_url` = '" . $id_url . "', а если запись уже есть, то `count` = count + 1
2. Medallion - 21 Мая, 2012 - 07:30:33 - перейти к сообщению
Задачу можно решить, но с дополнительной выборкой и условиями. Выбираем, сравниваем, если есть запись, ничего не делаем, если записи нет, добавляем. Но, я незнаю, достойный это вариант или нет. Хм
3. tuareg - 21 Мая, 2012 - 08:45:29 - перейти к сообщению
Вот тестовая таблица
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. CREATE TABLE `new_table` (
  3.   `id` int(11) NOT NULL AUTO_INCREMENT,
  4.   `count` tinyint(3) UNSIGNED NOT NULL DEFAULT '0',
  5.   PRIMARY KEY  (`id`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  7.  

Вот запрос
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. INSERT INTO `new_table` (`id`) VALUES (1) ON DUPLICATE KEY UPDATE `count`=`count`+1;
  3.  

Все работает
4. Dragon_Knight - 21 Мая, 2012 - 14:22:30 - перейти к сообщению
tuareg, Вы не внимательно прочитали мой запрос.

Задача сделать уникальное поле ТОЛЬКО при `id_url` = '" . $id_url . "'.
Другими словами, у конкретного значения `id_url` (int) не должно быть повторений полей `referer`, однако у разных `id_url`, значение `referer` может повторяться.

Я так подумал и понял что ON DUPLICATE KEY тут не подходит, и у меня есть только вариант с 3 запросами:
1) Проверяем наличие `referer` при `id_url` = '" . $id_url . "'
2) Если запись есть, то обновляем count
3) Если записи нету, то создаём её.

Т.е. как-то так, но не уверен что это оптимальное решение
PHP:
скопировать код в буфер обмена
  1. $query_1 = mysql_query("SELECT `id` FROM `" . $MySQL_Table_Data . "` WHERE `id_url` = '" . $id_url . "' AND `referer` = '" . $Referer . "' LIMIT 1");
  2. if(mysql_num_rows($query_1) == 1) // найдено
  3. {
  4.         $row = mysql_fetch_row($query_1);
  5.         $query_2 = mysql_query("UPDATE `" . $MySQL_Table_Data . "` SET `count` = count + 1 WHERE `id` = '" . $row['0'] . "'");
  6. }
  7. else // НЕ найдено
  8. {
  9.         $query_2 = mysql_query("INSERT INTO `" . $MySQL_Table_Data . "` (`id_url`, `referer`) VALUES ('" . $id_url . "', '" . $Referer . "')");
  10. }
5. tuareg - 21 Мая, 2012 - 18:27:41 - перейти к сообщению
Я Вам советую( настоятельно!!!) почитать про индексы в MySQL (какие они бывают, зачем они и т.д) Ваша задача решается одним запросом. Я его Вам привел. Нужно просто сделать индексы.
6. Dragon_Knight - 21 Мая, 2012 - 18:38:30 - перейти к сообщению
tuareg, Я читал и понял что одним запросом это не сделать, иначе я-бы тут не спрашивал.
А то что Вы предоставили сделает уникальный ключ по ВСЕЙ таблице, что неприемлемо.

Таблица должна быть такого формата:
CODE (htmlphp):
скопировать код в буфер обмена
  1. | id | id_url |   referer   | count |
  2. -------------------------------------
  3. | 1  |    1   |  yandex.ru  |   3   |
  4. | 2  |    1   |  google.ru  |   2   |
  5. | 3  |    1   |  rambler.ru |   1   |
  6. | 4  |    2   |  yandex.ru  |   5   |
  7. | 5  |    2   |  google.ru  |   6   |
  8. | 6  |    2   |  rambler.ru |   7   |
  9. | 7  |    3   |  yandex.ru  |   1   |
  10. | 8  |    4   |  yandex.ru  |   1   |
7. tuareg - 21 Мая, 2012 - 19:50:09 - перейти к сообщению
Извините, если я "погорячился". Давайте по порядку.
Итак.
Зачем Вам нужно поле id? Возможно оно Вам нужно для других запросов? Если да то его оставляем, если нет, то можно удалить.
Потом я имел ввиду:
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. CREATE TABLE `new_table` (
  3.   `id` int(11) NOT NULL AUTO_INCREMENT,
  4.   `id_url` int(11) UNSIGNED NOT NULL DEFAULT '0',
  5.   `referer` varchar(255) NOT NULL DEFAULT '',
  6.   `count` int(11) UNSIGNED NOT NULL DEFAULT '0',
  7.   PRIMARY KEY  (`id`),
  8.   UNIQUE KEY `nashIndex` (`id_url`,`referer`(10))
  9. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  10.  

Запрос
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. INSERT INTO `new_table`(`id_url`,`referer`) VALUES (1,'yandex.ru') ON DUPLICATE KEY UPDATE `count`=`count`+1;
  3.  

Выполните пару раз запрос.
Но эта конструкция тоже не совсем оптимальна(она работает, не оптимальна в плане размера индекса, если это не критично, тогда...). Если она Вас устроит, тогда ОК. Иначе это отдельный вопрос.
P.S Эта конструкция идеальна для простого: если нет-->вносим иначе--> увеличиваем count на 1
8. Dragon_Knight - 21 Мая, 2012 - 22:21:41 - перейти к сообщению
tuareg, да именно это и требуется. Спасибо.
Тока вопрос про табличку, можете поподробнее рассказать про "UNIQUE KEY `nashIndex` (`id_url`,`referer`(10))"
Как я понял:
nashIndex - Имя, в данном случае без разницы что указать.
(*) - Список полей, которые не должны совпадать (по логике AND).
Но вот что такое `referer`(10) - цифра 10 - ??
(Добавление)
Методом случайных проб и не менее случайных ошибок понял, что 10, это длинна сравниваемой строчки, и если строка длиннее, то сравниваются только первый 10 символов.

В итоге пришёл к такой базе:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE IF NOT EXISTS `url_data` (
  2.   `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  3.   `id_url` int(11) UNSIGNED NOT NULL,
  4.   `referer` varchar(255) NOT NULL,
  5.   `count` int(11) UNSIGNED NOT NULL DEFAULT '1',
  6.   PRIMARY KEY (`id`),
  7.   UNIQUE KEY `nashIndex` (`id_url`,`referer`(255))
  8. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;

И к такому запросу:
PHP:
скопировать код в буфер обмена
  1. $query = mysql_query("INSERT INTO `" . $MySQL_Table_Data . "`(`id_url`,`referer`) VALUES ('" . $id_url . "','" . $Referer . "') ON DUPLICATE KEY UPDATE `count` = `count`+1");


tuareg, Ещё раз Спасибо! Улыбка

 

Powered by ExBB FM 1.0 RC1