---
title: "Tutorial P2P - Datenmodell"
url: "https://docs.noreja.com/de/article/noreja-smart-data-forge-tutorial-p2p-datenmodell"
language: "de"
last_updated: "2026-09-22T10:42:04.567Z"
---

# Tutorial P2P - Datenmodell

Aufbau der relationalen Datenbankstruktur als Basis für die kausale Prozesskette.

> **TL;DR**  
> **Ziel:** Die ersten fünf Tabellen unseres P2P-Beispiels selbst anlegen und ihre PK-/FK-Beziehungen verstehen.  
> **Voraussetzungen:** Smart Data Forge ist geöffnet, `Target Database` steht auf `SQL Server` und `Mode: Simple` ist aktiv.  
> **Ergebnis:** `bestellanforderung`, `freigabe_a`, `freigabe_b`, `bestellung` und `bestellposition` sind als relationale Grundlage des P2P-Modells vorhanden.

## Warum beginnen wir mit dem Datenmodell?

Ein Purchase-to-Pay-Prozess besteht nicht aus einer einzelnen Tabelle.

Eine Bestellanforderung kann zu einer Bestellung führen. Eine Bestellung kann wiederum mehrere Bestellpositionen enthalten. Freigaben, Lieferanten, Wareneingänge, Rechnungen und Zahlungen sind eigenständige Objekte mit eigenen Schlüsseln und Zeitpunkten.

Die Smart Data Forge bildet diese Beziehungen explizit ab.

Deshalb definieren wir zuerst die **Datenstruktur** und erst anschließend die kausale Prozesskette **Causal Chain**.

In diesem Artikel erstellen wir bewusst nur einen didaktisch reduzierten Ausschnitt. Nach dem manuellen Einstieg wird später `Config 1 – Basis` geladen, die das vollständige Simple-Schema enthält.

