Самый эффективный способ ... Уникальная случайная строка - PullRequest
4 голосов
/ 03 октября 2009

Мне нужно эффективно вставить 5-символьную СЛУЧАЙНУЮ строку в базу данных, одновременно гарантируя, что она УНИКАЛЬНА. Генерация случайной строки не является проблемой, но в настоящее время я создаю строку, а затем проверяю БД, если она уже существует ... если это так, я начинаю заново.

Есть ли более эффективный способ сделать этот процесс?

Обратите внимание, я НЕ хочу использовать GUID или что-то еще, что больше 5 символов .... Я ДОЛЖЕН придерживаться 5 символов.

PS: я не думаю, что это имеет значение, но все мои строки чувствительны к регистру.

Вот часть "Случайная строка"

    Public Function GetRandomNumbers(ByVal numChars As Integer) As String
    Dim chars As String() = { _
     "A", "B", "C", "D", "E", "F", _
     "G", "H", "I", "J", "K", "L", _
     "M", "N", "O", "P", "Q", "R", _
     "S", "T", "U", "V", "W", "X", _
     "Y", "Z", "0", "1", "2", "3", _
     "4", "5", "6", "7", "8", "9", _
     "a", "b", "c", "d", "e", "f", _
     "g", "h", "i", "j", "k", "l", _
     "m", "n", "o", "p", "q", "r", _
     "s", "t", "u", "v", "w", "x", _
     "y", "z"}
    Dim rnd As New Random()
    Dim random As String = String.Empty
    Dim i As Integer = 0
    While i < numChars
        random += chars(rnd.[Next](0, 62))
        System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
    End While
    Return random
End Function

Ответы [ 7 ]

9 голосов
/ 03 октября 2009

Создайте таблицу с большим пулом из 5-символьных строк, которые добавляются последовательно (чтобы они были уникальными), и имеют GUID в качестве своего первичного ключа. Добавьте столбец, чтобы указать, используются ли они или нет.

Когда вам нужен новый номер, вы выбираете топ 1 из пула, упорядочиваете по гиду (чтобы он стал случайным) и устанавливаете результат как «потраченный».

1 голос
/ 03 октября 2009

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

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

Если вы, например, будете использовать слово из трех символов и только из символов 0 и 1, существует восемь возможных перестановок. Если вы уже использовали комбинации «010» и «100», вы получите что-то похожее на это:

PI = индекс перестановки
UI = неиспользованный индекс перестановки

No. PI UI
----------
000 0  0
001 1  1
010 2  -
011 3  2
100 4  -
101 5  3
110 6  4
111 7  5

Чтобы выбрать неиспользованную перестановку, вы просто генерируете случайное число от 0 до 5 и выбираете соответствующую перестановку.

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

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

1 голос
/ 03 октября 2009

Случайность важнее или уникальность важнее? - обратите внимание, что я сказал «более» важно; Я понимаю, что вам нужны оба.

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

Если уникальность важнее, просто используйте счетчик и добавьте его к нулю до пяти цифр. Это, конечно, ограничит вас 100 000 строк, поэтому вы можете альтернативно использовать счетчик и преобразование в символьное пространство (например, 1 = "A", 2 = "B", 27 = "AA" и т. Д.) .

1 голос
/ 03 октября 2009

Вы можете создать GUID и использовать только первые 5 символов?

0 голосов
/ 13 июля 2010

Как вы знаете, как долго ваше слово будет, почему бы не подход на основе дерева? (Давайте назовем это рандомизированной прогулкой по дереву)

Скажите, что ваше слово содержит n символов. Создайте список всех символов s в S и свяжите счетчик для каждого символа и возможного положения в строке, по сути, это матрица M измерений s, умноженная на n. Теперь бросьте свои кости и выберите первую букву и ищите M (s, 1). Если M (s, 1) больше или равно количеству возможных слов, начинающихся с s, поверните снова. В противном случае увеличьте M (s, 1).

Повторите это для каждой буквы от 1 до n.

Должно быть довольно быстро, пока вы не употребите много слов.

0 голосов
/ 03 октября 2009

Я думаю, вы должны придерживаться своей оригинальной идеи. Наложение уникального ограничения на индекс и разрешение для базы данных проверять / сообщать дубликаты для вас было бы довольно эффективным методом проверки дублирования, но это предположение зависит от некоторой не предоставленной информации, такой как количество строк и вероятность обнаружения дублирований со случайно выбранными данными. 1001 *

Полное предварительное заполнение уникального пула последовательностей с вашими параметрами требует 459 миллионов таблиц строк.

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

0 голосов
/ 03 октября 2009

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

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

...