--- title: 概要 description: ワークスペースにアプリが追加するデータ ― オブジェクト、フィールド、リレーション ― の形を整えます。 icon: database --- Twenty アプリの**データレイヤー**とは、アプリがワークスペースに*追加*するデータのことです。宣言する新しいレコードタイプ、既存オブジェクトに追加するカラム、およびそれらのレコード同士がどのように接続されるかを指します。 ```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 │ └──────────────────────────────────────────────────┘ ``` ## このセクションについて `defineObject` — 固有のフィールドを持つ新しいレコードタイプを宣言します。 `defineField` — 標準オブジェクトや他のアプリのオブジェクトにフィールドを追加します。 オブジェクト間の双方向 `MANY_TO_ONE` / `ONE_TO_MANY` 接続。 ## エンティティの概要 | エンティティ | 目的 | 定義方法 | | ---------- | ------------------------------------------------------------------------------- | -------------------------------------- | | **オブジェクト** | 固有のフィールドを持つ新しいカスタムレコードタイプ(例: PostCard、Invoice) | `defineObject()` | | **フィールド** | オブジェクト上のカラム。 スタンドアロンフィールドは、作成していないオブジェクトも拡張できます(例: Company に `loyaltyTier` を追加) | `defineField()` | | **リレーション** | 2 つのオブジェクト間の双方向リンク ― 両側がフィールドとして宣言されます | `defineField()` と `FieldType.RELATION` | | **インデックス** | オブジェクトの 1 つに対する定期的なクエリを高速化するためのデータベースインデックス | `defineIndex()` | SDK はビルド時に AST 解析を通じてこれらを検出するため、ファイル構成は自由です ― 慣例としては `src/objects/`、`src/fields/`、`src/indexes/` です。 安定した `universalIdentifier` UUID が、デプロイをまたいであらゆるものを結び付けます。 ## インデックス(任意) アプリは、オブジェクトと一緒にインデックスを同梱しておくことで、繰り返し実行されるクエリを高速に保つことができます。 最も一般的なケースは、頻繁に読み取るステータス列や外部キー列です。 ```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, }, ], }); ``` ### 一意のインデックス `defineIndex` は、単一列と複数列のどちらの一意性でも、`isUnique: true` を受け付けます。 これは推奨されるプリミティブです — `defineField({ isUnique: true })` は非推奨であり、今後のリリースで削除されます。 ```ts defineIndex({ universalIdentifier: '…', objectUniversalIdentifier: PERSON_UNIVERSAL_IDENTIFIER, isUnique: true, fields: [{ universalIdentifier: '…', fieldUniversalIdentifier: EMAIL_FIELD_UNIVERSAL_IDENTIFIER }], }); ``` ### その他の制約 * 部分的な `WHERE` 句は管理者の管理下にあり、アプリ側で宣言することはできません。 * 各オブジェクトにはカスタムインデックスを最大 10 個まで設定できます(フレームワーク自身のインデックスはカウントされません)。 `fields` 配列は、Postgres に使わせたい順序に並べてください ― 電話帳のように、最も左の列が先になります。 インデックスにはコストがかかります。テーブルへの書き込みのたびに更新されます。 必要とするクエリがある場合にのみインデックスを追加してください。 **Application Config** や **Roles & Permissions** をお探しですか? それらは、アプリが追加するデータではなくアプリ自体を記述するものであり、[Config](/l/ja/developers/extend/apps/config/overview) 配下にあります。 **Connections**(Linear、GitHub、Slack OAuth)をお探しですか? それらはロジック関数*から*呼び出されるために存在し、[Logic](/l/ja/developers/extend/apps/logic/connections) 配下にあります。