Chapter 01

认识 Drizzle 与安装

理解 ORM 的价值与局限,搞清 Drizzle 在 Prisma/Kysely/TypeORM 格局中的独特定位,并完成首个连接。

1.1 ORM 是什么

ORM(Object-Relational Mapping,对象关系映射)是一类库,帮你在"面向对象的代码"与"关系型数据库的表"之间搭桥——免手写 SQL、免手拼字符串、免担心 SQL 注入。

查询构建器(Query Builder)
如 Kysely、Knex——提供 db.select().from().where() 式的链式 API,产出 SQL 字符串发给驱动。不会把行映射成对象图。
ActiveRecord
如 Rails AR、TypeORM、Mongoose——每行是一个"模型实例",对象有 .save()/.delete() 方法。抽象高,但"魔法"也多。
Data Mapper
如 Doctrine(PHP)、SQLAlchemy(Python)——查询和持久化由单独的"仓库"处理,模型对象"无知"自己要被存。更可测试,但 API 复杂。
Schema-first ORM
如 Prisma——用 DSL 写 schema、运行代码生成器产出客户端。类型安全好,但需要 build 步骤。

1.2 Drizzle 的定位

Drizzle 是查询构建器 + 轻量 ORM 的混合:

1.3 Drizzle vs Prisma vs Kysely vs TypeORM

维度DrizzlePrismaKyselyTypeORM
Schema 语法TypeScriptDSLTypeScriptDecorator 类
代码生成❌ 不需要✅ generate 步骤可选(introspect)
运行时体积7KB~20MB(含 engine)< 50KB~10MB
Edge 支持✅ 原生有 Edge adapter(较新)
Relational Queries❌(要手写 JOIN)
SQL 表达力高(接近原生)中(遇到难的要 raw)
迁移工具drizzle-kitprisma migratekysely-migratortypeorm migration
学习曲线低(懂 SQL 即可)中(学 DSL)
如何选

• 全新项目 + TypeScript + 可能上 Edge → Drizzle
• 团队不熟 SQL + 追求自动化 → Prisma
• 只要查询构建器、不要 ORM 抽象 → Kysely
• 老项目 + 已用 decorator 风格 → TypeORM

1.4 支持的数据库与 driver

数据库推荐 driver场景
PostgreSQLpostgres(postgres.js)通用首选,性能最佳
PostgreSQLpg(node-postgres)老项目兼容
Neon / Supabase@neondatabase/serverlessServerless Postgres(HTTP)
MySQL / MariaDBmysql2通用
Planetscale@planetscale/databaseServerless MySQL
SQLite(本地)better-sqlite3Node.js 本地
SQLite(Bun)bun:sqliteBun 运行时
Turso / libsql@libsql/client分布式 SQLite
Cloudflare D1D1Database(CF 内置)Workers 环境

1.5 安装

# 核心 + 迁移工具
$ npm i drizzle-orm
$ npm i -D drizzle-kit

# 按数据库选 driver
$ npm i postgres            # Postgres
$ npm i mysql2              # MySQL
$ npm i better-sqlite3      # SQLite (Node)
$ npm i @libsql/client      # Turso
$ npm i @neondatabase/serverless   # Neon

1.6 第一次连接:PostgreSQL + postgres.js

// src/db.ts
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";

const client = postgres(process.env.DATABASE_URL!, {
  max: 10,             // 连接池大小
  idle_timeout: 20,
  connect_timeout: 10,
});

export const db = drizzle(client);
// src/example.ts
import { db } from "./db";
import { sql } from "drizzle-orm";

const [{ now }] = await db.execute<{ now: Date }>(sql`select now()`);
console.log(now);

1.7 MySQL 与 SQLite 版本

// MySQL
import { drizzle } from "drizzle-orm/mysql2";
import mysql from "mysql2/promise";
const conn = await mysql.createPool(process.env.DATABASE_URL!);
export const db = drizzle(conn);
// SQLite(Node)
import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
const sqlite = new Database("./sqlite.db");
export const db = drizzle(sqlite);
// SQLite(Bun 原生)
import { drizzle } from "drizzle-orm/bun-sqlite";
import { Database } from "bun:sqlite";
export const db = drizzle(new Database("./app.db"));

1.8 连接池注意点

ORM 的"性能坑"很多不是查询本身,而是连接管理:

1.9 Hello Drizzle:最小可跑示例

// src/schema.ts
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  name: text("name").notNull(),
  createdAt: timestamp("created_at").defaultNow(),
});

// src/app.ts
import { db } from "./db";
import { users } from "./schema";

await db.insert(users).values({ name: "Alice" });

const rows = await db.select().from(users);
console.log(rows);
// [{ id: 1, name: "Alice", createdAt: 2026-04-20T... }]
注意类型推断

rows 的类型自动推断为 { id: number; name: string; createdAt: Date | null }[]——完全来自 schema.ts,没有任何代码生成步骤。改 schema 后 IDE 立刻知道。

1.10 小结与下一步