TypeORM 支持哪些数据库?如何选择和配置?
TypeORM 能连的数据库不少,但“支持”不等于“随便换个 type 就能无痛迁移”。MySQL、PostgreSQL、SQLite 这类关系型数据库是它最常见的使用场景;MongoDB 虽然也在支持列表里,但功能边界和 SQL 数据库明显不同。选型时要同时看驱动成熟度、团队经验、迁移能力、事务需求和生产环境的运维成本。
TypeORM 官方支持的数据库有哪些
常见项目里会遇到的数据库大致可以分成三类。
| 数据库 | TypeORM type 值 | 常用驱动 | 适合场景 |
|---|---|---|---|
| MySQL | mysql | mysql2 | Web 应用、传统业务系统、读写规模中等的服务 |
| MariaDB | mariadb | mysql2 | MySQL 兼容生态、开源替代 MySQL 的场景 |
| PostgreSQL | postgres | pg | 复杂查询、JSONB、地理信息、事务要求高的系统 |
| SQLite | sqlite | sqlite3 | 本地开发、桌面应用、小型工具、测试环境 |
| better-sqlite3 | better-sqlite3 | better-sqlite3 | 需要同步 API、性能更好的本地 SQLite 场景 |
| sql.js | sqljs | sql.js | 浏览器、纯 JS 运行环境、无需本地数据库进程的场景 |
| Microsoft SQL Server | mssql | mssql | Windows / .NET 技术栈、企业内部系统 |
| Oracle | oracle | oracledb | 大型企业、金融、电信等已有 Oracle 基础设施的系统 |
| CockroachDB | cockroachdb | pg | 分布式 SQL、高可用、多地域部署 |
| SAP HANA | sap | @sap/hana-client 或 hdb-pool | SAP 生态、企业数据平台 |
| Google Spanner | spanner | @google-cloud/spanner | Google Cloud 上的全球分布式关系型数据库 |
| MongoDB | mongodb | mongodb | 文档模型、非关系型数据,但 TypeORM 支持有限 |
原文里提到的 MySQL / MariaDB、PostgreSQL、SQLite、Microsoft SQL Server、Oracle、MongoDB、CockroachDB 都是 TypeORM 里比较重要的数据库类型。补充的 better-sqlite3、sqljs、sap、spanner 也经常出现在官方支持列表或实际项目配置里。
使用前先安装对应数据库驱动
TypeORM 本身不内置所有数据库驱动。你配置了 type: 'postgres',还需要安装 pg;配置了 type: 'mysql',通常还要安装 mysql2。这一步漏掉时,项目启动会直接报找不到依赖。
常见安装命令如下:
bash# MySQL / MariaDB npm install typeorm mysql2 # PostgreSQL / CockroachDB npm install typeorm pg # SQLite npm install typeorm sqlite3 # better-sqlite3 npm install typeorm better-sqlite3 # sql.js npm install typeorm sql.js # Microsoft SQL Server npm install typeorm mssql # Oracle npm install typeorm oracledb # SAP HANA npm install typeorm @sap/hana-client # Google Spanner npm install typeorm @google-cloud/spanner # MongoDB npm install typeorm mongodb
如果项目使用 pnpm 或 yarn,把 npm install 换成对应命令即可。生产环境还要注意驱动的原生依赖,例如 Oracle 的 oracledb 往往需要额外的客户端库,部署容器时不能只复制 Node.js 代码。
常见数据库配置示例
MySQL / MariaDB
MySQL 和 MariaDB 的配置很接近,差别主要在 type。如果用 MariaDB,建议明确写成 mariadb,不要因为兼容 MySQL 协议就偷懒写 mysql。
typescriptimport { DataSource } from 'typeorm'; export const AppDataSource = new DataSource({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'password', database: 'test', entities: ['src/entities/**/*.ts'], migrations: ['src/migrations/**/*.ts'], synchronize: false, });
MariaDB 示例:
typescriptnew DataSource({ type: 'mariadb', host: 'localhost', port: 3306, username: 'root', password: 'password', database: 'test', synchronize: false, });
PostgreSQL
PostgreSQL 是 TypeORM 项目里很常见的选择,尤其适合需要 JSONB、复杂索引、事务和更强 SQL 能力的后端服务。
typescriptnew DataSource({ type: 'postgres', host: 'localhost', port: 5432, username: 'postgres', password: 'password', database: 'test', schema: 'public', entities: ['src/entities/**/*.ts'], migrations: ['src/migrations/**/*.ts'], synchronize: false, });
PostgreSQL 的一个优势是类型能力更强,比如 jsonb、数组、枚举、部分索引等。但这些能力也会带来迁移成本:如果以后切到 MySQL,并不是改个连接配置就结束。
SQLite / better-sqlite3 / sql.js
SQLite 适合本地、小工具、桌面端或测试环境。它不需要单独启动数据库服务,配置也最简单。
typescriptnew DataSource({ type: 'sqlite', database: './database.sqlite', entities: ['src/entities/**/*.ts'], synchronize: false, });
如果希望使用 better-sqlite3:
typescriptnew DataSource({ type: 'better-sqlite3', database: './database.sqlite', entities: ['src/entities/**/*.ts'], synchronize: false, });
浏览器或纯 JS 环境可以考虑 sqljs:
typescriptnew DataSource({ type: 'sqljs', entities: ['src/entities/**/*.ts'], synchronize: false, });
SQLite 系列不要被“轻量”两个字误导。它很适合嵌入式和本地单机,但并不适合高并发写入的服务端核心库。多人同时写、长事务、复杂权限隔离这些场景,还是优先考虑 PostgreSQL 或 MySQL。
Microsoft SQL Server
SQL Server 常出现在 Windows Server、Azure、企业内部系统里。
typescriptnew DataSource({ type: 'mssql', host: 'localhost', port: 1433, username: 'sa', password: 'yourStrong(!)Password', database: 'test', options: { encrypt: true, trustServerCertificate: true, }, entities: ['src/entities/**/*.ts'], synchronize: false, });
这里的 options 经常影响连接结果。开发环境可能需要 trustServerCertificate: true,生产环境则要认真配置证书,不建议长期用“信任所有证书”的方式糊过去。
Oracle
Oracle 在大型企业里很常见,但 Node.js 部署比 MySQL、PostgreSQL 麻烦一些,尤其是客户端依赖和连接池配置。
typescriptnew DataSource({ type: 'oracle', host: 'localhost', port: 1521, username: 'system', password: 'password', sid: 'xe', entities: ['src/entities/**/*.ts'], synchronize: false, });
Oracle 字段类型、序列、大小写标识符、分页 SQL 和日期处理都和 MySQL / PostgreSQL 有差异。已有 Oracle 基础设施时可以用;新项目如果没有强约束,不建议为了“企业级”三个字盲选。
CockroachDB
CockroachDB 走 PostgreSQL 协议,TypeORM 配置上和 PostgreSQL 很像,但 type 要写成 cockroachdb。
typescriptnew DataSource({ type: 'cockroachdb', host: 'localhost', port: 26257, username: 'root', password: '', database: 'defaultdb', ssl: false, entities: ['src/entities/**/*.ts'], synchronize: false, });
它适合分布式 SQL 和高可用需求,但要接受一个现实:分布式事务、唯一索引、时间戳、重试策略都会比单机 PostgreSQL 更复杂。业务代码里要考虑事务重试,不能只按传统单库思路写。
SAP HANA
SAP HANA 通常不是普通互联网项目的首选,但在 SAP 生态和企业数据平台里会遇到。
typescriptnew DataSource({ type: 'sap', host: 'localhost', port: 30015, username: 'SYSTEM', password: 'password', database: 'test', entities: ['src/entities/**/*.ts'], synchronize: false, });
这类数据库的关键不在 TypeORM 配置,而在企业环境里的账号权限、网络策略、驱动安装和 DBA 协作。上线前最好让运维或 DBA 一起确认连接池、超时、字符集和权限边界。
Google Spanner
Spanner 面向 Google Cloud 的全球分布式数据库场景,和传统单机关系型数据库的使用习惯差异比较大。
typescriptnew DataSource({ type: 'spanner', projectId: 'my-gcp-project', instanceId: 'my-instance', databaseId: 'my-database', entities: ['src/entities/**/*.ts'], synchronize: false, });
如果项目没有明确的全球分布式、一致性和云厂商绑定需求,Spanner 通常不是默认选择。它的价值在架构层面,不是 ORM 层面。
MongoDB
TypeORM 也支持 MongoDB,但要单独看待。MongoDB 不是 SQL 数据库,很多 TypeORM 在关系型数据库里的能力不能直接套用。
typescriptnew DataSource({ type: 'mongodb', host: 'localhost', port: 27017, database: 'test', entities: ['src/entities/**/*.ts'], synchronize: false, });
MongoDB 实体通常使用 ObjectIdColumn:
typescriptimport { Entity, ObjectIdColumn, ObjectId, Column } from 'typeorm'; @Entity() export class User { @ObjectIdColumn() id: ObjectId; @Column() name: string; }
需要特别注意:TypeORM 对 MongoDB 的支持并不等同于 Mongoose 那种围绕文档数据库设计的完整体验。关系映射、迁移、QueryBuilder、事务习惯、复杂聚合这些地方都会受限。如果业务核心就是 MongoDB 文档模型,很多团队会直接选择 MongoDB 原生驱动或 Mongoose,而不是用 TypeORM 硬包一层。
SQL 数据库和 MongoDB 的差异别忽略
TypeORM 的主场仍然是关系型数据库。SQL 数据库里,Entity 通常对应表,Column 对应列,Relation 对应外键或中间表;迁移系统也主要围绕表结构变更工作。
MongoDB 的模型完全不同。它存的是文档,天然支持嵌套对象,很多时候不需要外键和 Join。你当然可以在 TypeORM 里写 MongoDB Entity,但不要期待 @ManyToOne、leftJoinAndSelect、SQL 风格迁移这些能力都能照常使用。
简单判断:
- 需要事务、关系、报表查询、强一致结构:优先 SQL 数据库。
- 数据结构经常变化、文档嵌套明显、关系较弱:可以考虑 MongoDB。
- 已经决定用 MongoDB,并且会大量用聚合管道和文档特性:优先评估原生驱动或 Mongoose。
选择数据库时看这几个问题
团队最熟哪个数据库
ORM 能降低一部分使用门槛,但不能替代数据库经验。慢查询、锁等待、索引失效、连接池打满、迁移失败,这些问题最后还是要靠数据库知识解决。团队熟 PostgreSQL,就不要为了“切换简单”硬上 Oracle;团队 MySQL 经验深,也不必因为 PostgreSQL 功能强就马上换。
业务关系是否复杂
电商订单、权限系统、财务流水、内容平台这类关系清晰的业务,MySQL / PostgreSQL 更稳。日志、配置快照、用户画像、表单结果这类结构变化频繁的数据,MongoDB 或 JSONB 可能更舒服。
是否需要数据库特有能力
PostgreSQL 的 JSONB、数组、GIN 索引很好用;MySQL 的生态和运维资料很丰富;SQLite 部署简单;CockroachDB 和 Spanner 解决的是分布式一致性问题。用了这些能力,就要接受迁移时不再“数据库无关”。
部署环境是否支持
有些驱动在本地跑得很顺,进容器或 CI 就开始报错。Oracle、SAP HANA、SQLite 原生模块、better-sqlite3 都可能遇到构建环境问题。生产部署前要确认镜像、系统依赖、CPU 架构和连接配置。
迁移和 schema 的常见坑
TypeORM 给人一种“同一套 Entity 可以跑所有数据库”的感觉,但实际项目里,schema 差异经常藏在细节里。
字段类型不完全通用
varchar、text、timestamp、json、uuid、enum 在不同数据库中的实现不完全一样。PostgreSQL 有 jsonb,MySQL 有自己的 JSON 类型,SQLite 对类型更宽松,Oracle 的日期和字符类型又是另一套习惯。
尽量不要在通用代码里随便写数据库特有类型。如果明确只支持 PostgreSQL,那用 jsonb 没问题;如果未来要兼容 MySQL,就要提前设计抽象方式。
自动同步不适合生产
synchronize: true 在开发初期很方便,但生产环境必须关掉。它会根据 Entity 自动改表,遇到字段删除、类型调整、索引变化时风险很高。生产环境应该使用 migration,并在测试环境先跑一遍。
typescriptnew DataSource({ type: 'postgres', host: 'localhost', port: 5432, username: 'postgres', password: 'password', database: 'test', entities: ['src/entities/**/*.ts'], migrations: ['src/migrations/**/*.ts'], synchronize: false, });
迁移生成结果要人工检查
migration:generate 能减少手写 SQL,但不要把它当成绝对正确。字段重命名可能被识别成“删除旧列 + 新增新列”,这会导致数据丢失。索引、默认值、枚举、外键变化也要仔细看生成文件。
一个比较稳的习惯是:
bashnpm run typeorm migration:generate -- src/migrations/UpdateUserTable npm run typeorm migration:run npm run typeorm migration:show
生成后先读 migration 文件,再决定是否提交。对大表做字段修改时,最好拆成多次迁移:先加新列,再回填数据,再切读写,最后删旧列。
命名和大小写会影响跨库
PostgreSQL 对未加引号的标识符会转小写,MySQL 在不同系统上表名大小写行为可能不同,Oracle 对大小写和保留字也更敏感。Entity、表名、列名建议统一使用小写加下划线,少用数据库关键字。
typescript@Entity({ name: 'user_account' }) export class UserAccount { @Column({ name: 'created_at' }) createdAt: Date; }
这类看起来啰嗦的命名,能省掉不少跨环境问题。
生产环境配置要注意什么
连接池别用默认值糊弄
数据库连接不是越多越好。Node.js 服务副本一多,每个进程都开连接池,很容易把数据库打满。MySQL、PostgreSQL、SQL Server 等驱动的连接池配置方式略有不同,上线前要按实例数和数据库上限计算。
日志要区分开发和生产
开发环境可以打开 SQL 日志,排查很方便;生产环境全量打印 SQL 可能泄露敏感参数,也会制造大量日志。建议生产只打开错误日志或慢查询监控。
typescriptnew DataSource({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'password', database: 'test', logging: ['error'], synchronize: false, });
事务和锁要按数据库特性处理
同样一段事务代码,在 MySQL、PostgreSQL、CockroachDB 上的表现可能不同。隔离级别、死锁重试、行锁语法、DDL 是否能在事务里执行,都需要看数据库文档。特别是 CockroachDB 这类分布式 SQL,事务重试不是异常情况,而是应用必须处理的正常流程。
不要轻易承诺“随时切库”
TypeORM 的统一 API 确实能让简单 CRUD 更像一套代码,但真实系统里总会用到数据库特有能力:JSONB、全文索引、枚举、分页语法、锁、地理类型、数组、触发器、存储过程。用了以后,切库成本就会明显上升。
比较靠谱的说法是:TypeORM 能降低多数据库适配成本,但不能消除数据库差异。
怎么选最稳
如果是普通 Node.js 后端,默认可以从 MySQL / MariaDB 或 PostgreSQL 里选。团队重视生态、运维经验和兼容性,MySQL / MariaDB 很稳;需要复杂查询、JSONB、强事务和扩展能力,PostgreSQL 更合适。
本地工具、桌面应用、测试环境选 SQLite、better-sqlite3 或 sql.js。企业已有 SQL Server、Oracle、SAP HANA,就按现有基础设施接入。需要分布式 SQL,再评估 CockroachDB 或 Spanner。MongoDB 则要单独判断:如果只是想用 TypeORM 顺手连一下可以,但如果业务大量依赖文档数据库特性,最好认真比较 TypeORM MongoDB 支持和 MongoDB 原生生态的差别。
TypeORM 支持的数据库很多,真正影响项目质量的不是列表有多长,而是你有没有选一个团队能维护、迁移能控制、生产问题能排查的数据库。