1

この問題を解決する方法がわかりません:

さまざまなオンライン ベンダー (Amazon、Newegg など) から注文情報をインポートします。各ベンダーには、データベースに反映された注文に関する独自の用語と構造があります。私たちのデータは問題なくデータベースにインポートされますが、私が直面している問題は、スキーマに関係なく、データベースから必要なフィールドを抽出するメソッドを作成することです。

たとえば、次の構造があるとします。

Newegg 構造:

"OrderNumber" integer NOT NULL, -- The Order Number
"InvoiceNumber" integer, -- The invoice number
"OrderDate" timestamp without time zone, -- Create date.

アマゾンの構造:

"amazonOrderId" character varying(25) NOT NULL, -- Amazon's unique, displayable identifier for an order.
"merchant-order-id" integer DEFAULT 0, -- A unique identifier optionally supplied for the order by the Merchant.
"purchase-date" timestamp with time zone, -- The date the order was placed.

これらのアイテムを選択して一時テーブルに配置し、クエリを実行するにはどうすればよいですか?

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

"OrderNumber" character varying(25) NOT NULL,
"TransactionId" integer,
"PurchaseDate" timestamp with time zone

一部のデータベースは注文番号を整数で表し、他のデータベースはさまざまな文字で表すことを理解しています。データ型を文字列値にキャストする予定であることを処理します。

これを理解するのに役立つ、それについて読むための提案を誰かが持っていますか?

正確な答えは必要ありません。正しい方向に微調整するだけです。

データは Java によって消費されるため、特定の Java クラスが役立つ場合は、遠慮なく提案してください。

4

2 に答える 2

4

VIEWまず、この機能を提供するを作成できます。

CREATE VIEW orders AS
SELECT '1'::int            AS source -- or any other tag to identify source
      ,"OrderNumber"::text AS order_nr
      ,"InvoiceNumber"     AS tansaction_id -- no cast .. is int already
      ,"OrderDate" AT TIME ZONE 'UTC' AS purchase_date -- !! see explanation
FROM   tbl_newegg

UNION  ALL  -- not UNION!
SELECT 2
       "amazonOrderId"
      ,"merchant-order-id"
      ,"purchase-date"
FROM   tbl_amazon;

このビューは、他のテーブルと同じようにクエリできます。

SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
  • が一意でない場合はsourceが必要です。order_nr異なるソースで一意の注文番号を保証するには、他にどのような方法がありますか?

  • Atimestamp without time zoneは、グローバル コンテキストではあいまいです。タイムゾーンに関連してのみ有効です。timestampとを混在させる場合、これを機能させるには、 を特定のタイム ゾーンtimestamptzに配置する必要があります。詳細については、この関連する回答をお読みください。timestampAT TIME ZONE

    私はタイムゾーンとして UTC を使用していますが、別のタイムゾーンを提供することをお勧めします。単純なキャスト"OrderDate"::timestamptzでは、現在のタイム ゾーンが想定されます。の結果にAT TIME ZONE適用されます。そのため、別のキャストを追加しませんでした。timestamptimestamptz

  • 可能です、PostgreSQL でキャメルケースの識別子を使用しないことをお勧めします。考えられるさまざまな混乱を回避します。私が提供した小文字の識別子 (不要になった二重引用符なし) に注意してください。

  • varchar(25)の型として使用しないでくださいorder_nrtext文字列でなければならない場合は、任意の長さ修飾子なしで使用してください。すべての注文番号が数字だけで構成されている場合、integerまたはbigintより高速になります。

パフォーマンス

これを高速化する 1 つの方法は、ビューを具体化することです。つまり、結果を (一時) テーブルに書き込みます。

CREATE TEMP TABLE tmp_orders AS
SELECT * FROM orders;

ANALYZE tmp_orders; -- temp tables are not auto-analyzed!

ALTER TABLE tmp_orders
ADD constraint orders_pk PRIMARY KEY (order_nr, source);

インデックスが必要です。私の例では、主キー制約によってインデックスが自動的に提供されます。

テーブルが大きい場合は、一時テーブルを作成する前に、RAM でこれを処理するのに十分な一時バッファーがあることを確認してください。そうしないと、実際に速度が低下します。

SET temp_buffers = 1000MB;

セッション内の一時オブジェクトへの最初の呼び出しである必要があります。セッションのためだけに、グローバルに高く設定しないでください。とにかく、セッションの最後に一時テーブルが自動的に削除されます。

必要な RAM の量を見積もるには、テーブルを一度作成して測定します。

SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));

dba.SE に関するこの関連する質問の下のオブジェクト サイズの詳細。

1 つのセッション内で多数のクエリを処理する必要がある場合にのみ、すべてのオーバーヘッドが発生します。他のユースケースについては、他のソリューションがあります。クエリの時点でソース テーブルがわかっている場合は、代わりにソース テーブルにクエリを送信する方がはるかに高速です。そうでなければ、あなたのユニークさをorder_nrもう一度疑うでしょう。実際、一意であることが保証されている場合は、source導入した列を削除できます。

クエリが 1 つまたは少数の場合は、具体化されたビューではなくビューを使用する方が高速な場合があります。

また、レコードが見つかるまでテーブルを次々とクエリするplpgsql 関数も検討します。オーバーヘッドを考慮すると、いくつかのクエリの方が安いかもしれません。もちろん、必要なすべてのテーブルのインデックス。

textまた、またはに固執する場合は、それを検討してvarcharください。order_nrCOLLATE "C"

于 2012-11-10T00:28:30.700 に答える
0

データとのやり取りの基本を定義する抽象クラスを作成し、アクセスする必要があるデータベース スキーマごとにクラスを派生させる必要があるように思えます。これにより、コア コードが単一のオブジェクト タイプで動作できるようになり、各実装では、そのデータベース スキーマに固有の形式でクエリを指定できます。

何かのようなもの:

public class Order
{
    private String orderNumber;
    private BigDecimal orderTotal;
    ... etc ...
}

public abstract class AbstractOrderInformation
{
  public abstract ArrayList<Order> getOrders();
  ...
}

Newegg クラスの場合:

public class NeweggOrderInformation extends AbstractOrderInformation
{
   public ArrayList<Order> getOrders() {
      ... do the work of getting the newegg order
   }
 ...
}

次に、任意の数のフォーマットを使用でき、情報が必要な場合は、すべての実装を反復処理して、それぞれから注文を取得できます。

于 2012-11-09T23:42:40.830 に答える