Получить уникальный номер из файла, содержащего список номеров одновременно - PullRequest
1 голос
/ 17 октября 2011

У меня есть список уникальных номеров в файле. Всякий раз, когда пользователь моего сайта делает запрос, мне нужно получить значение из этого списка, чтобы ни один другой пользователь не получил такое же значение. Может быть много одновременных запросов, и, следовательно, основная проблема заключается в том, чтобы гарантировать, что никакие два пользователя не получат одинаковое значение. Меня не беспокоит производительность в том смысле, что пользователь не ожидает ответа после выполнения запроса, поэтому все может происходить в фоновом режиме. Из того, что я прочитал, это может быть реализовано с помощью файловых блокировок или я могу хранить данные в БД и использовать блокировки БД. Я просто хочу получить представление о том, как лучше всего это сделать. Я использую postresql в качестве базы данных, и мне было интересно, можно ли это сделать, используя последовательности, в которых я сохраняю текущий номер строки в последовательности, чтобы моя программа знала, какую строку читать из БД. Но, опять же, я не уверен, как предотвратить чтение одной строки несколькими процессами, прежде чем какой-либо из них сможет обновить ее.

1 Ответ

3 голосов
/ 17 октября 2011

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

  • Создайте таблицу: create table special_number (id serial, num varchar(100) not null);
  • Убедитесь в уникальности: create unique index special_number_num on special_number(num);
  • Загрузите свои числа в таблицу, используя COPY, позволяя идентификатору автоматически увеличиваться с 1
  • Создайте последовательность: create sequence num_seq;
  • Используйте тот факт, что функция postgres nextval гарантированно безопасна для одновременного выбора номера изсписок: select num from special_number where id = (select nextval('num_seq'));.Это вернет null, если у вас закончились цифры.

Этот подход на 100% безопасен и прост - внутренние преимущества postgres как базы данных делают всю тяжелую работу.

ВотSQL извлечен сверху:

create table special_number (id serial, num varchar(100) not null);
create unique index special_number_num on special_number(num);
copy special_number(num) from '/tmp/data.txt'; -- 1 special number per file line
create sequence num_seq;
select num from special_number where id = (select nextval('num_seq'));

Этот SQL был протестирован на postgres и работает как ожидалось.

...