Лучший способ проверить наличие дубликатов ключей в базе данных - PullRequest
1 голос
/ 16 июня 2009

Это больше вопрос правильности. Скажем, у меня есть таблица со столбцом первичного ключа в моей базе данных. В моем коде DAO у меня есть функция с именем insertRow (строковый ключ), которая вернет true, если ключ не существует в таблице, и вставит новую строку с ключом. В противном случае, если строка с таким ключом уже существует, она возвращает false. Лучше / хуже, чтобы insertRow сначала проверял наличие ключа или просто продолжал вставлять и ловить ошибку дублирующегося ключа? Или экономия на одном операторе выбора - слишком тривиальная оптимизация, чтобы даже беспокоиться о ней?

Так в коде sudo:

boolean insertRow(String key){
    //potentially a select + insert
    if(select count(*) from mytable where key = "somekey" == 0){
       insert into mytable values("somekey")
       return true;
    }
    return false;
}

или

  boolean insertRow(String key){
    try{
       //always just 1 insert
       insert into mytable values("somekey")
       return true;
    } catch (DuplicateKeyException ex){}
    return false;
  }

Ответы [ 7 ]

6 голосов
/ 16 июня 2009

Вставьте строку, поймайте ошибку дублированного ключа. Мой личный выбор

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

Только проверяя оба сценария, вы точно будете знать

3 голосов
/ 16 июня 2009

Попробуйте вставить, затем поймайте ошибку.

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

User1: Check for key "newkey"? Not in database.
User2: Check for key "newkey"? Not in database.
User1: Insert key "newkey". Success.
User2: Insert key "newkey". Duplicate Key Error.

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

3 голосов
/ 16 июня 2009

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

Если целью кода является обновление, то вам следует либо воспользоваться предложением select или INSERT ... ON DUPLICATE KEY UPDATE (если поддерживается вашим механизмом базы данных.) В качестве альтернативы, создать хранимую процедуру, которая обрабатывает эту логику для вас.

2 голосов
/ 16 июня 2009

Второй, потому что первый вариант удваивает дБ, а второй - только один раз.

0 голосов
/ 16 июня 2009

Теперь, когда я нашел книгу Мартина Фаулера в Интернете, приличный способ сделать это - таблица ключей - см. Стр. 222 для получения дополнительной информации.

0 голосов
/ 16 июня 2009

еще две опции в MySQL должны использовать

insert ignore into....

и

insert into .... on duplicate key update field=value

в том числе on duplicate key update field=field

См .: http://dev.mysql.com/doc/refman/5.0/en/insert.html

Edit: Вы можете проверитьффекты_проверенных на предмет наличия или отсутствия эффекта вставки.

0 голосов
/ 16 июня 2009

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

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

Однако я бы предложил использовать EXISTS запрос вместо count(*)

if(exists (select 1 from mytable where key = "somekey"))
    return false
else
    insert the row

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

Другой вариант - полностью поместить логику в инструкцию SQL.

...