ORM

オブジェクト指向のコードとリレーショナル DB のテーブルをマッピングするライブラリ

データベース開発ツール

ORM とは

ORM (Object-Relational Mapping) は、プログラミング言語のオブジェクトとリレーショナル DB のテーブルをマッピングし、SQL を直接書かずにデータベースを操作するライブラリである。

ORM の例

ORM 言語 特徴
Prisma TypeScript 型安全、スキーマファースト
Drizzle TypeScript 軽量、SQL に近い
TypeORM TypeScript デコレータベース
SQLAlchemy Python 最も成熟
GORM Go シンプル

Prisma の使い方

// schema.prisma
model User {
  id    String  @id @default(uuid())
  name  String
  email String  @unique
  orders Order[]
}

model Order {
  id     String @id @default(uuid())
  amount Int
  userId String
  user   User   @relation(fields: [userId], references: [id])
}
// 型安全なクエリ
const user = await prisma.user.findUnique({
  where: { id: '123' },
  include: { orders: true }, // リレーションを含む
});
// user の型: User & { orders: Order[] }

ORM vs 生 SQL vs クエリビルダー

アプローチ 抽象度 型安全
ORM 高い Prisma, TypeORM
クエリビルダー 中程度 Drizzle, Knex
生 SQL 低い pg ライブラリ

ORM の落とし穴

N+1 問題

// ❌ N+1: ユーザーごとに注文を個別取得
const users = await prisma.user.findMany();
for (const user of users) {
  const orders = await prisma.order.findMany({ where: { userId: user.id } });
}

// ✅ include で一括取得
const users = await prisma.user.findMany({ include: { orders: true } });

複雑なクエリ

ORM では表現しにくい複雑なクエリ (ウィンドウ関数、CTE) は生 SQL にフォールバックする。

const result = await prisma.$queryRaw`
  SELECT user_id, SUM(amount) as total
  FROM orders
  GROUP BY user_id
  HAVING SUM(amount) > 10000
`;

DynamoDB と ORM

DynamoDB は RDB ではないため、従来の ORM は使えない。DynamoDB 用のライブラリ (ElectroDB, DynamoDB Toolbox) がある。

Lambda での選択

ケース 推奨
RDS + 複雑なリレーション Prisma
RDS + パフォーマンス重視 Drizzle or 生 SQL
DynamoDB AWS SDK 直接 or ElectroDB

現場での応用を知るには関連書籍も役立つ。

関連用語