1

yyyyMMddxxxxxxの形式で注文番号を生成する必要があります。xxxxxxは深夜以降の注文数です。

たとえば、20120821000004は2012年8月21日の4番目の注文です。1秒あたり最大5つの注文を作成できるため、これはパフォーマンスの考慮事項です。

明らかな解決策は、次のようなことを実行して、インクリメントする最新の順序を見つけることです。

SELECT MAX (id) FROM table_name WHERE id LIKE '2012-08-21%'

しかし、それはパフォーマンスの問題にぶつかる可能性があります。

私が調査した他のオプションは、数値コンポーネントを駆動し、挿入トリガーを使用するために使用されるシーケンスを作成することです。このアプローチの問題は、1日の開始時にシーケンスをゼロにロールオーバーする安全な方法が必要なことです。これにより、シーケンスが真夜中にリセットされない場合、衝突/競合状態が発生する可能性があります。

ここでOracleを使用して気密性を高めるだけでなく、パフォーマンスを向上させるためのトリックはありますか?

4

5 に答える 5

1

新しい日ごとに新しいシーケンスを生成できます。'order_seq_20120821'のような意味のある名前を付けます。

  • 今日のシーケンスが存在するかどうかを確認します
  • 作成しない場合(ここで同時実行を処理します。別のスレッドが作成した可能性があります)
  • その後、それを使用します

ここでは実際にはJavaの質問ではなく、クライアントはデータベースの同時実行性を処理できません

于 2012-08-21T01:18:55.147 に答える
1

外部ユーティリティを使用せずにSQLでこれを行う場合は、次の2つのテーブルを保持する可能性があります。

  • 絶対注文ID
  • 日付/注文オフセット

最初のテーブルは、単調に増加する一意のID値を生成するために使用されます。2番目のテーブルは、最初のテーブルから毎日のIDまでの毎日のオフセットを追跡するために使用されます。行はその日の最初の注文に挿入され、日付と最初のテーブルの最上位のIDになります。次に、最初のテーブルからプルされた新しいIDから2番目のテーブルのIDオフセットを差し引くことにより、注文IDを計算できます。

整数の絶対注文IDを使用して、DB内の注文を内部的に追跡し、日付/オフセットデータを使用して、日付と毎日の注文番号の人にわかりやすい情報をその場で、または相互参照として生成することを検討できます。

于 2012-08-21T01:34:08.203 に答える
0

これは特にOracleソリューションではありませんが、日付、xxxxxx(intとして)、および注文番号の3つの列を持つ注文番号テーブルを作成することを考えています。

インデックスを(日付、xxxxxxx)に保持します。次に、次のようにクエリを実行します。

select max(id) from OrderNumbers where date = <date>

これはインデックスを使用し、操作を高速化するはずです。

もう1つのアイデアは、同様のテーブルを保持することですが、現在の日付のみです。このバージョンでは、シーケンス/自動インクリメント列がxxxxxxを自動生成します。次に、トリガーを使用して注文番号を計算し、最後に挿入された値をフェッチして新しい注文番号を作成できます。これは、特にデータのロックの問題を検討する場合に、最速の方法である可能性があります。

于 2012-08-21T01:01:46.493 に答える
0

次の注文IDで始まるシーケンスを作成できます

CREATE SEQUENCE orders_seq
 START WITH     201208210000001
 INCREMENT BY   1
 NOCACHE
 ;

そして、ジョブによって深夜から翌日の最初のIDまでシーケンスをインクリメントします。

 declare
  v_curr_id NUMBER;
  v_inc     NUMBER;
  v_next_val NUMBER;
 begin 
  select orders_seq.nextval into v_curr_id from dual;
  v_next_val := to_number(to_char(SYSDATE+1, 'yyyymmdd') || '000000');
  v_inc := v_next_val - v_curr_id;
  execute immediate ' alter sequence orders_seq increment by ' || v_inc ;
  select orders_seq.nextval into v_curr_id from dual;
  execute immediate ' alter sequence orders_seq increment by 1';
 end;
 /
于 2012-08-21T05:47:11.033 に答える
0

曜日ごとにOracleシーケンスを作成します。

CREATE SEQUENCE SEQ_MON
START WITH 1
INCREMENT BY 1
ORDER;

CREATE SEQUENCE SEQ_TUE
START WITH 1
INCREMENT BY 1
ORDER;

SEQ_SUNまでのETC

以下を返すOracleストアドプロシージャを作成します
。1。日時
2.上記の日時に対応する曜日のシーケンス番号

以下のロジック:
-現在の日付と時刻を変数に格納します
-日付に対応する曜日を変数に取得します。
注:NLS_TERRITORY設定に依存しない式を使用してください。1 + TRUNC(DT)-TRUNC(DT、'IW')を使用して、月曜日に1を取得できます。
-上記の曜日に対応するシーケンスから次のシーケンスを取得します
-変数の日時と上記で取得した新しいシーケンス番号を返します。

ジョブのスケジュール:
毎日午前1時(深夜ではない)に実行されるスケジュールされたジョブを作成して、前日のシーケンスをリセットします。

上記のアプローチでは、24時間年中無休で安全に操作できます。

重要:
要求のタイムスタンプが割り当てられたシーケンス番号と一致するように、返された日時を使用して着信要求にタイムスタンプを付ける必要があります。これは、深夜直前にヒットするリクエストにとって重要です。

于 2013-04-29T15:32:11.327 に答える