# Drizzleのrelations機能の基本

> Drizzle ORMのrelations機能を理解し、外部キー制約との違いやクエリAPIの使用方法を学びましょう。このガイドでは、SQLライクなAPIとRelational APIの特徴を比較し、データ取得を簡素化する方法を解説します。

- 公開日: 2025-09-26
- 著者: Tsukamura
- タグ: SQL
- URL: https://tech.anycloud.co.jp/articles/drizzle-study

---

# Drizzle ORM

最近Drizzle ORMを初めて使ったので、その時に簡単に公式ドキュメントをみて覚えておこーっとおもって書いている記事です

[Drizzle ORM - Get started](https://orm.drizzle.team/docs/get-started)

## 主な特徴

### SQL-likeとRelational、両方のAPIを提供

Drizzleは開発者のニーズに応じて2つの異なるアプローチでデータアクセスができる

**SQL-like API**

```typescript
// SQLに慣れている人にとって直感的
await db
  .select()
  .from(users)
  .leftJoin(posts, eq(posts.userId, users.id))
  .where(eq(users.active, true))

```

**Relational API**

```typescript
// ネストしたデータを簡単に取得
const result = await db.query.users.findMany({
  with: {
    posts: true,
    profile: true
  }
});

```

Relational APIでも常に1つのSQLクエリを生成するため、N+1問題を回避し高いパフォーマンスを維持するみたい。

### 学習コストがかなり低そう

SQLを知っていれば、Drizzleを知っているって言えるみたいで以下のようにほぼ同じじゃんってなる

```sql
-- 従来のSQL
SELECT * FROM users WHERE active = true ORDER BY name

```

```typescript
// Drizzleでもほぼ同じ構造
db.select().from(users).where(eq(users.active, true)).orderBy(users.name)
```

## Relationsとは

Drizzle ORMのrelations機能は、外部キー制約を追加するのとはちがうぽい

この辺実際にテーブルつくって試したかたちなので間違えてたら指摘してください🙏

外部キー制約（Foreign Keys）

-   データベースレベルの制約
-   データ整合性を保証
-   制約違反時にエラー

Relations

-   アプリケーションレベルの抽象化
-   クエリAPIを使用可能にする
-   構造的なデータ取得を実現する

重要ポイント クエリAPIを使いたい場合、Relations定義が必要で外部キー制約とは独立してる

```typescript
// ❌ relationsなし → クエリAPIは使用不可
const result = await db.query.users.findMany({
  with: { posts: true } // Error
});

// ✅ relations定義あり → クエリAPI使用可能
export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}));

```

### 選択肢の比較

選択肢1: SQL likeなやつ

```typescript
const result = await db.select()
  .from(users)
  .leftJoin(posts, eq(posts.authorId, users.id));

// 結果：平坦で重複あり
[
  { userId: 1, userName: "田中", postId: 1, postTitle: "投稿1" },
  { userId: 1, userName: "田中", postId: 2, postTitle: "投稿2" },
]
```

選択肢2: Relations使用（relations定義が必要）

```typescript
const result = await db.query.users.findMany({
  with: { posts: true }
});

// 結果：ネスト構造で重複なし
[
  {
    id: 1,
    name: "田中",
    posts: [
      { id: 1, title: "投稿1" },
      { id: 2, title: "投稿2" }
    ]
  }
]
```

### Relations定義例

```typescript

// テーブル定義
export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name'),
});

export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  content: text('content'),
  authorId: integer('author_id'), // 外部キー制約は任意
});

// Relations定義（クエリAPIを使いたい場合）
export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}));

export const postsRelations = relations(posts, ({ one }) => ({
  author: one(users, {
    fields: [posts.authorId],
    references: [users.id],
  }),
}));
```

### 簡単なまとめ

-   Relations = クエリAPIを使用可能にする設定
-   外部キー制約は任意、Relationsはクエリapi使用時に必要
-   従来のJOINかRelationsか、用途に応じて選択可能

Relationsと外部キーの違いをちゃんと理解してないとこまりそうなので、この記事が参考になれば幸いです!
