Ontology Design Patterns

An ontology is a formal description of the kinds of things in a domain and the relationships among them. Ontology design patterns are reusable templates for common modelling situations — taxonomies, parts-of-things, time-stamped facts, n-ary relationships.

Most knowledge-graph projects in 2026 don't use formal ontologies (OWL, RDFS) directly. They use lighter property-graph schemas with informal modelling guidelines. But the patterns from the formal-ontology tradition still inform good schema design.

When formal ontologies are worth it

Specific cases:

Most enterprise knowledge graphs don't fit these cases. They benefit from ontology-style thinking without ontology-style formalism.

Common patterns

Class hierarchy (taxonomy)

The simplest pattern: types organised in an is-a hierarchy.

Vehicle
├── Car
│   ├── Sedan
│   ├── SUV
│   └── Hatchback
├── Truck
└── Motorcycle

In RDFS / OWL, rdfs:subClassOf. In a property graph, multiple labels or a parent_class relationship.

Patterns to follow:

Part-of (mereology)

Modelling parts of things:

Engine -[:PART_OF]-> Car
Wheel -[:PART_OF]-> Car
Cylinder -[:PART_OF]-> Engine

Subtleties:

Membership (taxonomic)

Things belonging to groups, roles, categories:

Alice -[:MEMBER_OF]-> EngineeringTeam
Alice -[:HAS_ROLE]-> Manager
Alice -[:WORKS_FOR]-> Anthropic

Pattern: use distinct relationship types for distinct membership concepts. Don't overload MEMBER_OF to mean both "is in this team" and "has this role."

Time-indexed facts

Most facts are true at a particular time. The CEO of a company changes; the price of a product changes; a relationship is established and ended.

Three approaches:

Reified relationships (common in RDF)

A relationship becomes its own node:

(Dario)-[:HOLDS_POSITION]->(position_1)
position_1 :Position {role:'CEO', company:'Anthropic', from:2021}

Pros: time, source, confidence all attached cleanly. Cons: more nodes; queries are more verbose.

Edge properties (property graphs)

Properties on the edge:

(Dario)-[:CEO_OF {since:2021, until:NULL, source:'web'}]->(Anthropic)

Pros: less verbose; queries simpler. Cons: limited support for time-querying patterns.

Effective-dated rows (relational)

Each fact gets a separate row with valid_from / valid_until. See DatabaseDesign.

For most modern KGs, edge properties suffice. Reified relationships are formally cleaner but heavier.

N-ary relationships

A relationship that involves more than two things:

"In 2021, Anthropic, with Series A funding from Google, founded its San Francisco office."

Two entities (Anthropic, Google), a relation (funded), a year (2021), an event (founding office).

Modelling options:

Reified n-ary relationships are how RDF/OWL handle this; property graphs increasingly adopt the same pattern.

Provenance

Where did this fact come from? Critical for any KG that ingests from multiple sources.

Patterns:

For agentic / RAG use cases, provenance is non-negotiable. Without it, you can't tell "the model said this from training data" from "the KG said this from a verified source."

Identity and equivalence

Same entity in different sources, or the same entity referred to differently:

This is also where the "open-world" vs "closed-world" assumption matters. Open world: absence of a fact doesn't mean it's false. Closed world: everything I haven't said is false. KGs typically operate open-world; SQL databases closed-world. Mismatching produces bugs.

Lightweight alternative patterns

For most teams in 2026 building a KG, the formal-ontology toolkit (OWL, RDF, SPARQL) is overkill. Lighter alternatives:

Schema as documentation

Document your KG's vocabulary in a wiki or schema-as-code (a Markdown file, a YAML schema, dbt docs).

node_types:
  Person:
    description: A natural person
    properties: [name, email, birth_year]
  Company:
    description: A legal entity
    properties: [name, founded_year, headquarters]
edge_types:
  WORKS_AT:
    description: Employment
    source: Person
    target: Company
    properties: [role, start_date, end_date]

Enforced by code at ingestion. No reasoner required; constraints are concrete.

Schema validation

For structured KGs, validate insertions against the schema:

Tools: pydantic for Python; JSON Schema; custom validators. Reject malformed data at insertion.

Light formal vocabulary

If you need some formal-ontology benefits without full RDF/OWL:

This gives interoperability and shared vocabulary without committing to the full semantic-web stack.

Anti-patterns

Pragmatic recommendations

For a new KG project:

  1. Start with a small, concrete schema. Five to ten node types; ten to fifteen edge types. Document each.
  2. Use property graphs (not RDF) unless you have a specific reason. Easier; more tooling.
  3. Adopt time, provenance, and confidence as edge properties. Standardise from day one.
  4. Reuse vocabulary from existing schemas where applicable. Schema.org, Wikidata, domain-specific ontologies.
  5. Validate at ingestion. Schema as code; reject malformed.
  6. Iterate. The schema will evolve; design for additive change.

You'll have an ontology, just an informal one. That's usually enough.

Further reading