18 10 月 2026
小程序后端绕不开数据库。选 MySQL 还是 MongoDB?连接怎么管?SQL 注入怎么防?这篇用一个真实的"用户 + 订单"模型,把小程序后端数据库的选型、连接、防护、备份整套方案讲透。

一、选型:什么项目用什么数据库

场景推荐理由
有订单/用户/商品等结构化数据MySQL 8事务、关联查询、生态成熟
高频读的会话/缓存Redis微秒级读取,扛 token 和热点数据
日志/埋点/行为数据MongoDB 或直接 ES写入无模式,查询灵活
配置类小数据应用内 JSON / SQLite别为十个配置起个库

90% 的小程序用 MySQL + Redis 就够了,别一上来就堆技术栈。小程序云开发用的是文档型数据库(类 MongoDB),没有事务和复杂关联——这也是云开发 vs 自建后端里劝你"正式项目自建"的原因之一。

二、MySQL 基础配置

1. 建库建账号(别用 root 跑业务):

CREATE DATABASE miniapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'app'@'127.0.0.1' IDENTIFIED BY '强密码';
GRANT SELECT, INSERT, UPDATE, DELETE ON miniapp.* TO 'app'@'127.0.0.1';
FLUSH PRIVILEGES;

三个要点:utf8mb4(支持 emoji,utf8 会截断)、localhost only(数据库不对公网开放)、最小权限(业务账号不给 DDL 权限,见数据库安全加固与权限最小化)。

2. Docker 起一个 MySQL:

services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 强密码
      MYSQL_DATABASE: miniapp
    command: --default-authentication-plugin=caching_sha2_password
    volumes: ["db-data:/var/lib/mysql"]
    restart: unless-stopped
volumes:
  db-data:

3. 参数调优(2核4G 机器参考):

[mysqld]
innodb_buffer_pool_size = 1G        # 内存的 50-60% 给缓冲池
max_connections = 200               # 小程序并发通常 < 100
innodb_flush_log_at_trx_commit = 2  # 性能与安全的折中

完整调优见MySQL 安装与优化入门。

三、连接管理:连接池是生命线

反面教材——每个请求建一次连接:

// 错误:高并发下把 MySQL 连接数打满,直接 "Too many connections"
app.get('/api/list', async (req, res) => {
  const conn = await mysql.createConnection(dbConfig)
  const [rows] = await conn.query('SELECT * FROM posts LIMIT 20')
  await conn.end()
  res.json(rows)
})

正确做法——连接池,整个应用共享:

const mysql = require('mysql2/promise')
const pool = mysql.createPool({
  host: '127.0.0.1',
  user: 'app',
  password: '强密码',
  database: 'miniapp',
  waitForConnections: true,
  connectionLimit: 20,        // 池大小 ≈ max_connections 的 1/4 到 1/2
  queueLimit: 0,
  charset: 'utf8mb4'
})

app.get('/api/list', async (req, res) => {
  const [rows] = await pool.query('SELECT id, title FROM posts WHERE status=? LIMIT ?', [1, 20])
  res.json(rows)
})

池大小怎么定:connectionLimit × 应用实例数 < max_connections × 0.8。留 20% 余量给运维和后台任务。

四、SQL 注入:参数化查询没有例外

小程序后端面对公网,所有用户输入都不可信。注入的经典后果是拖库——用户的手机号、订单全泄露。

// 危险:字符串拼接,输入 ' OR 1=1 -- 直接穿
const sql = `SELECT * FROM users WHERE phone = '${phone}'`

// 安全:参数化,驱动层处理转义
const [rows] = await pool.query('SELECT * FROM users WHERE phone = ?', [phone])

// 动态条件也安全(注意 LIMIT 的参数化)
const conditions = ['status = ?']
const params = [1]
if (req.query.keyword) {
  conditions.push('title LIKE ?')
  params.push(`%${req.query.keyword}%`)
}
const [rows] = await pool.query(
  `SELECT id, title FROM posts WHERE ${conditions.join(' AND ')} LIMIT ?`,
  [...params, 20]
)

三条铁律:

  1. 永远参数化,ORM(Sequelize/TypeORM/Prisma)同理
  2. 绝不拼接 SQL,包括 ORDER BY 字段名(白名单校验)
  3. 错误信息别返回给前端——err.message 里的表结构是给攻击者的礼物,统一返回"服务器错误"

配套防护:WAF 规则过滤常见注入特征,见WAF 规则实战和网站常见漏洞与基础防护。

五、Redis:会话和缓存的标配

小程序登录态放 Redis 是标准姿势:

const { createClient } = require('redis')
const redis = createClient({ url: 'redis://:强密码@127.0.0.1:6379' })
await redis.connect()

// 登录:签发 token 存 Redis,2 小时过期
await redis.set('token:' + token, openid, { EX: 7200 })

// 鉴权中间件
app.use(async (req, res, next) => {
  const token = req.headers.authorization?.replace('Bearer ', '')
  const openid = await redis.get('token:' + token)
  if (!openid) return res.status(401).json({ error: '未登录' })
  req.openid = openid
  next()
})

Redis 必须设密码——没密码的 Redis 是公网扫描器的自助提权通道,见Redis 未授权访问防护。缓存雪崩防护(随机过期时间)见Redis 大 Key 与热 Key 处理。

六、备份:数据的最后防线

小程序后台的数据库是纯增量资产,丢了不可再生。三层备份:

# 1. 每日逻辑备份(crontab)
0 3 * * * mysqldump -u root -p强密码 --single-transaction --routines miniapp \
  | gzip > /backup/miniapp-$(date +\%F).sql.gz

# 2. 异地一份(另一台机器或对象存储)
rsync -az /backup/ user@备份机:/backup/miniapp/

# 3. binlog 开启,支持时间点恢复

binlog 时间点恢复的完整操作见MySQL 备份与恢复实战。每周做一次恢复演练——没验证过的备份等于没有备份。

七、性能 checklist

  • [ ] 连接池已启用,池大小合理
  • [ ] 查询字段具体化(别 SELECT *,大文本列拖慢 IO)
  • [ ] 高频查询走索引,EXPLAIN 验证,慢查询治理见MySQL 慢查询优化实战
  • [ ] 热点数据进 Redis,数据库只兜底
  • [ ] 深分页用游标(WHERE id < ?)替代大 OFFSET
  • [ ] 每日备份 + 异地 + 恢复演练

结语

小程序数据库的技术核心就四件事:选对型、管好连接、防住注入、备好数据。MySQL + Redis + 连接池 + 参数化查询,这一套组合能扛住日活十万级的小程序,而且是每个后端的基本功,没有玄学。

需要搭小程序数据库服务器,可以看看财富云计算:NAT 型云服务器支持 443 映射,SSD 盘扛数据库随机读写,快照 + 自动备份随打随走,4核8G 档跑 MySQL + Redis 毫无压力,价格比独立 IP 机型省一半以上。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:小程序审核被拒原因与解决:TOP10 拒因清单和过审技巧
  2. 下一篇:小程序图片上传与文件存储:对象存储直传方案
发表评论 1

取消回复