---
title: Übersicht
description: Gestalten Sie die Daten, die Ihre App zu einem Workspace hinzufügt – Objekte, Felder und Beziehungen.
icon: database
---

Die **Datenebene** einer Twenty-App umfasst die Daten, die Ihre App zu einem Workspace *hinzufügt* – die neuen Datensatztypen, die sie deklariert, die Spalten, die sie zu bestehenden Objekten hinzufügt, und wie diese Datensätze miteinander verknüpft sind.

```text
┌──────────────────────────────────────────────────┐
│ Object — a record type, e.g. PostCard            │
│    ├─ Field     (name, type, label)              │
│    ├─ Field                                      │
│    └─ Relation  (link to another object)         │
└──────────────────────────────────────────────────┘
            │
            ├── lives in your app, OR
            │
            ▼
┌──────────────────────────────────────────────────┐
│ Standard / other apps' objects                   │
│    └─ Field added by your app via defineField    │
└──────────────────────────────────────────────────┘
```

## In diesem Abschnitt

<CardGroup cols={2}>
  <Card title="Objekte" icon="table" href="/l/de/developers/extend/apps/data/objects">
    `defineObject` – deklarieren Sie neue Datensatztypen mit eigenen Feldern.
  </Card>
  <Card title="Objekte erweitern" icon="wand-magic-sparkles" href="/l/de/developers/extend/apps/data/extending-objects">
    `defineField` – fügen Sie Standardobjekten oder Objekten anderer Apps Felder hinzu.
  </Card>
  <Card title="Beziehungen" icon="diagram-project" href="/l/de/developers/extend/apps/data/relations">
    Bidirektionale `MANY_TO_ONE`- / `ONE_TO_MANY`-Verbindungen zwischen Objekten.
  </Card>
</CardGroup>

## Entitäten im Überblick

| Entität       | Zweck                                                                                                                                                | Definiert mit                            |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| **Objekt**    | Ein neuer benutzerdefinierter Datensatztyp (z. B. PostCard, Invoice) mit eigenen Feldern                                                             | `defineObject()`                         |
| **Feld**      | Eine Spalte in einem Objekt. Eigenständige Felder können Objekte erweitern, die Sie nicht erstellt haben (z. B. `loyaltyTier` zu Company hinzufügen) | `defineField()`                          |
| **Beziehung** | Eine bidirektionale Verknüpfung zwischen zwei Objekten – beide Seiten werden als Felder deklariert                                                   | `defineField()` mit `FieldType.RELATION` |
| **Indizes**   | Ein Datenbankindex, um eine wiederkehrende Abfrage für eines Ihrer Objekte zu beschleunigen                                                          | `defineIndex()`                          |

Das SDK erkennt diese zur Build-Zeit über eine AST-Analyse, sodass die Dateiorganisation Ihnen überlassen ist – die Konvention ist `src/objects/`, `src/fields/` und `src/indexes/`. Stabile `universalIdentifier`-UUIDs verknüpfen alles über Deploys hinweg.

## Indizes (optional)

Apps können Indizes gemeinsam mit ihren Objekten ausliefern, um wiederkehrende Abfragen schnell zu halten. Der häufigste Fall ist eine Status- oder Fremdschlüsselspalte, die Sie häufig lesen.

```ts src/indexes/post-card-status.index.ts
import { defineIndex } from 'twenty-sdk/define';

import {
  POST_CARD_UNIVERSAL_IDENTIFIER,
  STATUS_FIELD_UNIVERSAL_IDENTIFIER,
} from '../objects/post-card.object';

export default defineIndex({
  universalIdentifier: 'b6e9d2a1-5a4c-46ca-9d52-42c8f02d1ff0',
  objectUniversalIdentifier: POST_CARD_UNIVERSAL_IDENTIFIER,
  fields: [
    {
      universalIdentifier: 'b6e9d2a1-5a4c-46ca-9d52-42c8f02d1ff1',
      fieldUniversalIdentifier: STATUS_FIELD_UNIVERSAL_IDENTIFIER,
    },
  ],
});
```

### Eindeutige Indizes

`defineIndex` akzeptiert `isUnique: true` sowohl für Einspalten- als auch Mehrspalteneindeutigkeit. Dies ist das empfohlene Primitive – `defineField({ isUnique: true })` ist veraltet und wird in einer zukünftigen Version entfernt.

```ts
defineIndex({
  universalIdentifier: '…',
  objectUniversalIdentifier: PERSON_UNIVERSAL_IDENTIFIER,
  isUnique: true,
  fields: [{ universalIdentifier: '…', fieldUniversalIdentifier: EMAIL_FIELD_UNIVERSAL_IDENTIFIER }],
});
```

### Andere Einschränkungen

* Partielle `WHERE`-Klauseln bleiben unter Kontrolle der Administratoren – Apps können sie nicht deklarieren.
* Jedes Objekt ist auf 10 benutzerdefinierte Indizes begrenzt (die Indizes des Frameworks selbst werden nicht mitgezählt).

Ordnen Sie das `fields`-Array so an, wie Postgres es verwenden soll – die ganz linke Spalte zuerst, wie in einem Telefonbuch. Indizes sind nicht kostenlos: Jeder Schreibvorgang in die Tabelle aktualisiert sie. Fügen Sie einen nur dann hinzu, wenn Sie eine Abfrage haben, die ihn benötigt.

<Note>
Suchen Sie nach **Application Config** oder **Roles & Permissions**? Diese beschreiben die App selbst und nicht die Daten, die sie hinzufügt – sie befinden sich unter [Config](/l/de/developers/extend/apps/config/overview). Suchen Sie nach **Connections** (Linear, GitHub, Slack OAuth)? Diese existieren, um *von* Logikfunktionen aufgerufen zu werden, und befinden sich unter [Logic](/l/de/developers/extend/apps/logic/connections).
</Note>
