1

割引を提供するクーポンコードを生成しようとしています。試してみましMath.Random()たが、毎回一意のコードが保証されるかどうかわかりません?.

dbms_random.stringまた、乱数を生成する「Oracle」のユーティリティも試しましたが、一意のコードは保証されません。

これを行うための優れたアルゴリズムを知っている人はいますか?

私はJavaとオラクルを使用してコードを開発しています。

編集:いくつかの応答を見た後、生成されたすべてのコードをテーブルに保存する必要があることを追加したいと思います。生成されたコードは英数字でなければなりません。

4

6 に答える 6

3

Java UUID クラスを使用できます。ランダムな 128 ビットの英数字文字列を生成します。文字列の繰り返しの可能性は天文学的に低いです。

具体的には:

import java.util.UUID
.
.
String uniqueString = UUID.randomUUID().toString()
.
.
于 2013-04-28T05:31:21.650 に答える
1

ランダムはランダムですが、これが一意であるとは限りません。

使用したコードをどこかに (データベースに戻すなど) 保存し、新しいコードを作成するときにレコードをスキャンする必要があります。

現実的には、前もって 100 個 (または 1000 個、または 10,000 個) のクーポンを生成して保存し、必要に応じて割り当てたいと思うかもしれません。

于 2013-04-28T05:07:37.713 に答える
1

乱数とシーケンス番号を組み合わせます。シーケンス番号が一意であるため、一意の乱数が得られます。

それ以外の場合は、試行錯誤のアプローチを行う必要があります。実行時間を節約するために事前に実行することもできます。一意のインデックス Coupon_id を持つテーブル「coupon-keys」があるとします。ランダム キーを生成して挿入します。一意でない場合は挿入の失敗をキャッチし、十分なクーポン キーが生成されるまで再試行します。さらに、「使用済み」列があり、クーポンを発行するたびに列を更新して、まだ利用可能なクーポン番号を追跡します。

于 2013-04-28T08:14:19.533 に答える
1

10g 以降の Oracle には dbms_crypto パッケージが含まれており、完全にランダムなシーケンスを生成できます。

http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_crypto.htm#i1000605 .

いくつかのランダムな RAW バイトを取得したら、utl_encode パッケージを使用して、これらを適切な英数字文字列にエンコードできます。

http://psoug.org/reference/utl_encode.html

クーポン コードが十分に長い場合、競合は発生しませんが、クーポンの作成を PL/SQL 関数でラップして競合を処理することはできます。例えば。UNIQUE 制約を使用し、INSERT が失敗した場合に例外をキャッチします。(ボブ・ジャービスが示唆したように。)

于 2013-04-29T22:59:21.500 に答える
0

ここに私の提案があります:

テーブルは次のようになります

CREATE TABLE COUPONS
  (COUPON_CODE NUMBER
     CONSTRAINT PK_COUPONS
       PRIMARY KEY
       USING INDEX);        -- plus whatever other fields you need

一意のコードを生成するコードは、次のようにする必要があります

DECLARE
  nCoupon_code    NUMBER;
  bCode_unique     BOOLEAN;
BEGIN
  bCode_unique := FALSE;

  WHILE bCode_unique = FALSE LOOP
    BEGIN
      nCoupon_code := GENERATE_COUPON_CODE;  -- function to generate a coupon code

      INSERT INTO COUPONS (COUPON_CODE)
        VALUES (nCoupon_code);

      bCode_unique := TRUE;
    EXCEPTION
      WHEN DUP_VAL_ON_INDEX THEN
        NULL;  -- Fall through, loop back to the top, generate new code, continue
    END;
  END LOOP;  -- bCode_unique
END;

ここで何が起こっているかというと、プログラムは最初に「一意のコード」フラグを FALSE に設定し、一意のコードがまだ生成されていないことを示しています。その後、ループに入り、'code unique' フラグがまだ FALSE である限り継続します。次に、クーポン コードが生成され、データベースに保存されます。コードが一意である場合、すべて問題なく、「一意のコード」フラグが設定され、ループが終了します。ただし、コードが一意でない場合、INSERT ステートメントは DUP_VAL_ON_INDEX 例外で失敗します。これは COUPON_CODE が COUPONS テーブルの主キーであり、主キーには 3 つの属性があることがわかっているためです。(ここでの目的のために、COUPONS.COUPON_CODE に UNIQUE 制約を使用して、同じ効果を得ることもできます)。生成されたクーポン コードが一意ではないために DUP_VAL_ON_INDEX 例外がスローされた場合、コードがまったく何もしない例外ハンドラーに入ります。つまり、'code unique' フラグは FALSE のままで、コードは例外ハンドラーから脱落し、'code unique' フラグがまだ FALSE であるため、別のコードが生成される場所でループが再び開始されます。などなど、一意のコードが最終的に生成され、INSERT が成功するまで。

これは大変な作業のように思えるかもしれませんが、クーポン コード生成アルゴリズムが適切に選択されていれば、多くの衝突は発生しないため、頻繁にループする必要はありません。IMO これは、環境を考慮すると合理的な解決策です。PL/SQL では、データベースを使用して、一意性の保証などの面倒な作業を行うことを期待しています。重複を生成することは決してなく、おそらく重複を生成しない唯一の真のコード生成アルゴリズムを考え出すために膨大な時間を費やすことができます。最終的に選択されたコードが一意になるようにしてください。YMMV。また、One True Algorithm の実装は、特に有効な時間の使い方ではないにしても、非常に楽しいものです。:-)

共有してお楽しみください。

于 2013-04-29T01:06:04.630 に答える