设计用于需求预测分解的简单方案


9

我正在做一个简单的数据库设计任务,作为一个培训练习,在这种情况下,我必须针对以下情况提出基本的架构设计:

我具有产品的父子层次结构(例如,“原材料”>“在制品”>“最终产品”)。

  • 在每个级别下订单。
  • 在接下来的6个月内,应在每周的存储桶中查看订单数量。
  • 可以针对每个产品级别进行需求预测。
  • 未来6个月内任何一周的需求预测都可以在今天完成。
  • 未来6个月将对每周的水桶进行需求预测。

需求预测通常在层次结构的较高级别(原始物料或在制品级别)进行,必须将其分解为较低级别(最终产品)。

有两种方法可以将需求预测从较高级别分解为较低级别:

  1. 用户指定最终产品的百分比分布。假设有一个正在进行的工作的1000的预测..用户说我要在存储区10中为最终产品1分配40%,为最终产品2分配60%。然后从现在开始第10周(星期日至星期六),预测值最终产品1的价格为400,最终产品2的价格为600。
  2. 用户说,只需根据针对第5个桶中的最终产品下达的订单进行分解,而第5个桶中第1个产品和第2个产品的订单分别为200和800,则EP1的预测值为((200/1000)* 100)%对于EP2,将是“进行中的工作”预测的((800/1000)* 100)%。

在接下来的6个月中,应可以按周的时段查看预测,理想的格式应为:

product name | bucket number | week start date | week end date | forecast value | created_on

PRODUCT_HIERARCHY表可能如下所示:

id  |   name                |   parent_id
__________________________________________
1   |   raw material        |   (null)
2   |   work in progress    |   1
3   |   end product 1       |   2
4   |   end product 2       |   2

ORDERS可能如下所示:

id | prod_id | order_date | delivery_date | delivered_date

哪里,

prod_id是引用idPRODUCT_HIERARCHY表的外键,

如何存储预测? 对于这样的要求,什么是好的基础架构?


我选择每周26个桶的订单的想法是:

SELECT
    COUNT(*) TOTAL_ORDERS,
    WIDTH_BUCKET(
        delivery_date,
        SYSDATE,
        ADD_MONTHS(sysdate, 6), 
        TO_NUMBER( TO_CHAR(SYSDATE,'DD-MON-YYYY') - TO_CHAR(ADD_MONTHS(sysdate, 6),'DD-MON-YYYY') ) / 7
    ) BUCKET_NO
FROM
    orders_table
WHERE
    delivery_date BETWEEN SYSDATE AND ADD_MONTHS(sysdate, 6);

但这将使从今天开始的每周时段,与一天无关。如何在Oracle中将它们转换为星期日至星期六?

请帮助设计此数据库结构。

(将使用Oracle 11g)


1
听起来就像您正在建立数据仓库。顺序将是事实表。产品和标注表的日期。在查看包含多个步骤的流程时,您可能需要使用累积事实表。
尼尔·麦圭根

Answers:


1

好的,这是我想出的数据模型。

PRODUCT-存储产品信息并维护父子层次结构

id  NUMBER  "Primary Key Not Null"                  
level_code  VARCHAR2    Not Null                    
name    VARCHAR2    Not Null                    
description VARCHAR2                        
parent_id   NUMBER  Foreign Key references PRODUCT(id)                  

订单-存储产品订单

id  NUMBER  "Primary Key Not Null"                  
prod_id     NUMBER  "Foreign Key references PRODUCT(id) Not Null"                   
order_type  VARCHAR2    "Not Null Default 'Default'"
order_qty   NUMBER  Not Null
order_date  NUMBER  Foreign Key references DATE_INFO(date_key)
delivery_date   NUMBER  "Foreign Key references DATE_INFO(date_key)
Check delivery_date >= order_date"

预测-存储产品的预测值(从父级分解后的较高级别的存储值,较低级别的存储值)

id  NUMBER  "Primary Key Not Null"
product_id  NUMBER  "Foreign Key references PRODUCT(id) Not Null"
forecast_value  NUMBER  Not Null
week    NUMBER  "Foreign Key references DATE_INFO(date_key) Not Null"                   

DISAGGREGATION_RULES-存储使用哪种方法将值从较高级别分解到较低级别以及将多少百分比分配给较低级别

id  NUMBER  "Primary Key Not Null"
parent_product_id   NUMBER  "Foreign Key id references PRODUCT(id) Not Null"
child_product_id    NUMBER  "Foreign Key id references PRODUCT(id) Not Null"
method  VARCHAR2    Not Null                    
from_week   NUMBER  "Foreign Key references DATE_INFO(date_key) Not Null"
to_week NUMBER  "Foreign Key references DATE_INFO(date_key) Not Null Check end_week >= start_week"
percent_distribution    NUMBER  Not Null                    

DATE_INFO-日期维度,具有有关开始日期(必须是星期六)和结束日期的信息,该日期对应于特定日期所在的星期

date_key    NUMBER  "Primary Key
Not Null"                   
full_date   DATE    Not Null                    
week_begin_date DATE    Not Null                    
week_end_date   DATE    Not Null

至于存储桶编号..我正在使用以下功能计算周开始日期(就我而言,是星期六)

CREATE OR REPLACE FUNCTION get_week_start_date(v_bucket_num IN NUMBER)
  RETURN DATE
IS
  week_start_date DATE;
BEGIN
  SELECT (TRUNC(SYSDATE+2, 'IW')-2) + ((v_bucket_num-1) * 7)
  INTO week_start_date FROM dual;
  RETURN week_start_date;
END;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.