2011-12-24 3 views
3

У меня есть база данных mySQL, и у меня есть скрипт Perl, который подключается к нему и выполняет некоторые манипуляции с данными. Одна из таблиц в БД выглядит следующим образом:Как проверить, существует ли значение в базе данных mySQL?

CREATE TABLE `mydb`.`companies` (
    `company_id` INT NOT NULL AUTO_INCREMENT, 
    `company_name` VARCHAR(100) NULL , 
    PRIMARY KEY (`company_id`)); 

Я хочу, чтобы вставить некоторые данные в этой таблице. Проблема в том, что некоторые компании в данных могут быть повторены.

Вопрос: Как проверить, что «имя_компании» уже существует? Если он существует, мне нужно получить «company_id» и использовать его для вставки данных в другую таблицу. Если это не так, то эту информацию следует ввести в эту таблицу, но у меня уже есть этот код.

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

Я могу добавить дополнительный запрос «SELECT», но это создаст дополнительный удар по БД.

Я попытался найти ответ, но каждый вопрос здесь или поток в Интернете говорят об использовании проверки первичного ключа. Мне это не нужно. Структура БД уже установлена, но я могу внести изменения, если это необходимо. Эта таблица будет использоваться в качестве дополнительной таблицы.

Есть ли другой способ? Как в DB, ​​так и в Perl.

+0

Название компании должно быть частью первичного ключа, у вас не было бы проблем, если бы вы это сделали. – Mat

+0

Хорошая точка, Матем. Я добавил, что в качестве варианта 2 в своем ответе. –

+0

InnoDB или MyISAM? –

ответ

4

«Сценарий можно запускать несколько раз одновременно, поэтому я не могу просто прочитать данные в хэш и проверить, существует ли он уже».

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

  1. Предполагая, что я правильно понимаю вашу проблему, вам нужно посмотреть транзакции. Вы должны иметь возможность проверять данные и вставлять данные, прежде чем кому-либо разрешат проверять эти данные. Это заставит второй экземпляр скрипта проверять данные до тех пор, пока первый экземпляр не завершит проверку и вставку.

    Отъезд: http://dev.mysql.com/doc/refman/5.1/en/innodb-transaction-model.html

    И: http://dev.mysql.com/doc/refman/5.1/en/commit.html

    MyISAM не поддерживает транзакции. InnoDB делает. Поэтому вам нужно убедиться, что ваша таблица - InnoDB. Начните свой набор запросов с START TRANSACTION.

  2. В качестве альтернативы вы можете сделать это, если у вас есть уникальный указатель на company_name (что вам нужно).

    $query_string = "INSERT INTO `companies` (NULL,'$company_name')"; 
    

    Это приведет к ошибке, если company_name уже существует. Попробуйте пробный запуск, пытаясь вставить дублирующее название компании. В PHP

    $result = mysql_query($query_string); 
    

    $ результат будет равен false при ошибке.Так,

    if(!$result) { 
        $query2 = "INSERT INTO `other_table` (NULL,`$company_name`)"; 
        $result2 = mysql_query($query2); 
    } 
    

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

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

if(!$result) { 
    $query2 = "INSERT INTO `other_table` (NULL,`$company_name`)"; 
    $result2 = mysql_query($query2); 
} else if($result !== false) { // must use '!==' rather than '!=' because of loose PHP typing 
    $last_id = mysql_insert_id(); 
    $query2 = "UPDATE `other_table` SET `some_column` = 'some_value' WHERE `id` = '$last_id'"; 
    // OR, maybe you want this query 
    // $query2a = "INSERT INTO `other_table` (`id`,`foreign_key_id`) VALUES (NULL,'$last_id'); 
} 
+0

1. Я работаю с DB, делающим пару вставок за одну транзакцию. В основном я вставляю данные в пару таблиц внутри одной транзакции (7 или 8 таблиц), но только 3 нужно проверить, проверяются ли дубликаты внутри этой большой транзакции. 2. Как я сказал Mat, я не могу сделать его частью первичного ключа, я могу только установить его уникальным. Любая другая идея? Спасибо. – Igor

+0

Ну, решение №2 означает, что я дважды удалю БД: один раз на вставке, а затем выберите, чтобы извлечь идентификатор (первичный ключ). Этого недостаточно. Также таблица будет расти со временем, а загрузка на БД будет огромной. – Igor

+0

Вы говорите, что вам нужно получить идентификатор вставленного значения для использования в других таблицах? Это может показаться невероятным, но на самом деле это не требует 2-го удара. Дайте мне знать, если это то, что вы имеете в виду, и я добавлю это к своему ответу. –

0

Предлагаю вам написать хранимую процедуру (STP), которая принимает данные как название компании. В этом STP сначала проверьте существующее название компании. Если он существует, верните идентификатор. В противном случае введите и верните id.

Таким образом, вы попали БД только один раз

+1

Да, но нет гарантии избежать дублирования вставок с двумя экземплярами скрипта, запущенного одновременно. –

0

Для использования InnoDB сделки. Для таблицы блокировки MyISAM выполните модификации, разблокируйте.

Смежные вопросы