---
url: /docs/recipes/new-table.md
---
# 新增数据表

## 示例模型

以下新增个人项目表的示例尚未存在于模板：

```ts
// db/schema/project.ts
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { generateId } from "./id";
import { user } from "./user";

export const project = pgTable("project", {
  id: text()
    .primaryKey()
    .$defaultFn(() => generateId("prj")),
  userId: text()
    .notNull()
    .references(() => user.id, { onDelete: "cascade" }),
  name: text().notNull(),
  createdAt: timestamp({ withTimezone: true, mode: "date" })
    .defaultNow()
    .notNull(),
});
```

从 `db/schema/index.ts` 导出新表；根据查询补充索引和关系。字段长度等输入约束仍需服务端明确校验。

## 迁移

```sh
bun db:generate
bun db:check
# 审查 SQL，确认目标为隔离开发库后执行
bun db:migrate
```

提交 SQL、快照和元数据。测试数据库应用已提交迁移，漏迁移会直接暴露为缺表问题。

## 接口与页面

在私有接口按当前用户过滤，写入用户 ID 从会话派生，不接收客户端指定身份。然后增加统一查询模块和工作台页面。

新增初始化资料时设置稳定唯一键，不依赖随机 ID 来防重。生产结构改动采用兼容迁移，禁止使用结构推送代替审查。

## 验证

检查删除行为、跨用户隔离、索引和迁移执行，确认导出可以被 API 正确引用。新增表不会自动获得界面、组织权限或套餐限制。
