5

こんにちは、9 桁の一意のアカウント番号を生成する必要があります。ここに私の疑似コードがあります:

function generateAccNo()

    generate an account number between 100,000,000 and 999,999,999

    if the account number already exists in the DB 
        call generateAccNo()    /* recursive call */
    else
        return new accout number
    end if

end function

関数はうまく機能しているようですが、再帰呼び出しが少し心配です。

これによりメモリ リークが発生しますか (Apache での PHP 5)?

これは、この問題に取り組むための受け入れ可能な方法ですか?

ご意見ありがとうございます。

4

10 に答える 10

8

これにより、スタック オーバーフローが発生する可能性が非常に高いことがわかりますよね? 顧客の数が増えるにつれて、許容できるアカウント番号が見つからない可能性が高くなります。

また、連続した口座番号を作成して、毎回 1 ずつ増やすことができないのはなぜですか? このアプローチでは、現在データベースにある最大 ID を読み取り、それをインクリメントするだけで済みます。

率直で申し訳ありませんが、あなたの解決策は問題に取り組むためのひどい方法です. 大量のメモリを使用し (スタックが無限に成長する可能性があるため)、データベースに対して大量の高価な呼び出しを行います。

他のアプローチを実際に検討する必要が
あります。顧客を作成するたびに顧客番号を増やすことを強くお勧めします。実際、データベースを適切に設定した場合 (id 列の自動インクリメントを使用)、id を設定する必要さえありません。新しい顧客を挿入するたびに、ID が設定されます。

于 2008-09-19T01:00:50.350 に答える
3

データセットが大きくなるにつれて、また乱数の生成が正しく実装されていない場合、どちらも問題が発生しやすくなります。2つのアイデアが思い浮かびます。

。GUID

最小限の労力で真に一意のIDが必要な場合は、GUIDを検討してください。コードで作成しない場合でも、DBは挿入時に割り当てられる可能性があります。あまりユーザーフレンドリーではありませんが、一意であることが保証されています。ただし、挿入時にDBによって生成されるシーケンシャルAccountRecordIdと組み合わせると、確実な組み合わせになります。

。複合キー:ランダム+シーケンシャル

すべてのニーズに対応する1つの方法は、表面的には少しぎこちなく感じますが、5桁(またはそれ以上)の連続したdbキーから、さらに5桁のランダム性の複合アカウント番号を作成することです。乱数が重複している場合、シーケンシャルIDはアカウント番号全体の一意性を保証するため、問題にはなりません。

于 2008-09-19T01:48:39.300 に答える
2

ここで再帰呼び出しを使用する必要はありません。条件として存在しないことをテストする関数で単純な while ループを実行します。

function generateAccNo()

    generate an account number between 100,000,000 and 999,999,999

    while ( the account number already exists in the DB ) {
         generate new account number;
    }
    return new account number

end function

ただし、このコードがおもちゃ以外のものである場合、ランダムに生成してテストすることは、一意のアカウント番号を生成するための次善のアプローチです。

于 2008-09-19T01:03:30.030 に答える
1

または、一意のアカウント番号として知られている、生成されたバッファを含む別のテーブルを維持することもできます。このテーブルには、自動インクリメントの整数IDが必要です。アカウント番号が必要な場合は、バッファ内のインデックスが最も低いレコードをプルして、そのテーブルから削除するだけです。定期的に実行されるプロセスを用意して、バッファーを補充し、容量が>>通常の使用法であることを確認します。利点は、エンドユーザーがアカウント番号の作成に費やした時間が基本的に一定になることです。

また、処理のオーバーヘッドまたは再帰または反復のリスク、実際の問題は決定論とデータベースクエリの繰り返しのオーバーヘッドであることに注意する必要があります。私はTheZenkerのランダム+シーケンシャルのソリューションが好きです。不要なオーバーヘッドを追加することなく、一意のIDを生成することが保証されています。

于 2008-09-19T01:27:53.233 に答える
1

大丈夫そうですが、ある種の死ぬ条件が必要だと思います。あきらめる前に、これを何回実行させるつもりですか?

膨大な数の範囲でこれが起こりそうにないことはわかっていますが、何か問題が発生して、以前の呼び出しに戻るだけで、再び自分自身を呼び出すことになる可能性があります。

于 2008-09-19T01:03:00.720 に答える
1

アカウント番号を順番に生成することはセキュリティ上のリスクです。それを行うには、他のアルゴリズムを見つける必要があります。

于 2008-09-19T01:20:41.253 に答える
0

ここで再帰を使用する必要はありません。単純なループは同じくらい高速で、消費するスタック スペースが少なくなります。

于 2008-09-19T01:02:02.937 に答える
0

while ループに入れることができます。

function generateAccNo()

    while (true) {    

      generate an account number between 100,000,000 and 999,999,999

      if the account number already exists in the DB 
          /* do nothing */
      else
          return new accout number
      end if
    }

end function
于 2008-09-19T01:02:14.887 に答える
0

なぜだめですか:

lock_db
do
    account_num <= generate number
while account_num in db

put row with account_num in db

unlock_db
于 2008-09-19T01:04:08.720 に答える
0

データベースにこれを処理させないのはなぜですか? SQL Server では、100000000 で始まる ID 列を持つことができます。または、持っているデータベースで sql を使用することもできます。最大IDプラス1を取得するだけです。

于 2008-09-19T01:05:35.470 に答える