2

エレガントに解決する方法がわからない問題があります。

背景情報

ウィジェットのテーブルがあります。各ウィジェットには、1 から 999 までの範囲の数字から ID が割り当てられます。1 ~ 999 の値は、データベースの「config」というテーブルに「lower_range」および「upper_range」として保存されています。ユーザーが Web アプリを使用して新しいウィジェットを作成するように要求した場合、次のことを実行できる必要があります。

  • lua の math.random 関数または sqlite の乱数ジェネレーターを使用して、1 から 999 までの乱数を生成します (これまでのところ、私のテストでは、lua の math.random は常に同じ値を返します...しかし、それは別の問題です)。
  • select ステートメントを実行して、この番号が割り当てられたウィジェットが既に存在するかどうかを確認します...
  • そうでない場合は、新しいウィジェットを作成します。
  • それ以外の場合は、現在使用されていない番号を取得するまでプロセスを繰り返します。

問題

上記のロジックで見られる問題は 2 つあります。

  1. 一意の値が見つかるまで検索を続ける必要があるため、アルゴリズムには時間がかかる可能性があります。
  2. 同じ値を生成する新しいウィジェット番号の同時要求を防ぐにはどうすればよいですか?

任意の提案をいただければ幸いです。ありがとう

4

5 に答える 5

2

事前に乱数を生成し、テーブルに保存します。番号が一意であることを確認してください。次に、次の番号を取得する必要がある場合は、既に割り当てられている番号を確認して、テーブルから次の番号を取得します。だから、代わりに

  • 1 ~ 999 の数字を生成する
  • すでに割り当てられているかどうかを確認する
  • 新しい番号などを生成します。

これを行う:

  • ランダムな順序で 1 ~ 999 の値を持つ 999 個の要素の配列を生成します
  • あなたのGetNextId機能はreturn ids[currentMaxId+1]

同時リクエストを管理するには、適切なシーケンスを生成するリソースが必要です。おそらく最も簡単な方法は、ウィジェット テーブルのキーをids配列のインデックスとして使用することです。widgetsしたがって、最初にレコードをテーブルに追加し、そのキーを取得してから、 を使用してウィジェット ID を生成しますids[key]

于 2013-05-08T18:20:05.190 に答える
1

乱数を生成しないでください。ランダムな順序のリストから番号を選択してください。

たとえば、1 ~ 999 の数字のリストを作成します。Fisher-Yatesまたは同等の方法を使用してそのリストをシャッフルします ( C#を使用していない場合でも、C# でリストをランダム化するも参照してください)。

これで、最近使用したインデックスをリストで追跡できます。(リストのシャッフルは 1 回だけ行う必要があり、その後、結果を保存して再利用します)。

大まかな擬似コード:

If config-file does not contain list of indices
    create a list with numbers 1 - 999
    Use Fisher-Yates to shuffle that list
    // list now looks like 0, 97, 251, 3, ...
    Write the list to the config file
    Set 'last index used' to 0 and write to config file
end if

これを使用するには、

NextPK = myList[last-index-used]
last-index-used = last-index-used + 1
write last-index-used to config file
于 2013-05-08T18:16:35.093 に答える
1

キーと「使用済み」プロパティを格納するテーブルを作成します。

CREATE TABLE KEYS
  ("id" INTEGER, "used" INTEGER)
;

次に、次を使用して新しいキーを見つけます

select id
from KEYS
where used = 0
order by RANDOM()
limit 1
于 2013-05-08T18:15:16.567 に答える
0

同時に使用されている ID を取得してフラグを立てるには (Declan_K の回答を拡張):

random_sequence 値に置き換えます ((使用される random_sequence から ID を選択 = 0 order by random()), 1);

rowid = last_insert_rowid(); の random_sequence から ID を選択します。6

「未使用」のシーケンス テーブル エントリがなくなると、select は「空白」を返します。

更新には、私が見ることができる last_insert_rowid() 同等物がないため、replace into を使用します。

于 2013-05-08T21:07:44.793 に答える
-2

SQL を使用して主キーを作成できます。これは、データベースに ros を追加するたびに 1 つ増加します。

于 2013-05-08T18:04:15.683 に答える