Keystone 支持 MySQL:数据库供应商配置与实战指南
2026/9/24 14:40:35 网站建设 项目流程
  • 后端

【免费下载链接】keystone

The superpowered headless CMS for Node.js — built with GraphQL and React

项目地址:https://gitcode.com/gh_mirrors/key/keystone
点击查看免费下载

本指南以 Keystone 官方博客《Keystone now supports MySQL》为骨架展开,结合当前仓库中的源码、配置文档与测试代码,系统讲解 MySQL 作为数据库供应商的配置方式、与 Postgres/SQLite 的关键差异、id 字段选择以及测试工具用法。读完本文,你将能够为 Keystone 项目一键切换 MySQL,并规避跨数据库行为差异带来的坑。

引言:Keystone 的三大数据库供应商

Keystone 是一个基于 Node.js、以 GraphQL 与 React 构建的超强 headless CMS(无头内容管理系统)。Keystone 官方博客于 2022 年 6 月宣布:Keystone 正式支持 MySQL,至此支持的数据库类型达到三种——PostgreSQL、MySQL 与 SQLite。

从源码角度看,这三种数据库类型的支持在 packages/core/src/types/core.ts 中被定义为一个联合类型:

export type DatabaseProvider = 'sqlite' | 'postgresql' | 'mysql'

而在配置校验层(packages/core/src/schema.ts),Keystone 会对db.provider做白名单校验,只接受这三个值:

if (!['postgresql', 'sqlite', 'mysql'].includes(config.db.provider)) { throw new TypeError(`"db.provider" only supports "sqlite", "postgresql" or "mysql"`) }

在生成 Prisma schema 时,packages/core/src/lib/core/prisma-schema-printer.ts 会直接将db.provider原样写入datasource块:

datasource mysql { provider = "mysql" }

也就是说,Keystone 的数据库能力由对应的 Prisma provider(postgresqlmysqlsqlite)驱动,开发者只需在db配置中声明 provider,即可获得整套 schema 生成、迁移与 GraphQL 查询能力。

MySQL 数据库配置:最简起步

官方博客给出的 MySQLdb.config示例(db.provider'mysql',连接串指向本地 3306 端口的keystone数据库,并使用uuid作为 id 字段)如下:

export default config({ db: { provider: 'mysql', url: 'mysql://dbuser:dbpass@localhost:3306/keystone', idField: { kind: 'uuid' }, }, ... });

这是最直观的起步写法:provider声明数据库类型,url给出包含用户名、密码、主机、端口与库名的标准 MySQL 连接串。idField: { kind: 'uuid' }指定列表主键使用 UUID 字符串,而非默认的自增整数。

基于驱动适配器的现代配置(推荐)

随着 Prisma 驱动适配器(driver adapter)机制的引入,当前仓库的官方配置文档(docs/content/docs/config/config.md)推荐在db中使用prismaClientOptions显式传入适配器。MySQL 对应的适配器是@prisma/adapter-mariadb(MariaDB 协议与 MySQL 兼容,可直连 MySQL 服务器):

import { PrismaMariaDb } from '@prisma/adapter-mariadb' export default config<TypeInfo>({ db: { provider: 'mysql', prismaClientOptions: () => ({ adapter: new PrismaMariaDb(process.env.DATABASE_URL!), }), onConnect: async context => { /* ... */ }, idField: { kind: 'uuid' }, }, /* ... */ })

配置项说明:

  • provider:取值固定为'mysql',由 DatabaseProvider 约束;
  • prismaClientOptions:返回 Prisma Client 构造选项的函数,其中必须包含adapter
  • onConnect:接收 KeystoneContext(如数据播种等启动期动作);
  • idField:id 字段种类,可为cuid(默认)、uuidnanoidulidautoincrement;MySQL 与 PostgreSQL 上autoincrement还可指定type: 'BigInt'

配套地,还需要在prisma.config.ts中为 Prisma CLI 提供数据源 URL(keystone dev内部的prisma db push依赖它):

