最有效的方式......独特的随机字符串

时间:2009-10-03 14:41:09

标签: asp.net database random unique

我需要有效地将5个字符的RANDOM字符串插入数据库,同时确保它是独一无二的。生成随机字符串不是问题,但目前我正在做的是生成字符串,然后检查数据库是否已经存在......如果存在,我重新开始。

是否有更有效的方法来完成此过程?

请注意,我不想使用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 个答案:

答案 0 :(得分:9)

创建一个包含大量5个字符字符串的表,这些字符串按顺序添加(因此它们是唯一的),并且具有GUID作为其主键。添加一列以指示是否使用它们。

当你需要一个新号码时,你从池中选择前1,按guid排序(因此它变成随机的),并将结果设置为“花费”。

答案 1 :(得分:1)

您可以生成GUID并仅使用前5个字符吗?

答案 2 :(得分:1)

随机性更重要,还是独特性更重要? - 请注意,我说“更重要”;我知道你需要两者。

如果随机性更重要,那么您将需要某种方式来跟踪历史值。数据库本身(带有适当的索引)将是最好的方法。

如果唯一性更重要,那么只需使用计数器并将其填充到五位数即可。当然,这将限制为100,000行,因此您可以使用计数器和转换为字符空间(例如,1 =“A”,2 =“B”,27 =“AA”,依此类推)

答案 3 :(得分:1)

有一种方法可以随机选择未使用的独特单词,但它可能不会比你现在所做的更好。

原则是你确定未使用的单词的哪些排列,根据有多少未使用的permations生成一个随机数,然后选择那个。

例如,如果您使用包含三个字符的单词,并且只使用字符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的随机数,然后选择相应的排列。

保留所有可能的permeations列表当然不实用,所以你需要一个可以从字符串中确定置换索引的函数,以及一个可以从置换索引中确定字符串的函数。

此外,要确定哪些排列未使用,您必须检查使用了哪些排列,因此您仍需要在某个时候查询该表。

答案 4 :(得分:0)

如果要将字符串插入到现有的,已填充的表中,那么您将始终需要检查字符串是否不存在(它不必是显式的SELECT)。您可以手动操作,也可以对列具有UNIQUE约束并让数据库执行此操作。因此,如果数据库因为字符串已经存在而返回错误,则生成另一个错误。

请注意,如果您有一个空表并希望用多个随机字符串填充它,那么这是一个不同的问题。

答案 5 :(得分:0)

我认为你应该坚持自己的创意。对索引施加一个唯一约束并让数据库检查/报告欺骗是一种相当有效的欺骗检查方法,但这种假设取决于一些未提供的信息,如行数和遇到随机选择数据的欺骗的可能性。 / p>

使用您的参数完全预先填充唯一的序列池需要一个4.59亿行表。

您可以使用布隆过滤器将可管理的统计信息加载到数据库或主内存中并避免欺骗,但是根据行数和过滤器配置,当行数占459的可观比例时,这可能会导致过滤器饱和百万限制..由于过滤器可以报告误报,您应该努力确保您不会遇到系统卡住的情况,尝试通过过滤器永久接近的排列。

答案 6 :(得分:0)

如果你知道你的话有多长,为什么不采用基于树的方法呢? (我们称之为随机树步行)

说你的单词有n个字符。生成S中所有符号的列表,并将每个符号和计数器中可能位置的计数器相关联,基本上是维度为s乘以n的矩阵M.现在滚动你的骰子并选择第一个字母并查找M(s,1)。如果M(s,1)大于或等于以s开头的可能单词的数量,则再次滚动。否则增加M(s,1)。

对每个字母1到n重复此操作。

在您使用多达多个单词之前,应该非常快。