3

10,000人のユーザーがいて、主キーが1から10,000までの一意のIDである場合、元の主キーを推測できないように、すべてのユーザーに一意のIDを与える方法はありますか?

たとえば、Facebookプロファイルなどへのリンクはhttp://site.com/profile?id=293852になります。

そこにあるIDは、データベース内のユーザーの主キーと同じである可能性がありますか?ランダムに生成されたものは一意である必要があるため、2つの無関係な一意のID列を作成する方法を考えるのに苦労しています。数字だけを使ってGUIDを作成できるとしたら、長さが長すぎると思います。

そしてアイデア?

4

5 に答える 5

2

システム内のユーザーの列挙を避けるために、ID を非連続にすることをセキュリティ上の理由から本当にお勧めします。しかし、40 億 (つまり 2^32) は小さすぎて、検出不可能な間隔を提供できません。そのため、GUID の方が適しています。データベースに応じて (仕様を見ると MSSQL のように見えます)、guid のようなフィールド、バイト フィールド (MySQL の場合)、または 2 つの個別の int64 に格納できます。

URL のサイズを小さくするために、base64 エンコーディングを適用して、GUID が短く見えるようにすることができます。

于 2011-02-14T10:55:38.860 に答える
2

通常、次の 2 つのオプションがあります。

  1. あなたが言ったように、ランダムに生成されたデータを使用してください。(それらが一意であることを確認する必要があるだけです。つまり、十分な長さ、または生成-検証-再試行のいずれかです。)
  2. 主キーを取得し、それを「疑似ランダムに」、主キーとは何の関係もないように見える別のものに変換します。変換は非常に単純かもしれません (穏やかな保護だけが必要なnew Random(primaryKey).NextInt()場合)

しかし、それでは…なぜ主キーの値を保護する必要があると思いますか? ユーザーが他の有効なユーザー ID を推測できないようにすることが唯一の理由である場合は、主キーにランダムな文字列を追加するだけです (データベースに保存し、アクセス時にその正確性を検証します)。

于 2011-02-14T10:56:52.843 に答える
1

ランダムで一意の ID をどのように生成するかは有用な質問ですが、それらをいつ生成するかについて仮定しているようです!

私のポイントは、挿入されるデータとは本質的に独立しているため、行の作成時にこれらの ID を生成する必要がないということです。

私がしていることは、将来の使用のためにランダムな ID を事前に生成することです。そうすることで、自分の甘い時間をかけてそれらが一意であることを絶対に保証でき、挿入時に処理を行う必要がありません。

たとえば、order_id を含む orders テーブルがあります。この ID は、ユーザーが注文を入力するとその場で生成され、1、2、3 などのように永久に増分されます。ユーザーは、この内部 ID を確認する必要はありません。

次に、別のテーブルがあります-random_ids with (order_id, random_id)。次の 24 時間に挿入される可能性のある注文をカバーするのに十分な数の行をこのテーブルに事前にロードする、毎晩実行するルーチンがあります。(1 日で 10000 件の注文があった場合、問題が発生しますが、それは良い問題です!)

このアプローチにより、一意性が保証され、処理負荷が挿入トランザクションからバッチ ルーチンに移され、ユーザーには影響しません。

于 2011-08-05T11:02:30.103 に答える
0

ユーザーが主キーを参照できるようにすることの何が問題になっていますか?

数字をランダムに生成し、衝突が起こらないように非常に大きな数字であることを確認してから、選択を実行して存在しないことを確認します。

または、膨大な数を選択して、それに基づいて方程式を立てることもできます。何かのようなもの:

unique = 1000000000 * (-1 * PK)^3

つまり、固有の数値は、PK が増加するにつれて開始数値から遠ざかり、PK が奇数か偶数かに応じて開始数値より上または下になります。方程式を複雑にすればするほど、発見される可能性は低くなりますが、誰かが解決する可能性は常にあるため、この方法に 100% 依存することは決してありません。

于 2011-02-14T10:55:57.220 に答える
0

私がしているのは、GUID の一部と実際の ID を使用することです。

テーブルには、デフォルト値が newid() の列タイプの uniqueidentifier があります。

次に、その一部を取り、実際のシリアル ID を末尾に追加し、その間に既知の区切り文字を付けます。これは GUID に表示されないため、文字 H を使用します。

したがって、行 #8659 の場合:
IDcolumn=8659
GUIDcolumn='{200BAB55-C7D5-4456-AB57-CFF8B7E82A90}'
PROFILECODE='200BAB55H8659'

次の方法で正しい行を見つけることができます。

partGUID=split(PROFILECODE,'H')(0) - gives 200BAB55
realID=split(PROFILECODE,'H')(1) - give 8659
select * from mytable where IDcolumn=8659 and left(GUIDcolumn,8)='200BAB55';

理論的には、SQL パーサーは最初に IDcolumn 8659 を​​持つすべての行を見つけてから、GUIDcolumn をチェックする必要があります。

プロファイルの ID を推測しようとしても、その一部を変更しただけでは成功しません。

于 2011-02-14T10:59:04.717 に答える