Как проверить, существует ли значение в БД mySQL? - PullRequest
3 голосов
/ 24 декабря 2011

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

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

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

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

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

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

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

Есть ли другой способ? И в БД, и в Perl.

Ответы [ 3 ]

4 голосов
/ 24 декабря 2011

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

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

  1. Если я правильно понимаю вашу проблему, вам нужно посмотреть на транзакции. Вы должны иметь возможность проверять данные и вставлять данные, прежде чем кому-либо еще будет разрешено проверять эти данные. Это удержит второй экземпляр скрипта от проверки данных, пока 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);
    

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

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

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

РЕДАКТИРОВАТЬ: продолжая описанный выше код и выполняя свою работу за вас, вот что вы бы сделали, если вставка прошла успешно.

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 голосов
/ 24 декабря 2011

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

0 голосов
/ 24 декабря 2011

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

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

...