本番データベースからDWスタースキーマ設計を構築するための手順/ルールは何ですか。具体的には、多対多の関係をどのように処理しますか。
多対多の関係を含む基本的なデータを取得し、正規化された本番データベースにアクセスする方法を理解しています。
例えば:
テーブルProduct Entity
、Promotion
、Employee
を指定して販売トランザクションを処理する場合、最初のステップはテーブルSaleTransaction
を作成することです。
SaleTransaction
- TransactionID
- ProductID
- EmployeeID
- SellingDateID
- Quantity
- SaleAmount
- PromotionID
Promotion
エンティティは次のようになります。
Promotion
- PromotionID
- ProductID
- DiscountAmount
ただし、販売トランザクションごとに1つの製品と1つのプロモーションしか許可されません。 1つ以上の製品と0個以上のプロモーションを許可したいので、
PromotionID
、ProductID
、Quantity
、および(いくつかのビジネスルールで要求されない限り)SaleAmount
をSaleTransaction
から削除します
SaleTransactionDetail
を作成します。
- DetailID
- TransactionID
- ProductID
- Quantity
- SaleAmount
SaleTransactionPromotion
を作成します:
- TransPromoID
- PromotionID
本番DB設計をDWスタースキーマ設計に移行するための同等の手順は何ですか?
多対多のテーブルは、通常「ブリッジテーブル」で処理されます。これは、トランザクションデータベースで使用するような多対多のテーブルの別の名前です。最初のテーブルへのFKの1つの列、2番目のテーブルへのFKの1つの列、そしておそらく1つまたは2つの列ハウスキーピングフィールド用。
また、ブリッジテーブルのWeight
フィールドに、1を各販売のエントリ数で割った値を設定することもできます。これにより、複数のプロモーションがあった注文の二重カウントを避けたい場合に、SUM(Weight)
ではなくCOUNT(*)
を計算できます。
提案されたスキーマはそのままで良いですが、少し改善できると思います。 2つのことが頭に浮かびます。 1つは、通常、SalesTransactions
とSalesTransactionDetails
を1つのテーブルに折りたたむことです。これにより、顧客IDなどの冗長性が導入され、OLTP本能が軽快になります(正規化されたデータベースからデータウェアハウジングへの移行はパラダイムシフトです!)。ただし、この場合は価値があります。すべての売り上げを1つのテーブルにまとめると、結合が簡素化され、多くのデータベースでは、ビットマップインデックスを使用することを通知します。ウェアハウスでは、テーブルスキャンを実行しなければならないことがよくありますが、ファクトテーブルは非常に狭く、メモリに収まります。
したがって、3つのテーブルSales
、Promotions
、およびSalesPromotions
があります。後者は適用されない可能性がある最終性を意味するため、「販売」ではなく「注文」を検討する場合があります。システムに、発注されたが出荷されていない、またはクローズされていない注文が含まれている場合、より一般的な用語が意味をなします。それは不自然なことですが、名前の付け方について慎重に考えることは決して害にはなりません。
CREATE TABLE Orders
-- IDs/dimensions:
OrderID
EmployeeID
ProductID
-- Date dimensions: date placed, date contract signed, date shipped, etc.
-- Metrics: quantity, gross price, net price, extended price
-- Attributes: is taxable, currency code, business key
CREATE TABLE Promotions
PromotionID
-- Date dimensions: date effective, date expires
-- Metrics: fixed amount, percentage amount
-- Attributes: name, type
CREATE TABLE OrderPromotions
OrderID
PromotionID
Weight
ExtendedPrice
は、値を格納するのではなく、計算列にすることができます。属性がOrders
テーブルを膨らませ始める場合は、「 ジャンクディメンション 」を検討してください。
ProductID
をPromotions
に含めることもできますが、これはプロモーションが1つの製品にのみ適用される場合に限られます。たとえば、特定のラインアイテムではなく注文全体に適用されるいくつかのプロモーションがありますか?本日のプロモーションは商品コードABC1に適用されますが、価格変更後のABC2には明日適用されますか?
2つ目の注意点はIDです。ソースシステムのIDに依存するのではなく、データウェアハウスで合成キー(SK)を使用することを強くお勧めします。理由はいくつかあり、これはDBA.StackExchangeの他の場所で説明されていますが、手に負えません:
Customers.FirstOrderSK
フィールドには、注文したことがない顧客の場合は-1、注文したがまだ特定の情報がまだ入手できない顧客の場合は0が入力されます。レポートは、NULL値を処理する特別なロジックを配置する必要なく、これを反映できます。プロモーションなしの注文の「ダミーレコード」を含めることにより、ブリッジテーブルの合成キーを利用できます。 PromotionID
に-1を入力して、プロモーションが適用されなかったことを示します。これで、データの消費者は、定価で販売された注文をフィルタリングできます。