Zum Inhalt springen

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

FeldTypPflichtHinweise
iduuidjaPK
keytextjaglobal eindeutig, Format ^[a-z][a-z0-9_]*$
nametextja
descriptiontextnein
from_entity_type_iduuidjaFK → DDM_ENTITY_TYPE
to_entity_type_iduuidjaFK → DDM_ENTITY_TYPE
delete_policymdm.delete_policyjadefault restrict
is_activebooleanjadefault true
is_bidirectionalbooleanjadefault false
min_to_per_fromintegerjadefault 0. Mindestanzahl aktiver to-Endpunkte je from-Entität. Service-Layer-Regel (Workflow-/Status-Validierung), kein DB-Constraint
max_to_per_fromintegerneinNULL = unbegrenzt. Maximale Anzahl aktiver to-Endpunkte je from-Entität. Service-Layer-Regel — kein DB-Trigger (siehe OP-13a, revidiert 2026-04-29)
metadatajsonbjadefault '{}'
created_at / updated_at / created_by / updated_byStandardfelder

Wertebereich delete_policy

WertBedeutung
restrictLöschen nicht erlaubt, wenn Abhängigkeiten bestehen (Default)
detachBeziehung wird getrennt, Ziel bleibt erhalten
cascadenur in klar definierten Ausnahmefällen
archive_onlynur 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 >= 0 und falls max_to_per_from gesetzt, max_to_per_from >= 1
  • relation_type_cardinality_min_le_max_chk: min_to_per_from <= max_to_per_from (sofern max_to_per_from gesetzt)

Trigger

  • trg_relation_type_set_updated_at
  • Auf DDM_ENTITY_RELATION: kein Kardinalitäts-Trigger. min_to_per_from und max_to_per_from werden ausschließlich vom Service-Layer geprüft (OP-13a, revidiert 2026-04-29). Endpunkt-Typ bleibt trigger-erzwungen über trg_validate_entity_relation_types.

Verhalten

  • Service-Layer wertet delete_policy beim Löschen einer Quell-/Ziel-Entität aus (siehe Löschen und Archivierung).
  • is_bidirectional=true führt dazu, dass der Service-Layer beim relate-Aufruf zwei DDM_ENTITY_RELATION-Zeilen in derselben Transaktion schreibt (A→B und B→A). Bei unrelate/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üft trg_validate_entity_relation_types, dass die tatsächlichen DDM_ENTITY.entity_type_id-Werte zu from_entity_type_id/to_entity_type_id passen.
  • Inverse-Naming: Bei is_bidirectional=true muss der Service ein konsistentes inverses Endpunkt-Paar verwenden. Wenn from_entity_type_idto_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 inverses key (z. B. company_is_subsidiary_of). Konvention: Self-Relations sind standardmäßig nicht bidirektional; wer beide Richtungen braucht, legt zwei eigene DDM_RELATION_TYPEs mit klaren Keys an.

Kardinalität

  • min_to_per_from und max_to_per_from sind beide Service-Layer-Regeln (OP-13a, revidiert 2026-04-29). Begründung: einheitliche Handhabung; harte Trigger-Durchsetzung von max blockiert legitime Bulk-Imports und Re-Parenting in Migrations-Jobs. Verstöße werden über die Reporting-Views mdm.v_relation_min_violations und mdm.v_relation_max_violations sichtbar gemacht; der Service prüft beim relate-Aufruf und vor Status-Übergängen wie active.
  • Beispiele:
    • case_has_customer: from=case, to=customer, max_to_per_from=1 ⇒ Service lehnt einen zweiten aktiven case_has_customer für denselben Case ab.
    • customer_has_sales_owner: from=customer, to=employee, max_to_per_from=1 und min_to_per_from=1 ⇒ Service lehnt mehr als einen aktiven Vertriebsverantwortlichen ab; das Mindestmaß wird vor Statusübergang active geprü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 per DDM_ENTITY_RELATION an 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.

Verwandte Dokumente