![](https://cdn-assets.productfruits.com/71419936-44db-43a6-bf6b-2473572e9cec)

## 1\. SQL Server auswählen

Öffne `01 Define Tables`

Wähle bei `Target Database`: `SQL Server (T-SQL)`

Die Auswahl beeinflusst die später erzeugten DDL- und INSERT-Statements. Beispielsweise werden logische Datentypen für SQL Server unter anderem auf `INT`, `NVARCHAR`, `DECIMAL`, `BIT` und `DATETIME2` abgebildet.

## 2\. Tabelle `bestellanforderung` anlegen

Lege folgende Tabelle an:

| Einstellung | Wert |
| --- | --- |
| Table name | `bestellanforderung` |
| Primary key | `banf_id` |
| PK type | `INT` |
| Primary timestamp | `banf_erstellt_am` |

Die Smart Data Forge behandelt den ersten Timestamp einer Tabelle als **Primary Timestamp**. Er repräsentiert den Event-Zeitpunkt, über den die Tabelle später in die Prozesskette eingebunden wird.

Füge anschließend folgende fachliche Spalten hinzu:

| Spalte | Typ | Verwendung |
| --- | --- | --- |
| `anforderer` | `varchar` | Person, die die Beschaffung anfordert |
| `kostenstelle` | `varchar` | organisatorische Zuordnung |
| `geschaetzter_wert` | `decimal` | erwarteter Beschaffungswert |
| `beschaffungsart` | `varchar` | Art der Beschaffung |

![](https://cdn-assets.productfruits.com/97bb4793-deca-43f5-a8dc-a5325fe64a35)

Diese Struktur entspricht der fachlichen Grundlage des vollständigen P2P-Demosets, ist für den manuellen Einstieg aber bewusst kompakt gehalten. Im vollständigen Modell werden genau diese Attribute bereits für die Bestellanforderung verwendet.

### Warum brauchen wir diese Attribute?

Die Attribute dienen später nicht nur dazu, realistische Daten zu erzeugen.

Sie können auch **Ursachen für bestimmtes Prozessverhalten** darstellen.

Der `anforderer` wird beispielsweise später beim Maverick-Buying-Szenario relevant. Der `geschaetzter_wert` kann für wertabhängige Freigabelogik verwendet werden.

Damit entsteht bereits hier die Verbindung zwischen **fachlichem Attribut** und **späterem Prozessverhalten**.

## 3\. `freigabe_a` und `freigabe_b` anlegen

Als Nächstes legen wir zwei Freigabeobjekte an.

### `freigabe_a`

| Einstellung | Wert |
| --- | --- |
| Table name | `freigabe_a` |
| Primary key | `freigabe_a_id` |
| PK type | `INT` |
| Primary timestamp | `genehmigt_am` |

Zusätzliche Spalte:

| Spalte | Typ | Foreign Key |
| --- | --- | --- |
| `banf_id` | `int` | `bestellanforderung.banf_id` |

### `freigabe_b`

| Einstellung | Wert |
| --- | --- |
| Table name | `freigabe_b` |
| Primary key | `freigabe_b_id` |
| PK type | `INT` |
| Primary timestamp | `genehmigt_am` |

Zusätzliche Spalte:

| Spalte | Typ | Foreign Key |
| --- | --- | --- |
| `banf_id` | `int` | `bestellanforderung.banf_id` |

![](https://cdn-assets.productfruits.com/5fe2e16a-35ed-4d8a-8063-be766add236f)

**Hinweis zur Freigabestruktur**

Im vollständigen P2P-Modell sind `freigabe_a` und `freigabe_b` aufgrund einer technischen Einschränkung des Simulators als separate Tabellen angelegt: Da dieselbe Tabelle in der `Causal Chain` nur einmal platziert werden kann, musste eine fachlich gleiche Freigabe, die sowohl innerhalb eines Branch-Zweigs als auch außerhalb benötigt wurde, technisch dupliziert werden; beide Tabellen referenzieren daher die `bestellanforderung`.

## 4\. Tabelle `bestellung` anlegen

Lege anschließend `bestellung` an.

| Einstellung | Wert |
| --- | --- |
| Table name | `bestellung` |
| Primary key | `bestellung_id` |
| PK type | `INT` |
| Primary timestamp | `bestellung_erstellt_am` |

Füge folgende Spalten hinzu:

| Spalte | Typ | FK / Hinweis |
| --- | --- | --- |
| `banf_id` | `int` | FK → `bestellanforderung.banf_id`, nullable |
| `lieferant_id` | `int` | wird nach Import der Basis-Config vollständig verbunden |
| `bestellwert` | `decimal` | fachlicher Bestellwert |
| `waehrung` | `varchar` | z. B. EUR, USD, CHF |
| `status` | `varchar` | aktueller fachlicher Status |
| `abweichung` | `varchar` | später zur Kennzeichnung synthetischer Auffälligkeiten |
| `produktgruppe` | `varchar` | fachliche Produktgruppe |

Füge zusätzlich über `+ add timestamp` folgende Timestamps hinzu:

`bestellung_freigegeben_am`

`bestellung_geaendert_am`

Der erste Timestamp `bestellung_erstellt_am` bleibt der Primary Timestamp. Zusätzliche Timestamps werden relativ zu diesem primären Zeitpunkt modelliert. Die Engine hält reguläre Timestamp-Abfolgen grundsätzlich kausal konsistent; absichtliche Anomalien wie `Wrong Order` werden erst anschließend als Abweichungsmuster angewendet.

Für diesen manuellen Einstieg muss noch nicht jede Offset- und Null-Wahrscheinlichkeit exakt dem späteren Vollmodell entsprechen. Die vollständige Konfiguration wird anschließend über die Basis-Config geladen.

## 5\. Tabelle `bestellposition` anlegen

Zum Abschluss erstellen wir `bestellposition`.

| Einstellung | Wert |
| --- | --- |
| Table name | `bestellposition` |
| Primary key | `position_id` |
| PK type | `INT` |
| Primary timestamp | `position_angelegt_am` |

Füge folgende Spalten hinzu:

![](https://cdn-assets.productfruits.com/404b6f4f-fb8d-4972-a7bb-346744bbc6b9)

| Spalte | Typ | FK / Hinweis |
| --- | --- | --- |
| `bestellung_id` | `int` | FK → `bestellung.bestellung_id` |
| `material_id` | `int` | wird später mit der Referenztabelle `material` verbunden |
| `menge_bestellt` | `int` | bestellte Menge |
| `positionswert` | `decimal` | Wert der einzelnen Position |
| `status` | `varchar` | Status der Bestellposition |

Das vollständige Demo-Modell verwendet dieselben zentralen Felder und verbindet `bestellposition` über `bestellung_id` mit der Bestellung.

## Das bisherige relationale Modell

Nach diesem Schritt ergibt sich vereinfacht folgende Struktur:

`bestellanforderung`  
↳ `freigabe_a`  
↳ `freigabe_b`  
↳ `bestellung`  
 ↳ `bestellposition`

Wichtig: Diese Darstellung zeigt zunächst **Datenbeziehungen**. Sie sagt noch nicht vollständig aus, in welcher Reihenfolge Objekte erzeugt werden oder welcher Freigabepfad für einen Case gilt.

Diese Prozesslogik definieren wir anschließend unter `Causal Chain`.

## Warum ist `bestellung → bestellposition` eine 1:N-Beziehung?

Eine Bestellung kann mehrere Positionen enthalten.

Im Datenmodell wird das über den FK `bestellposition.bestellung_id` abgebildet.

Die tatsächliche Anzahl der erzeugten Bestellpositionen wird jedoch nicht im FK selbst definiert. Sie wird später in der `Causal Chain` als **Outgoing Cardinality** eingestellt.

Im vorhandenen P2P-Demoset ist diese Beziehung auf **1 bis 3 Positionen pro Bestellung** mit der Verteilung `skew_low` gesetzt.

Dadurch entstehen häufiger Bestellungen mit wenigen Positionen und seltener Bestellungen mit der maximalen Anzahl.

Die Smart Data Forge erzeugt bei einer 1:N-Kardinalität tatsächlich separate Child-Zeilen mit eigenen Primary Keys.

Die konkrete Einstellung nehmen wir im nächsten Artikel vor.

## Typische Fehler / darauf achten

**FK und Causal Chain sind nicht dasselbe.**  
Ein Foreign Key beschreibt, wie Datensätze relational verbunden sind. Erst die `Causal Chain` definiert, wann und in welcher Anzahl diese Objekte pro Case erzeugt werden.

**Primary Timestamp bewusst wählen.**  
Der erste Timestamp einer Tabelle steuert ihre primäre zeitliche Position im Prozess. Zusätzliche Timestamps sollten nicht versehentlich als primäres Event verwendet werden.

**Spaltennamen eindeutig halten.**  
Die Smart Data Forge verhindert doppelte Namen innerhalb derselben Tabelle. PK-, Timestamp- und normale Spaltennamen dürfen sich nicht überschneiden.

**Noch nicht zu viel konfigurieren.**  
Der manuelle Aufbau ist absichtlich reduziert. Im nächsten Schritt lernen wir zuerst die Prozesslogik kennen. Danach wechseln wir über `Config 1 – Basis` auf das vollständige Simple-P2P-Modell.

## Nächster Schritt

![](https://cdn-assets.productfruits.com/f7c1c23f-f852-4aa0-af6d-27c9fab811c8)

Im nächsten Artikel konfigurieren wir unter `Causal Chain`:

-   die beiden Freigabewege,
-   deren Zusammenführung vor der Bestellung,
-   die Beziehung von Bestellung zu Bestellposition,
-   die 1:N-Kardinalität mit 1–3 Positionen,
-   die grundlegenden Zeitabstände.

**Weiter:** [**Purchase-2-Pay Tutorial kausale Kette**](https://docs.noreja.com/de/article/noreja-smart-data-forge-p2p-kausale-kette)
