DDM_RELATION_TYPE
Status: Entwurf · Spec-Kandidat: ja
Zweck
Definiert eine fachliche Beziehung zwischen zwei Entitätstypen, inklusive Lösch-Policy und Richtungsverhalten. Wird sowohl von DDM_ENTITY_RELATION (konkrete Kanten) als auch von Referenz-Attributen (DDM_ENTITY_TYPE_ATTRIBUTE.relation_type_id) genutzt.
Felder
| Feld | Typ | Pflicht | Hinweise |
|---|---|---|---|
id | uuid | ja | PK |
key | text | ja | global eindeutig, Format ^[a-z][a-z0-9_]*$ |
name | text | ja | |
description | text | nein | |
from_entity_type_id | uuid | ja | FK → DDM_ENTITY_TYPE |
to_entity_type_id | uuid | ja | FK → DDM_ENTITY_TYPE |
delete_policy | mdm.delete_policy | ja | default restrict |
is_active | boolean | ja | default true |
is_bidirectional | boolean | ja | default false |
min_to_per_from | integer | ja | default 0. Mindestanzahl aktiver to-Endpunkte je from-Entität. Service-Layer-Regel (Workflow-/Status-Validierung), kein DB-Constraint |
max_to_per_from | integer | nein | NULL = unbegrenzt. Maximale Anzahl aktiver to-Endpunkte je from-Entität. Service-Layer-Regel — kein DB-Trigger (siehe OP-13a, revidiert 2026-04-29) |
metadata | jsonb | ja | default '{}' |
created_at / updated_at / created_by / updated_by | – | – | Standardfelder |
Wertebereich delete_policy
| Wert | Bedeutung |
|---|---|
restrict | Löschen nicht erlaubt, wenn Abhängigkeiten bestehen (Default) |
detach | Beziehung wird getrennt, Ziel bleibt erhalten |
cascade | nur in klar definierten Ausnahmefällen |
archive_only | nur Archivierung zulässig |
Constraints
relation_type_key_format_chk,relation_type_metadata_is_object_chk- Unique:
key relation_type_cardinality_nonneg_chk:min_to_per_from >= 0und fallsmax_to_per_fromgesetzt,max_to_per_from >= 1relation_type_cardinality_min_le_max_chk:min_to_per_from <= max_to_per_from(sofernmax_to_per_fromgesetzt)
Trigger
trg_relation_type_set_updated_at- Auf
DDM_ENTITY_RELATION: kein Kardinalitäts-Trigger.min_to_per_fromundmax_to_per_fromwerden ausschließlich vom Service-Layer geprüft (OP-13a, revidiert 2026-04-29). Endpunkt-Typ bleibt trigger-erzwungen übertrg_validate_entity_relation_types.
Verhalten
- Service-Layer wertet
delete_policybeim Löschen einer Quell-/Ziel-Entität aus (siehe Löschen und Archivierung). is_bidirectional=trueführt dazu, dass der Service-Layer beimrelate-Aufruf zweiDDM_ENTITY_RELATION-Zeilen in derselben Transaktion schreibt (A→B und B→A). Beiunrelate/Soft-Delete werden ebenfalls beide Zeilen verändert. Speicher-Verdoppelung ist gewollt — die Entscheidung ist Lese-Pfad-optimiert (siehe OP-13).- Endpunkt-Validierung: bei
DDM_ENTITY_RELATION-INSERT/UPDATE prüfttrg_validate_entity_relation_types, dass die tatsächlichenDDM_ENTITY.entity_type_id-Werte zufrom_entity_type_id/to_entity_type_idpassen. - Inverse-Naming: Bei
is_bidirectional=truemuss der Service ein konsistentes inverses Endpunkt-Paar verwenden. Wennfrom_entity_type_id≠to_entity_type_id, ist das eindeutig (A→B und B→A); wenn beide gleich sind (Self-Relation, z. B.company_has_subsidiary), muss zusätzlich Asymmetrie über die Beziehungsdaten transportiert werden — die inverse Relation hat ein passendes inverseskey(z. B.company_is_subsidiary_of). Konvention: Self-Relations sind standardmäßig nicht bidirektional; wer beide Richtungen braucht, legt zwei eigeneDDM_RELATION_TYPEs mit klaren Keys an.
Kardinalität
min_to_per_fromundmax_to_per_fromsind beide Service-Layer-Regeln (OP-13a, revidiert 2026-04-29). Begründung: einheitliche Handhabung; harte Trigger-Durchsetzung vonmaxblockiert legitime Bulk-Imports und Re-Parenting in Migrations-Jobs. Verstöße werden über die Reporting-Viewsmdm.v_relation_min_violationsundmdm.v_relation_max_violationssichtbar gemacht; der Service prüft beimrelate-Aufruf und vor Status-Übergängen wieactive.- Beispiele:
case_has_customer:from=case,to=customer,max_to_per_from=1⇒ Service lehnt einen zweiten aktivencase_has_customerfür denselben Case ab.customer_has_sales_owner:from=customer,to=employee,max_to_per_from=1undmin_to_per_from=1⇒ Service lehnt mehr als einen aktiven Vertriebsverantwortlichen ab; das Mindestmaß wird vor Statusübergangactivegeprüft.
- N-äre Beziehungen (3+ Endpunkte, z. B.
employee × project × role) werden nicht im Relations-Modell erweitert — stattdessen wird eine eigene Helper-DDM_ENTITY_TYPE(z. B.assignment) modelliert, die perDDM_ENTITY_RELATIONan alle beteiligten Entitäten hängt. Begründung: bewahrt das Zwei-Endpunkt-Schema, hält Index-/Trigger-Logik einfach, gibt fachliche Eigenschaften der n-ären Beziehung einen sauberen Ort (assignment.attributes).
Offen
- Mehrfache Relationstypen zwischen denselben zwei Typen (z. B. „beauftragt”, „gehört zu”) – Naming-Governance offen.