Будут ли все числа в таблице на 100% уникальными, если использовать этот простой алгоритм?

#mysql #sql #uniqueidentifier

#mysql #sql #уникальный идентификатор

Вопрос:

Моя цель — вставлять новое и уникальное (уникальность очень важна) число в таблицу MySQL на сервере каждый раз при событии на компьютере пользователя, используя ajax.

Итак, часть сервера в пользовательском событии делает это (используя php):

  • Находит максимальное значение из столбца в базе данных,
  • Добавляет 10 к максимальному значению,
  • это новое и уникальное (больше максимального) значение, мы вставляем insert в таблицу.

Будут ли все числа уникальными и будут похожи на 1, 11, 21, 31, если они начинаются с 1? Мне любопытно, завершится ли вставка в таблицу до того, как она начнет выполнять другую очередь, и может ли быть похоже 1, 11, 21, 21, 31, 41?

Если это теоретически работает так (упорядочено по времени)

  1. найдите максимальное значение из столбца для первого пользователя
  2. найдите максимальное значение из столбца для второго пользователя (оно будет таким же)
  3. вставьте (максимум 10) для первого пользователя в ту же таблицу
  4. вставьте (максимум 10) для второго пользователя в ту же таблицу (это будет то же самое), тогда результаты будут одинаковыми, и 1 значение может повторяться дважды или даже больше…

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

Добавлено: Можно ли быть уверенным с помощью этого алгоритма и без использования автоинкрементов? Автоинкремент используется для другого столбца. Пробелы между числами в порядке. Единственное требование заключается в том, что числа должны быть разными, но с некоторой «дельтой», которая больше единицы. Извините, я не заметил этого в своем вопросе. Спасибо.

Комментарии:

1. Почему бы просто не использовать ключ автоматического увеличения?

2. @OliCharlesworth В таблице может быть только один автоматически увеличивающийся столбец.

3. Либо вы не знаете о типе данных столбца, который делает это за вас, либо есть требования, о которых вы нам не сообщаете.

4. @Alex: max 1 вызвало бы проблемы, если бы две вставки произошли в одно и то же время. В зависимости от ограничений уникальности либо один из запросов завершится ошибкой, либо обе строки получат одинаковое значение.

5. @Alex: Потому что идентификаторы guid уродливы и громоздки. ‘151543’ гораздо менее внушителен, чем ‘1513512-2842-2344-1616-34c5643610fe’ или что-то еще. Особенно когда БД может автоматически увеличивать идентификатор int для вас, но вам нужно вызвать функцию, чтобы получить новый идентификатор guid. Лучше избегать их, если они не являются абсолютно необходимыми.

Ответ №1:

Если у вас нет особых причин против этого, я рекомендую использовать AUTO_INCREMENT — это будет масштабироваться намного лучше и фактически оставит меньше «дыр» в последовательности чисел, чем ваш подход.

И вы правы — ваш подход на самом деле не гарантирует уникальность в параллельной среде. Один из способов заставить ваш алгоритм работать — установить УНИКАЛЬНОЕ ограничение на ваше поле (если оно еще не является ПЕРВИЧНЫМ КЛЮЧОМ), а затем неоднократно пытаться вставить новое значение — если это не удается, просто сгенерируйте новое значение и повторите попытку, и в конечном итоге это удастся.

Ответ №2:

Используйте автоматически увеличивающийся столбец в базе данных

Ответ №3:

Похоже, вы хотите использовать автоинкремент.

Ответ №4:

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

 insert into mytable (
  column1,
  column2,
  fake_auto_incr
) select
    'value for column1',
    'value for column2',
    max (fake_auto_incr)   1
  from mytable
  

Поскольку insert это транзакционный оператор, базы данных ACID гарантируют, что max 1 трюк всегда на единицу больше текущего верхнего значения.

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

 insert into mytable (
  column1,
  column2,
  fake_auto_incr
) select
    'value for column1',
    'value for column2',
    coalesce (max (fake_auto_incr), 0)   1
  from mytable
  

Это приводит к тому, что начальное значение в пустой таблице становится равным 1, в противном случае используется следующее доступное значение.