Files
upstream-twenty/packages/twenty-docs/l/zh/developers/extend/apps/data/overview.mdx
upstream-mirror e7da97194a
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
2026-09-17 23:28:13 +05:00

102 lines
5.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 概览
description: 定义你的应用在工作区中添加的数据结构——对象、字段和关系。
icon: database
---
Twenty 应用的 **数据层(data layer)** 是你的应用*添加*到工作区中的数据——它声明的新记录类型、它为现有对象添加的列,以及这些记录之间如何相互关联。
```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 │
└──────────────────────────────────────────────────┘
```
## 本节内容
<CardGroup cols={2}>
<Card title="对象" icon="table" href="/l/zh/developers/extend/apps/data/objects">
`defineObject` —— 声明具有自有字段的新记录类型。
</Card>
<Card title="扩展对象" icon="wand-magic-sparkles" href="/l/zh/developers/extend/apps/data/extending-objects">
`defineField` —— 向标准对象或其他应用的对象添加字段。
</Card>
<Card title="关系" icon="diagram-project" href="/l/zh/developers/extend/apps/data/relations">
对象之间的双向 `MANY_TO_ONE` / `ONE_TO_MANY` 连接。
</Card>
<Card title="时间线活动类型" icon="clock-rotate-left" href="/l/zh/developers/extend/apps/data/timeline-activity-types">
为记录时间线定义自动审计事件和显式应用事件。
</Card>
</CardGroup>
## 实体一览
| 实体 | 目的 | 定义方式 |
| ----------- | ----------------------------------------------------- | ------------------------------------------- |
| **对象** | 具有自有字段的新自定义记录类型(例如 PostCard、Invoice) | `defineObject()` |
| **字段** | 对象上的一列。 独立字段可以扩展你未创建的对象(例如向 Company 添加 `loyaltyTier`) | `defineField()` |
| **关系** | 两个对象之间的双向链接——双方都声明为字段 | 使用 `defineField()` 并指定 `FieldType.RELATION` |
| **索引** | 用于加速在某个对象上经常执行的查询的数据库索引 | `defineIndex()` |
| **时间线活动类型** | 显示在记录时间线中的自动审计事件或显式域事件 | `defineTimelineActivityType()` |
SDK 会在构建时通过 AST 分析检测这些内容,因此文件组织方式由你决定——约定是使用 `src/objects/`、`src/fields/`、`src/indexes/` 和 `src/timeline-activity-types/`。 稳定的 `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 个自定义索引(框架自身的索引不计入其中)。
按照 Postgres 使用索引的方式来排列 `fields` 数组——最左边的列放在最前面,就像电话簿一样。 索引不是免费的:对表的每一次写入都会更新索引。 只有当你确实有查询需要某个索引时才添加它。
<Note>
在找 **Application Config** 或 **Roles & Permissions** 吗? 这些描述的是应用本身而不是它添加的数据——相关内容位于 [Config](/l/zh/developers/extend/apps/config/overview) 下。 在找 **Connections**(Linear、GitHub、Slack OAuth)吗? 这些用于*从*逻辑函数中调用,并位于 [Logic](/l/zh/developers/extend/apps/logic/connections) 下。
</Note>