6

我们的 Customer 表有一个用于 ID 的 int Identity 列。这将提供给客户,因此当他们打电话时,他们只需提供他们的 ID。

现在很明显,我们的竞争对手可以很容易地在我们的网站上注册两次,比如相隔一个月,然后就可以知道有多少人注册了。

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

提前致谢

4

5 回答 5

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 字段

于 2012-08-29T12:10:47.347 回答
3

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

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

您显然可以将这些保存到真实表格中。

这是下面的SQLFiddlehttp ://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()
于 2012-08-29T12:46:00.520 回答
0

您可以计算从标识列生成的列,并创建期望的唯一值。

例如计算列如下:

100000 + Identity_Column * 7 + 3

于 2012-08-29T12:23:22.150 回答
0

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

select cast(cast(current_timestamp as float)*10000 as int)
于 2012-08-29T12:27:55.743 回答
0

您可以制作一个包含 2 列的表格,一列的值是 100.000 到 999.999,另一列带有标记是否已给出数字。当让一个新客户从这个表中随机分配一个未分配的号码并将其标记为已分配。

于 2012-08-29T12:41:59.707 回答