Mysql помогите с использованием insert on duplicate key

Статус
В этой теме нельзя размещать новые ответы.

Artem_Paris

Новичок
Есть таблица sports, в которую я записываю спорт и страну.
Код:
$sport_list[] = array('sport'=>'russia', 'country'=>'football');
$sport_list[] = array('sport'=>'russia', 'country'=>'boxing');
$sport_list[] = array('sport'=>'russia', 'country'=>'tennis');
$sport_list[] = array('sport'=>'russia', 'country'=>'football');

foreach($sport_list as $sport)
{
   $sport_id = getId($sport);
         ......
}
А функции getId() я должен записать передаваемые данные в базу и вернуть id.
Но перед записью, нужно проверить наличие этой записи в базе, и если она там есть, то не записывать и вернуть просто id.
Вроде бы ничего сложного, делаю по самому простому, но самому долгому способу:
Код:
function getId($data)
{
    $res = $db->query("select id from sports where sport='{$data['sport']}' and country='{$data['country']}'");
    if($db->num_rows($res) == 0)
    {
        $sql = $db->query("INSERT INTO `sports` (`sport`, `country`) VALUES ('{$data['sport']}', '{$data['country']}')");
        $result = $db->query("select LAST_INSERT_ID() AS 'id'");
        $row = $db->fetch_row($result);
        return $row[0]['id'];
    }
    else
    {
        $row = $db->fetch_row($res);
        return $row[0]['id'];
    }
}
в базе:
UNIQUE KEY `id` (`id`),
KEY `sport` (`sport`),
KEY `country` (`country`)

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

AnrDaemon

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

Artem_Paris

Новичок
Не надо ничего проверять. БД без вас проверит и обругает, если что будет не так. При условии, что ключи стоят правильно.
этот вариант не рассматривается. нужно сделать все вышеописанные шаги каким-ниудь иным путем, который работает быстрее.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
А функции getId() я должен записать передаваемые данные в базу и вернуть id.
в функциях с названием getXXX не надо ничего никуда писать, эти функции должны только получать информацию

не работает, если я не передаю id.
ты его не передаешь в запросе
$sql = $db->query("INSERT INTO `sports` (`sport`, `country`) VALUES ('{$data['sport']}', '{$data['country']}')");
ты хочешь научиться или покапризничать?
 

Artem_Paris

Новичок
ты хочешь научиться или покапризничать?
Хочу научиться, но такие ответы явно мало чему меня научат.

итак, в функцию getId я все запихал, чтобы тут не расписывать по нескольким разным функциям и т.д. не надо к этому цепляться. да и не связано это с моим вопросом.

$sql = $db->query("Replace INTO `sports` (`sport`, `country`) VALUES ('{$data['sport']}', '{$data['country']}')");
Заново записывает в базу то, что у меня уже есть там. Если я при записи передаю еще и id, например :
$sql = $db->query("Replace INTO `sports` (`id`,`sport`, `country`) VALUES (1, '{$data['sport']}', '{$data['country']}')");
то только в этом случае происходит замена, а не запись. А так как у меня в запросах нет id, replace мне не поможет.
 

Artem_Paris

Новичок
Есть таблица:
Код:
CREATE TABLE `profiles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `surname` varchar(255) NOT NULL,
  `reg_date` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`),
  KEY `surname` (`surname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
в таблице помимо id может быть любое количество разных полей с индексами.
В таблице существует запись:
Код:
_____________________________________________
id   |    name    |  surname   |   regdate
_____________________________________________
1   |  Владимир   |   Иванов   |  01.01.2014
выплняю запросы:
Код:
INSERT INTO `profiles`(`name`, `surname`) VALUES ('Владимир', 'Иванов');
INSERT INTO `profiles`(`name`, `surname`) VALUES ('Иван', 'Владимирович');
После каждого запроса мне нужно вывести id записи.
При наличии похожих данных (запрос 1) вывести id существущей записи.
При отсутствии подобных данных в таблице (запрос 2), записать данные и вывести что-то вроде last_insert_id().

Это все делается удачно в вышеописанном коде, но делается жутко долго.

Если использовать ON DUPLICATE KEY UPDATE, то нужно чтобы id был уникальным полем и обязательно передавался в запросе.
Поэтому запрос:
Код:
INSERT INTO `profiles`(`name`, `surname`) VALUES ('Владимир', 'Иванов') ON DUPLICATE KEY UPDATE `name`='Владимир', `surname`='Иванов';
не срабатывает, как хотелось бы, а просто записывает еще одну запись в таблицу.
Можно ли заставить при insert делать проверку на дубликаты по передаваемым полям, а не по уникальному ключу?
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Я считаю, что после такого злостного нарушения CQS ни один уважающий себя человек не поможет этому говнюку.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Есть разные варианты, сделать REPLACE, создав предварительно уникальный ключ по 2м полям.

Если вставка одноразовая - добиться уникальности вставляемых данных и вставить их, предварительно убрав с таблицы ключи и потом создав их заного.

И что значит "работает долго"? Ты спешишь куда-то?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Повторю вопрос - ты хочешь научиться или покапризничать?
Ты хочешь научить или выступить?
по правилам и традициям форума переход на личности приводит к закрытию темы,
предлагаю продолжить горячее общение в другом месте
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху