Customerテーブルには、IDのintIdentity列があります。これは顧客に配布される予定だったので、顧客が電話をかけるときにIDを提供するだけで済みました。
競合他社が私たちのサイトに2回、たとえば1か月間隔で簡単に登録して、正確に何人の人が登録したかを知ることができるのは明らかです。
したがって、次のような「顧客ID」(SQLまたはc#)を作成する簡単な方法はありますか?(a)6桁の長さ(b)一意(c)連続していない(
前もって感謝します
Customerテーブルには、IDのintIdentity列があります。これは顧客に配布される予定だったので、顧客が電話をかけるときにIDを提供するだけで済みました。
競合他社が私たちのサイトに2回、たとえば1か月間隔で簡単に登録して、正確に何人の人が登録したかを知ることができるのは明らかです。
したがって、次のような「顧客ID」(SQLまたはc#)を作成する簡単な方法はありますか?(a)6桁の長さ(b)一意(c)連続していない(
前もって感謝します
1000000 の因数ではない任意の増分を選択した場合は、その数値の最後の 6 桁を使用して ID を提供できます。すなわち(IDENTITY (1,7)) % 1000000
。
しかし、競合他社は、いくつかの連続した登録によって増加を見つけることができるため、これで問題が完全に解決されるわけではありません.
したがって、完全にランダムな数値が必要なようです。そのためには、生成時にそれが既に存在するかどうかを確認するか、数値のリストを事前に生成してランダムに並べ替え、次の数値を選択する必要があります。新しい顧客を作成します。
考慮すべきもう1つのオプションは、十分に短い出力を作成する適切なアルゴリズムを見つけるか作成できる場合、何らかの形式の暗号化です。
大きな非係数増分ルートを使用する場合、その後、数字の順序を並べ替えて、より乱数を作成できます。
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 フィールドから実行することができます
これは非常識かもしれませんが、顧客番号を前もって生成する私の方法を次に示します。
これにより、必要な数の UNIQUE キーが非常に迅速に生成されます。
明らかに、これらを実際のテーブルに保存できます。
これは以下の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 個の可能なすべてのキーが生成されます。これは、1 回限りのジョブでは問題ありません。
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()
Identity 列から生成された列を計算し、期待される一意の値を作成できます。
たとえば、以下のような計算列:
100000 + Identity_Column * 7 + 3
juts がユーザー登録のタイムスタンプを使用するとどうなりますか。ユーザーのカウント情報と一意の情報は含まれていません(たとえば、毎秒ユーザーを登録しない場合)。たとえば、このクエリで 10000 を使用すると、1 分ごとにユーザーを登録して、一意の 9 桁の記号を取得できます。
select cast(cast(current_timestamp as float)*10000 as int)
100.000 から 999.999 までの値を持つ列と、数値が与えられたかどうかを示すマーカーを持つ列の 2 つの列を持つテーブルを作成できます。新しいクライアントを作成するときは、このテーブルから未割り当ての番号をランダムに割り当て、割り当て済みとしてマークします。