import 'dotenv/config' import { defineConfig, env } from 'prisma/config' export default defineConfig({ schema: 'schema.prisma', migrations: { path: 'migrations' }, datasource: { url: env('DATABASE_URL'), // only necessary if you want to use a specific shadow database shadowDatabaseUrl: env('SHADOW_DATABASE_URL'), }, })

注意,prismaClientOptions(运行时的 Prisma Client)与prisma.config.ts(Prisma CLI)是两套独立的配置来源,不要混用。

三种数据库的关键差异与选型依据

官方博客明确指出“Postgres 与 MySQL 在运行方式上存在差异”,并引导读者参考《choosing the right database》指南。仓库中的 docs/content/docs/guides/choosing-a-database.md 给出了选型时最需要关注的三个差异点:

1. 大小写敏感性(Case Sensitivity)

  • Postgres默认区分大小写;使用StringFilter时可用mode: insensitive实现不区分大小写的查询;
  • MySQL默认不区分大小写;
  • SQLitecontainsstartsWithendsWith不区分大小写;
  • 注意mode: insensitive在 MySQL 与 SQLite 上不被支持。

这意味着同样的 GraphQL 过滤与排序查询,在不同数据库上的结果可能不同,取决于数据库的 collation(排序规则)。

2. 字段默认类型差异

Prisma 针对不同数据库使用不同的默认列类型。例如 Keystone 的text字段在 Prisma 中映射为String

  • Postgres:使用text列类型;
  • MySQL:使用varchar(191)列类型。

如需覆盖默认类型,Keystone 的text字段支持db.nativeType选项。从源码 packages/core/src/lib/core/prisma-schema-printer.ts 可以看到,nativeType 会以@${datasourceName}.${nativeType}的形式打印进生成的 schema,例如@mysql.VarChar(255)

3. 自增整数字段的要求

当 Integer 字段使用defaultValue: { kind: 'autoincrement' }时,MySQL 要求该字段必须带索引,即同时设置isIndexed: trueisIndexed: 'unique'。Postgres 没有这个限制。

从源码(packages/core/src/fields/types/integer/index.ts、packages/core/src/fields/types/bigInt/index.ts)看,autoincrement还受若干约束校验:例如 SQLite 不支持BigInt类型的自增 id(packages/core/src/lib/id-field.ts),因此跨数据库迁移时要特别注意。

id 字段:从autoincrementuuid

官方博客示例特意为 MySQL 选择了idField: { kind: 'uuid' },这与 MySQL 自增主键的行为差异直接相关。Keystone 支持五种 id 种类,具体映射逻辑位于 packages/core/src/lib/id-field.ts:

idField kindPrisma 标量默认值
cuid(默认)Stringcuid 生成器
uuidStringuuid 生成器
nanoidStringnanoid 生成器(可配length
ulidStringulid 生成器
autoincrementInt(或type: 'BigInt'数据库自增

kindautoincrement时,可选的type在 MySQL/PostgreSQL 上支持BigInt;而 SQLite 不支持 BigInt 自增 id,会在校验阶段直接抛错。因此:

  • 若希望主键为随机字符串(便于分布式生成、避免暴露数据量),使用uuid/cuid/nanoid/ulid
  • 若希望沿用数据库自增主键,使用autoincrement,并注意 MySQL 下列字段的索引要求(见上文)。

MySQL 下的测试:@keystone-6/core/testing/mysql

仓库为 MySQL 提供了专门的测试工具,入口为 packages/core/src/testing/mysql.ts。它封装了 MySQL/MariaDB 连接的常用流程:

  • resetDatabase(config, migrationsDirectory):解析连接串中的数据库名,先尝试连接目标库;若库不存在(ER_BAD_DB_ERROR/ errno 1049),会先自动创建;
  • 通过mysql系统库建库,使用CREATE DATABASE ... CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci(errno 1007 表示库已存在,忽略);
  • 随后 DROP 并重建目标库,再依次执行migrationsDirectory下的迁移 SQL,完成测试库重置。

升级指南(docs/content/docs/guides/migrate-to-8.md)指出,测试工具按 provider 拆分:PostgreSQL 使用@keystone-6/core/testing/postgresql,MySQL 使用@keystone-6/core/testing/mysql。API 测试套件(tests/api-tests/utils.ts)也展示了按DATABASE_URL前缀自动选择 provider 并构造对应适配器的标准做法:

if (dbUrl.startsWith('mysql:')) return 'mysql' as const // ... return { adapter: new PrismaMariaDb(url) }

这与你生产环境配置中的prismaClientOptions使用方式完全一致。

完整实战示例:将现有项目切换到 MySQL

综合上述内容,一个可落地的 MySQL 配置如下(可直接复制到keystone.ts):

import { config } from '@keystone-6/core' import { PrismaMariaDb } from '@prisma/adapter-mariadb' export default config({ db: { provider: 'mysql', url: process.env.DATABASE_URL!, prismaClientOptions: () => ({ adapter: new PrismaMariaDb(process.env.DATABASE_URL!), }), onConnect: async context => { // 可选:启动时执行数据播种等操作 }, idField: { kind: 'uuid' }, }, lists: { /* ... */ }, })

环境变量示例(DATABASE_URL):

DATABASE_URL="mysql://dbuser:dbpass@localhost:3306/keystone"

然后按以下步骤完成接入:

  1. 安装驱动依赖:pnpm add @prisma/adapter-mariadb(具体以项目包管理器为准);
  2. prisma.config.ts中配置datasource.url指向DATABASE_URL
  3. 运行keystone devkeystone prisma migrate dev,让 Prisma 依据 provider 生成/同步 schema;
  4. 启动后即可通过 GraphQL API 与 Admin UI 操作 MySQL 中的数据。

结语

MySQL 的加入使 Keystone 在数据库选型上拥有 Postgres、MySQL、SQLite 三档能力:SQLite 适合本地开发与 Embedded Keystone 这类嵌入式场景,Postgres 与 MySQL 适合生产环境。切换数据库时,重点检查大小写敏感性、字段默认列类型与自增字段索引这三处行为差异,配合仓库中的 数据库选型指南 与 DB 配置文档,即可平稳迁移。

  • 后端

【免费下载链接】keystone

The superpowered headless CMS for Node.js — built with GraphQL and React

项目地址:https://gitcode.com/gh_mirrors/key/keystone
点击查看免费下载

相关推荐

上一篇:双速率分词革命:Step-Audio-Tokenizer如何重新定义语音大模型交互
下一篇:告别顶面缝隙与毛边:OrcaSlicer 流量校准一次搞定指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询