10

現在、次のシナリオをモデル化する必要がある小さなプロジェクトに取り組んでいます。

シナリオ

  1. 顧客から電話があり、彼は新車の見積もりを求めています。
  2. 営業担当者 お客様情報を登録します。
  3. 営業担当者 システムで見積もりを作成し、見積もりにアイテム (車) を追加します。
  4. 営業担当者 電子メールで顧客に見積もりを送信します。
  5. 顧客が見積もりを受け入れると、見積もりは見積もりではなく注文になります。
  6. 営業担当者 注文を確認してください。すべて問題ありません。彼は注文の請求を行います。注文はもはや注文ではなく、請求書です。

考え

これをモデル化するための理想的な方法を見つけるには少し助けが必要ですが、いくつかの考えがあります。

  1. 下書き・見積書・請求書どちらも基本的には注文だと思っています。
  2. 下書き/見積もり/請求書には個別の一意の番号 (ID) が必要なので、それらすべてに個別のテーブルを考えています。

モデル

これは私のデータ モデル v.1.0 です。ご意見をお聞かせください。

データモデル v.1.0 懸念

ただし、このモデルに関していくつかの懸念があります。

  1. 下書き/見積もり/請求書では、注文明細行に異なる品目と価格が含まれる場合があります。このモデルでは、すべての下書き/見積もり/請求書が同じ注文と注文明細行に接続されているため、個別の見積もり明細行/下書き明細行/請求明細書を作成することはできません。たぶん、これのために新しいテーブルを作成しますが、基本的に同じ情報が複数のテーブルに格納されてしまい、それも良くありません。
  2. 2 つ以上の見積もりが請求書になる場合がありますが、このモデルではど​​のように処理されますか?

これをよりよくモデル化する方法についてのヒントがあれば、私に知らせてください!

編集: データモデル v.1.4 ここに画像の説明を入力

4

3 に答える 3

6

「オーダーライン」に似たテーブル「クォートライン」が必要です。同様に、'invoicelines' テーブルが必要です。これらすべてのテーブルには、「割引」フィールドとともに「価格」フィールド (名目上は部品のデフォルト価格) が必要です。「割引」フィールドを「見積もり」、「注文」、および「請求書」テーブルに追加して、現金割引や特別オファーなどを処理することもできます。あなたが何を書いても、見積もりの​​金額と価格は顧客が実際に注文したものと一致しない可能性があり、実際に提供する金額と同じではない可能性があるため、別の表を用意することをお勧めします.

「下書き」テーブルが何であるかはわかりません。「下書き」テーブルと「請求書」テーブルは同じ情報を保持しているため、請求書のステータス (下書きまたは最終) を含む 1 つのフィールドでおそらく組み合わせることができます。収入 (請求書) に応じて税金を支払うことが想定されるため、請求書データを注文データから分離することが重要です。

「Quotes」、「Orders」、および「Invoices」にはすべて、営業担当者の値を保持するフィールド (外部キー) が必要です。このフィールドは、存在しない「SalesRep」テーブルを指します。「customers」テーブルに「salesrep」フィールドを追加することもできます。これは、顧客のデフォルトの担当者を指します。この値は「見積もり」テーブルにコピーされますが、デフォルトとは異なる担当者が見積もりを提供した場合は変更できます。同様に、このフィールドは、注文が見積もりから作成された場合、および請求書が注文から作成された場合にコピーする必要があります。

もっと多くのことを追加できるかもしれませんが、それはシステムをどれだけ複雑かつ詳細にしたいかによって異なります。車がオプションに従って構成され、それに応じて価格が設定されている場合は、何らかの形式の「部品表」を追加する必要がある場合があります。

于 2011-04-17T10:36:17.013 に答える
6

見積書、注文書、下書き、請求書などのすべてのものを、他のすべてのものと構造的に同一のものとしてモデル化したようです。その場合は、同様の属性をすべて 1 つのテーブルに「プッシュ」できます。

create table statement (
    stmt_id integer primary key,
    stmt_type char(1) not null check (stmt_type in ('d', 'q', 'o', 'i')),
    stmt_date date not null default current_date,
    customer_id integer not null  -- references customer (customer_id)
);

create table statement_line_items (
    stmt_id integer not null references statement (stmt_id),
    line_item_number integer not null,
    -- other columns for line items
    primary key (stmt_id, line_item_number)
);

あなたが説明したモデルではうまくいくと思いますが、これらをスーパータイプ/サブタイプとしてモデル化することで、長期的にはより良いサービスが提供されると思います. すべてのサブタイプに共通の列は、スーパータイプに「押し上げ」られます。各サブタイプには、そのサブタイプに固有の属性の個別のテーブルがあります。

この SO の質問とその受け入れられた回答 (およびコメント) は、ブログ コメントのスーパータイプ/サブタイプの設計を示しています。別の質問は、個人と組織に関するものです。人員配置と電話番号に関連するさらに別のもの。

後で 。. .

これは完全ではありませんが、時間がありません。広告申込情報が含まれていないことはわかっています。他の何かを見逃したかもしれません。

-- "Supertype". Comments appear above the column they apply to.
create table statement (
  -- Autoincrement or serial is ok here.
  stmt_id integer primary key,    
  stmt_type char(1) unique check (stmt_type in ('d','q','o','i')),
  -- Guarantees that only the order_st table can reference rows having
  -- stmt_type = 'o', only the invoice_st table can reference rows having
  -- stmt_type = 'i', etc.
  unique (stmt_id, stmt_type),
  stmt_date date not null default current_date,
  cust_id integer not null -- references customers (cust_id)
);

-- order "subtype"
create table order_st (
  stmt_id integer primary key,
  stmt_type char(1) not null default 'o' check (stmt_type = 'o'),
  -- Guarantees that this row references a row having stmt_type = 'o'
  -- in the table "statement".
  unique (stmt_id, stmt_type),
  -- Don't cascade deletes. Don't even allow deletes. Every order given
  -- an order number must be maintained for accountability, if not for
  -- accounting. 
  foreign key (stmt_id, stmt_type) references statement (stmt_id, stmt_type) 
    on delete restrict,
  -- Autoincrement or serial is *not* ok here, because they can have gaps. 
  -- Database must account for each order number.
  order_num integer not null,  
  is_canceled boolean not null 
    default FALSE
);

-- Write triggers, rules, whatever to make this view updatable.
-- You build one view per subtype, joining the supertype and the subtype.
-- Application code uses the updatable views, not the base tables.    
create view orders as 
select t1.stmt_id, t1.stmt_type, t1.stmt_date, t1.cust_id,
       t2.order_num, t2.is_canceled
from statement t1
inner join order_st t2 on (t1.stmt_id = t2.stmt_id);
于 2011-04-17T11:34:59.443 に答える