ORM

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

データベース開発ツール

ORM とは

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

ORM の例

ORM の例を以下に示す。

ORM言語特徴
PrismaTypeScript型安全、スキーマファースト
DrizzleTypeScript軽量、SQL に近い
TypeORMTypeScriptデコレータベース
SQLAlchemyPython最も成熟
GORMGoシンプル

Prisma の使い方

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 と生 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 での選択

Lambda での選択を以下にまとめる。

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

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

この記事は役に立ちましたか?

関連用語

関連する記事