在SQL Server中生成看似随机的唯一数字ID

我需要使用SQL Server生成看似随机的唯一8位数字 ID(可以在前面填充零)。 这是否有内置function? 我看到了这个 Identity属性,但它是顺序的,而不是随机的。

如果这是不可能的,那么直接将随机生成的ID写入db然后检查exception是不错的做法? (请注意,我的应用程序是multithreading的,因此在写入之前进行检查并不能保证唯一性,除非在primefaces操作中完成。)

谢谢!

更新:添加“数字”以澄清。 编辑表明随机性不需要加密强或任何接近。 看似随意就好了。 奥利弗提出了一个优雅的解决方案,我已经使用这种方法发布了答案。 谢谢,奥利弗!

随机性与唯一性发生冲突,但@Oliver提出了一种优雅的解决方案,当数字只需要随机出现时 ,同时存在基础订单。 来自Erics的http://ericlippert.com/2013/11/14/a-practical-use-of-multiplicative-inverses/ ,主要思想是,给定一对互质,正整数x和m,我们可以找到乘法逆 y,其中(x * y)%m == 1.这非常有用,因为给定数据库行ID z,我们可以通过执行encoded = (z*x) % m将z映射到另一个整数。 现在给出这个encoded ,我们怎样才能得到z? 简单, z = (encoded * y) % m因为(x*y*z) % m == z给定z

请注意,Eric展示了如何计算这个乘法逆。 但如果你很懒,就有这个 。

在我的实现中,我只是按原样存储每行的顺序ID。 然后,每个ID都映射到另一个数字,类似于文章中的“InvoiceNumber”。 当客户退回此“InvoiceNumber”时,您可以使用乘法反转将其映射回其原始数据库ID。

下面是从0到9的编码和解码序列的C#示例。

 public static void SeeminglyRandomSequence() { //use long to prevent overflow long m = 10; //modulo, choose m to be much larger than number of rows long x = 7; //anything coprime to m long y = 3; //multiplicative inverse of x, where (y*x) % m == 1 List encodedSequence = new List(); List decodedSequence = new List(); for (long i = 0; i < m; i++) { long encoded = (i * x) % m; encodedSequence.Add(encoded); } foreach (long encoded in encodedSequence) { long decoded = (encoded * y) % m; decodedSequence.Add(decoded); } Debug.WriteLine("just encoded sequence from 0 to {0}. Result shown below:", (m - 1)); Debug.WriteLine("encoded sequence: " + string.Join(" ", encodedSequence)); Debug.WriteLine("decoded sequence: " + string.Join(" ", decodedSequence)); } 

印刷结果是:

 just encoded sequence from 0 to 9. Result shown below: encoded sequence: 0 7 4 1 8 5 2 9 6 3 decoded sequence: 0 1 2 3 4 5 6 7 8 9 

如您所见,每个输入都映射到一个唯一的输出,并且很容易反转此映射。 在您的应用程序中,您可能希望从1开始,因为0始终映射到自身。

只是为了显示较大m的“表观随机性”,下面是m = 100,000,000时的前10个映射:

 just encoded sequence from 1 to 10. Result shown below: encoded sequence: 81654327 63308654 44962981 26617308 8271635 89925962 71580289 53234616 34888943 16543270 decoded sequence: 1 2 3 4 5 6 7 8 9 10 

使用以下查询创建8位数的randow唯一编号。

 SELECT CAST(RAND() * 100000000 AS INT) AS [RandomNumber] 

在查询下使用现有数字插入DB时避免exception。

 IF NOT EXIST(SELECT UniqueColumnID FROM TABLENAME WHERE UniqueColumnID = @RandowNumber) BEGIN --Insert query using @RandowNumber. END 

您可以使用NEWID()生成每次始终随机且唯一的uniqueIdentifier数据

要获得8个字符,您可以使用substring,left etc等function。

 select substring( cast( NEWID() as varchar(100)),0,8) 

或唯一性的新逻辑: – http://forums.asp.net/t/1474299.aspx?How+to+generate+unique+key+of+fixed+length+++digit+in+sql+server+2005 +

 select Left(NewID(),4)+Right(NewId(),4) 

你也可以使用random()函数。

检查此链接: 如何为TSQL选择中的每一行生成随机数?

如何在SQL Server中获取数字随机唯一ID

更新如果要使用唯一值int数据类型和8个字符长。 很好地创建如下所示的标识列,这对于8个字符长度的数据意味着(10,000,000)。 但之后它会给你例外。 所以要小心你想要的逻辑。(我仍然说,这是个坏主意)。 以如上所述的随机值存储,具有更长的长度,因此具有唯一性。

 create table temp (id numeric(8,0) IDENTITY(1,1) NOT NULL, value1 varchar ) --if you want do not stop after 8 character , give int datatype. insert into temp values( 'a'), ('b'), ('c') select * from temp drop table temp 

最后

它不能保证唯一,但很难通过NEWID()获得重复(参见上面的链接forums.asp.net)

创建SQL函数或过程如下:

 ALTER FUNCTION [dbo].[GenerateRandomNo] ( @Lower INT = 111111111, @Upper INT = 999999999 ) RETURNS NVARCHAR(128) AS BEGIN DECLARE @TempRandom FLOAT DECLARE @Random NVARCHAR(128); -- Add the T-SQL statements to compute the return value here SELECT @TempRandom = RandomNo from RandomNo SELECT @Random = CONVERT(NVARCHAR(128),CONVERT(INT,ROUND(((@Upper - @Lower -1) * @TempRandom + @Lower), 0))) WHILE EXISTS(SELECT * FROM Table WHERE Column = @Random) BEGIN SELECT @TempRandom = RandomNo from RandomNo SELECT @Random = CONVERT(NVARCHAR(128),CONVERT(INT, ROUND(((@Upper - @Lower -1) * @TempRandom + @Lower), 0))) END -- Return the result of the function RETURN @Random END 

如果要生成具有特定长度或范围的随机数,则调用该函数传递参数。

  --create -- table Tbl( idx int) DECLARE @unique_id int SET @unique_id= ( SELECT ROUND( 89999999 * RAND( ) + 10000000 , 0 ) ) IF not EXISTS( SELECT idx FROM tbl WHERE idx = @unique_id ) BEGIN INSERT INTO tbl( idx ) VALUES( @unique_id ) SELECT @unique_id, * FROM tbl END; --TRUNCATE TABLE tbl