客户ID(SQL)的唯一6位数字但不是连续的

时间:2012-08-29 12:05:53

标签: sql sql-server c#-4.0 random numbers

我们的Customer表有一个ID标识列。这将发给客户,所以当他们打电话时他们可以提供他们的身份证。

现在显而易见的是,我们的竞争对手可以轻松地在我们的网站上注册两次,比如相隔一个月,并确切地知道有多少人已注册。

因此,有一个很好的简单方法来创建一个“客户ID”(在SQL或c#中),我们可以给客户: (a)长6位数 (b)是独一无二的 (c)不是连续的(

提前致谢

5 个答案:

答案 0 :(得分:4)

如果您选择任何不是1000000因子的增量,那么您可以取该数字的最后6位数来提供ID;即(IDENTITY (1,7)) % 1000000

但是你的竞争对手仍然可以通过几个顺序注册找到增量,所以这不能完全解决问题。

所以看起来你想要一个完全随机的数字 - 所以为此,你必须在生成它时检查它是否已经存在,或者预生成数字列表,随机排序,然后选择创建新客户时的下一步。

另一种需要考虑的选择是某种形式的加密,如果您可以找到或创建一个能够创建足够短的输出的适当算法。

如果采用大的非因子增量路线,则可以随后重新排列数字的顺序以创建更随机的数字 - 例如;

declare @inc int , @loop int
declare @t table (i int, cn int, code varchar(4))

select @inc = 5173, @loop = 1
while @loop<=10000
begin
    insert @t (i, cn)
    select @loop, (@inc*@loop)%10000
    select @loop = @loop + 1
end

update @t 
set code = substring(convert(varchar(4),cn),2,1)
    + substring(convert(varchar(4),cn),4,1)
    + substring(convert(varchar(4),cn),3,1)
    + substring(convert(varchar(4),cn),1,1)

select code, count(*) from @t group by code having count(*)>1
select top 20 * from @t order by i 

根据您选择的数字,某些顺序项目之间会有相同的差异,但这个数字会有所不同。所以它不是加密安全,但可能足以阻止除最坚定的竞争对手之外的所有人。

您可以将上述内容转换为运行标准IDENTITY(1,1) id字段

的函数

答案 1 :(得分:3)

也许这是疯了,但这是我预先生成客户编号的方式。

这将生成许多您想要非常快的唯一键。

你显然可以将它们保存到真正的表格中。

以下是 SQLFiddle http://www.sqlfiddle.com/#!3/d41d8/3884

DECLARE @tbl TABLE
(
    ID INT IDENTITY(1,1),
    CustNo INT UNIQUE
)

DECLARE @Upper INT
DECLARE @Lower INT
DECLARE @NumberRequired INT

SET @Lower = 100000 ---- The lowest random number allowed
SET @Upper = 999999 ---- The highest random number allowed
SET @NumberRequired = 1000 -- How many IDs do we want?

WHILE (SELECT COUNT(*) FROM @tbl) < @NumberRequired
BEGIN
    BEGIN TRY
        INSERT INTO @tbl SELECT (ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0))
    END TRY
    BEGIN CATCH
        -- If it goes wrong go round the loop again
    END CATCH
END

SELECT  *
FROM    @tbl

编辑:实际上这可能更快。它在我的开发机器上在大约30秒内生成所有900000个可能的密钥,这对于一次性工作是可以的。

DECLARE @tbl TABLE
(
    ID INT
)

DECLARE @Upper INT
DECLARE @Lower INT
DECLARE @i INT;

SET @Lower = 100000 ---- The lowest random number allowed
SET @Upper = 999999 ---- The highest random number allowed

SET @i = @Lower

WHILE @i <= @Upper
BEGIN
    INSERT INTO @tbl SELECT @i
    SET @i = @i + 1
END

SELECT  ID
FROM    @tbl ORDER BY NEWID()

答案 2 :(得分:0)

您可以拥有从Identity列生成的计算列,并创建Expect的唯一值。

例如计算列如下:

100000 + Identity_Column * 7 + 3

答案 3 :(得分:0)

如果juts使用用户注册时间戳,该怎么办?它不包含用户的计数信息和唯一(例如,如果您没有每秒注册用户)。例如,如果在此查询中使用10000,则可以每分钟注册用户并获得唯一的9符号数字:

select cast(cast(current_timestamp as float)*10000 as int)

答案 4 :(得分:0)

您可以创建一个包含2列的表,其中一列的值为100.000至999.999,另一列的标记是否已发出数字。当新客户端随机分配此表中的未分配号码并将其标记为已分配时。