sql - 数据建模草稿/报价/订单/发票

标签 sql database-design data-modeling invoice

我目前正在做一个小项目,我需要对以下场景进行建模:

场景

  • 客户打来电话,他想要一辆新车的报价。
  • 销售代表。注册客户信息。
  • 销售代表。在系统中创建报价,并将项目添加到报价(汽车)。
  • 销售代表。通过电子邮件将报价发送给客户。
  • 客户接受报价,报价现在不再是报价而是订单。
  • 销售代表。检查订单,一切正常,他为订单开具发票。订单现在不再是订单,而是发票。

  • 感想

    我需要一些帮助来找出理想的建模方法,但我有一些想法。
  • 我认为草稿/报价/发票基本上都是订单。
  • 草稿/报价/发票需要单独的唯一编号(ID),所以我正在考虑为所有这些单独的表格。

  • 型号

    这是我的数据模型 v.1.0,请告诉我你的想法。

    Data model v.1.0
    关注

    然而,我对这个模型有一些担忧:
  • 订单行上的草稿/报价/发票可能有不同的项目和价格。在此模型中,所有草稿/报价/发票都连接到同一订单和订单行,因此不可能有单独的报价行/草稿行/发票行。也许我会为此创建新表,但是基本上相同的信息将存储在多个表中,这也不好。
  • 有时两个或多个报价会变成发票,这个模型将如何处理这个问题?

  • 如果您对如何更好地建模有任何提示,请告诉我!

    编辑:数据模型 v.1.4
    enter image description here

    最佳答案

    看起来您已经对这些事物中的每一个进行了建模——报价、订单、草稿、发票——在结构上与所有其他事物相同。如果是这种情况,那么您可以将所有类似的属性“推送”到一个表中。

    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)
    );
    

    我认为这适用于您所描述的模型,但我认为从长远来看,通过将它们建模为父类(super class)型/子类型,您会得到更好的服务。所有子类型共有的列被“向上”插入父类(super class)型;每个子类型都有一个单独的表,用于显示该子类型独有的属性。

    This SO question及其接受的答案(和评论)说明了博客评论的父类(super class)型/子类型设计。 Another question与个人和组织有关。 Yet another有关人员配备和电话号码。

    之后 。 . .

    这不完整,但我没时间了。我知道它不包括订单项。可能漏掉了别的东西。
    -- "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);
    

    关于sql - 数据建模草稿/报价/订单/发票,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5692924/

    相关文章:

    database - 我应该如何设计表以将标签存储在数据库中?

    java - Hibernate:如何建模继承类型结构并在没有显式转换的情况下执行操作

    mysql - SQL SELECT 查询列中的多个值和范围

    SQL:更新 GROUP BY 以包含基于另一列最大值的值

    mysql - 按一个字段分组并统计匹配字段

    mysql - SQL:选择在另一个表中不具有值的 ID/值组合

    mysql - 使用mysql进行库存管理的思路

    php - 为每个事件构建标签列表

    database - 关系识别的通俗说法

    python - 需要帮助创建适当的模型来预测两个句子之间的语义相似性