2017-01-09 2 views
0

У меня есть большой стол (5 миллионов строк), с уникальным идентификатором колонкой под названием «unique_id»Использование уникального индекса MySQL для предотвращения дублирования, а не для повторного поиска?

Я бег запрос INSERT через Node.js (node-mysql привязок), и есть шанс, что дубликаты могут быть предприняты попытка для вставки.

два решения:

1) Make 'unique_id' индекс, и проверьте всю базу данных для повторяющейся записи, до ВСТАВИТЬ:

'SELECT unique_id WHERE example = "'+unique_id+'" LIMIT 1' 

2) Make 'unique_id' а уникальный индекс в MySQL и выполнить INSERT без проверки дубликатов. Очевидно, что любые дубликаты вызовут ошибку и не будут вставлены в таблицу.

Моя догадка заключается в том, что решение 2) лучше, так как оно предотвращает поиск в худшем случае (5 миллионов - 1) строк для дубликата.

Есть ли недостатки в использовании решения 2)?

ответ

1

Существует целый ряд преимуществ для определения уникального, первичный индекс для unique_id колонки:

  • Семантическая корректность - настоящее имя не отражает реальность, как вы можете иметь дубликаты в столбце под названием «unique_id»,
  • Автогенерация уникальных идентификаторов - вы можете делегировать это задание в базу данных и избежать конфликта идентификаторов (это не будет проблемой, если вы используете UUID вместо целых чисел),
  • Ускорение скорости - чтобы быть надежным решением 1 потребуется блокирующая транзакция (новые строки не должны быть вставлены между проверкой дублирования cate и вставка строки). Делегирование этого в MySQL будет намного более эффективным,
  • Следуя общему шаблону - это именно то, для чего были разработаны уникальные и первичные индексы. Ваше решение будет легко понять другим разработчикам,
  • Меньше кода.

С помощью второго решения вам может потребоваться обработать попытку вставить дубликат (если только ваши уникальные идентификаторы не генерируются MySQL).

Autoincremented Первичный индекс: https://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html

+0

Спасибо, это хороший ответ –

1

Удивительно, но это мало разница в производительности мудрым. Поиск будет использовать (и требует) тот же самый индекс.

Какое небольшое различие в производительности существует, однако, в пользу вашего (2) решения.

На самом деле в MySQL вы можете избавиться от ошибок в целом, используя ключевое слово IGNORE:

INSERT IGNORE INTO ... VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)...; 

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

Вас также может заинтересовать семейство трюков ON DUPLICATE KEY UPDATE :-).

Настоящая разница, как M.M. уже указано, находится в целостности. Используя ограничение UNIQUE-индекса, вы уверены в своих данных; в противном случае вам нужно ЗАБЛОКИРОВАТЬ таблицу между моментом, когда вы ее проверяете, и в тот момент, когда вы вставляете новый кортеж, чтобы избежать риска того, что кто-то другой добавит то же значение.


Ваше (1) решение может иметь место, если «duplicateness» данные требует значительной бизнес-логику работы, которые не могут быть легко переведены на ограничение MySQL. В этом случае вы бы

  • блокировать таблицу,
  • поиска кандидатов дубликатов (скажем, вы получите 20 из них),
  • выборки данных и убедитесь, что они ли действительно кандидаты
  • вставки новый кортеж, если он не конфликтует,
  • освободите замок.

(Можно было бы утверждать о хороших основаниях, что нужно сделать такую ​​сложная карусель проистекает из какой-то ошибки в проектировании баз данных. В идеале вы должны быть в состоянии сделать все, что в MySQL. Но Деловая реальность имеет способ быть далеко от идеала иногда).

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