Entwerfen eines einfachen Schemas zur Disaggregation der Bedarfsprognose


9

Ich mache eine einfache Datenbankentwurfsaufgabe als Schulungsübung, bei der ich ein grundlegendes Schemadesign für den folgenden Fall erstellen muss:

Ich habe eine Eltern-Kind-Hierarchie von Produkten (Beispiel: Rohmaterial> In Bearbeitung> Endprodukt).

  • Bestellungen werden auf jeder Ebene aufgegeben.
  • Die Anzahl der Bestellungen wird für die nächsten 6 Monate in wöchentlichen Eimern angezeigt.
  • Bedarfsprognosen können für jede Produktebene erstellt werden.
  • Die Nachfrageprognose für jede Woche innerhalb der nächsten 6 Monate kann heute erstellt werden.
  • Die Nachfrageprognose wird für wöchentliche Eimer für die nächsten 6 Monate erstellt.

Die Bedarfsprognose wird normalerweise auf der höheren Hierarchieebene (Rohmaterial- oder Work in Progress-Ebene) erstellt. Sie muss auf eine niedrigere Ebene (Endprodukt) disaggregiert werden.

Es gibt zwei Möglichkeiten, wie die Nachfrageprognose von einer höheren auf eine niedrigere Ebene aufgeschlüsselt werden kann:

  1. Der Benutzer gibt die prozentuale Verteilung für das Endprodukt an. Angenommen, es gibt eine Prognose von 1000 für Work In Progress. Der Benutzer sagt, ich möchte 40% für Endprodukt 1 und 60% für Endprodukt 2 in Eimer 10. Dann für die 10. Woche (Sonntag bis Samstag) ab sofort den Prognosewert für Endprodukt 1 wäre 400 und für Endprodukt 2 wäre 600.
  2. Der Benutzer sagt, dass er nur nach Bestellungen für Endprodukte in Bucket 5 disaggregiert und die Bestellungen in Bucket 5 für Endprodukt 1 und 2 200 bzw. 800 betragen. Der prognostizierte Wert für EP1 wäre dann ((200/1000) * 100)% und für EP2 wäre ((800/1000) * 100)% der Prognose für "Work in Progress".

Die Prognose muss für die nächsten 6 Monate in wöchentlichen Eimern angezeigt werden. Das ideale Format sollte sein:

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

Die Tabelle PRODUCT_HIERARCHY könnte folgendermaßen aussehen:

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

Die Tabelle ORDERS könnte folgendermaßen aussehen:

id | prod_id | order_date | delivery_date | delivered_date

wo,

prod_idist ein Fremdschlüssel, idder auf die Tabelle PRODUCT_HIERARCHY verweist.

Wie speichere ich die Prognose? Was wäre ein gutes Grundschema für eine solche Anforderung?


Meine Idee, Bestellungen für 26 wöchentliche Eimer auszuwählen, ist:

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

Dies gibt jedoch ab heute wöchentliche Eimer, unabhängig vom Tag. Wie kann ich sie in Oracle in Wochen von Sonntag bis Samstag konvertieren?

Bitte helfen Sie beim Entwerfen dieser Datenbankstruktur.

(wird Oracle 11g verwenden)


1
Klingt so, als würden Sie ein Data Warehouse erstellen. Reihenfolge wäre die Faktentabelle. Produkt und Datum der Maßtabellen. Möglicherweise möchten Sie eine akkumulierende Faktentabelle verwenden, da Sie einen Prozess betrachten, der mehrere Schritte umfasst.
Neil McGuigan

Antworten:


1

Okay, hier ist das Datenmodell, das ich mir ausgedacht habe.

PRODUKT - zum Speichern von Produktinformationen und zum Verwalten der Eltern-Kind-Hierarchie

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)                  

BESTELLUNGEN - um Bestellungen für Produkte zu speichern

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"

PROGNOSE - zum Speichern des Prognosewerts für Produkte (Speicherwert für höhere Ebenen, Speicherwert für niedrigere Ebenen nach Disaggregation von einem Elternteil)

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 - um zu speichern, mit welcher Methode ein Wert von einer höheren auf eine niedrigere Ebene disaggregiert wurde und wie viel Prozent auf eine niedrigere Ebene verteilt wurden

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 - Datumsdimension, enthält Informationen zum Startdatum (muss Samstag sein) und zum Enddatum, die der Woche entsprechen, in die ein bestimmtes Datum fällt

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

Was die Bucket-Nummer betrifft. Ich berechne das Wochenstartdatum (in meinem Fall das Datum am Samstag) mit der folgenden Funktion

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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.