跳到主要内容

云开发 MySQL 数据库

云开发 MySQL 数据库为您提供了完全托管的关系型数据库服务,支持在云函数中进行高效的数据操作。本文档将详细介绍如何在云函数中使用 MySQL 数据库,包括连接配置、数据操作、事务处理等核心功能。

快速开始

数据库连接

初始化 SDK

在使用 MySQL 数据库之前,需要先初始化云开发 SDK 并获取数据库引用:

const cloudbase = require('@cloudbase/node-sdk');

// 初始化云开发 App 实例
const app = cloudbase.init({
env: 'your-env-id' // 替换为您的环境 ID
});

// 获取 MySQL 数据库引用(使用默认实例和数据库)
const db = app.rdb();

基础操作

查询数据

使用 select() 方法查询表数据,支持条件筛选、关联查询等功能。

// 查询所有数据
const { data, error } = await db.from('articles').select();

// 查询指定字段
const { data, error } = await db.from('articles').select('id, title, created_at');

// 使用 * 查询所有字段
const { data, error } = await db.from('articles').select('*');

console.log('查询结果:', data);

插入数据

使用 insert() 方法向表中插入数据,支持单行插入和批量插入。

// 插入单条记录
const { error } = await db.from('articles').insert({
title: '云开发入门指南',
content: '这是一篇关于云开发的入门文章...',
author_id: 1,
status: 'draft'
});

if (error) {
console.error('插入失败:', error);
} else {
console.log('插入成功');
}

更新数据

使用 update() 方法更新表中的数据。注意:必须与过滤器结合使用

// 更新指定 ID 的记录
const { error } = await db.from('articles')
.update({
title: '更新后的标题',
status: 'published',
updated_at: new Date().toISOString()
})
.eq('id', 1);

console.log('更新结果:', error ? '失败' : '成功');

删除数据

使用 delete() 方法删除表中的数据。注意:必须与过滤器结合使用

// 删除指定 ID 的记录
const { error } = await db.from('articles')
.delete()
.eq('id', 1);

console.log('删除结果:', error ? '失败' : '成功');

HTTP API 访问

除了 Node.js SDK,您也可以通过 HTTP API 直接访问 MySQL 数据库。HTTP API 基于 REST 规范,支持标准的 HTTP 方法进行数据操作。

基础配置

// HTTP API 请求需要包含认证信息
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-access-token',
// 或使用其他认证方式
'X-CloudBase-Credentials': 'your-credentials'
};

const baseURL = 'https://your-env-id.service.tcloudbase.com/v1/rdb/rest';

查询数据

使用 GET 方法查询表中的数据:

# 查询所有数据
curl -X GET "https://your-env-id.service.tcloudbase.com/v1/rdb/rest/users" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json"

# 查询指定字段
curl -X GET "https://your-env-id.service.tcloudbase.com/v1/rdb/rest/users?select=id,name,email" \
-H "Authorization: Bearer your-access-token"

# 分页查询
curl -X GET "https://your-env-id.service.tcloudbase.com/v1/rdb/rest/users?limit=10&offset=20" \
-H "Authorization: Bearer your-access-token"

JavaScript 调用示例

// 查询用户列表
async function queryUsers() {
try {
const response = await fetch(`${config.baseURL}/users?select=*&limit=20`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${config.accessToken}`,
'Content-Type': 'application/json'
}
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const users = await response.json();
console.log('查询结果:', users);
return users;
} catch (error) {
console.error('查询失败:', error);
throw error;
}
}

// 条件查询
async function queryActiveUsers() {
const response = await fetch(`${config.baseURL}/users?status=eq.active&order=created_at.desc`, {
headers: {
'Authorization': `Bearer ${config.accessToken}`,
'Content-Type': 'application/json'
}
});

return await response.json();
}

高级功能

// 获取精确计数
async function getUserCount() {
const response = await fetch(`${config.baseURL}/users?select=*`, {
headers: {
'Authorization': `Bearer ${config.accessToken}`,
'Prefer': 'count=exact'
}
});

// 从响应头中获取计数
const count = response.headers.get('Content-Range');
console.log('用户总数:', count);

return count;
}

查询参数说明

参数说明示例
select选择字段,支持关联查询select=id,name,categories(name)
limit限制返回记录数limit=20
offset偏移量,用于分页offset=40
order排序字段order=created_at.desc
字段名=操作符.值过滤条件status=eq.active

过滤操作符

操作符说明示例
eq等于status=eq.active
neq不等于status=neq.inactive
gt大于age=gt.18
gte大于等于age=gte.18
lt小于age=lt.65
lte小于等于age=lte.65
like模糊匹配name=like.*张*
in包含id=in.(1,2,3)
is空值检查email=is.null

高级查询

查询修饰符

// 分页查询
const { data, error } = await db.from('articles')
.select('*')
.order('created_at', { ascending: false })
.range(0, 9); // 获取前 10 条记录

// 使用 limit 和 offset
const { data, error } = await db.from('articles')
.select('*')
.limit(10)
.offset(20);

复杂查询示例

// 复合条件查询
const { data, error } = await db.from('articles')
.select(`
id,
title,
category:categories(name),
author:users(name, email)
`)
.eq('status', 'published')
.gte('created_at', '2024-01-01')
.or('featured.eq.true,priority.gte.5')
.order('created_at', { ascending: false })
.limit(20);

// 内连接查询(排除 NULL 关联)
const { data, error } = await db.from('articles')
.select('title, categories!inner(name)')
.eq('categories.status', 'active');

事务处理

云开发 MySQL 支持事务操作,确保数据一致性:

exports.transferPoints = async (event, context) => {
const { fromUserId, toUserId, points } = event;

try {
// 开始事务
const { data, error } = await db.rpc('transfer_points', {
from_user: fromUserId,
to_user: toUserId,
point_amount: points
});

if (error) {
throw new Error(error.message);
}

return {
success: true,
message: '积分转移成功',
data: data
};
} catch (error) {
console.error('积分转移失败:', error);
return {
success: false,
error: error.message
};
}
};

原生 SQL 查询

对于复杂的查询需求,可以使用原生 SQL:

// 使用 RPC 调用存储过程或函数
const { data, error } = await db.rpc('get_user_statistics', {
user_id: 123,
start_date: '2024-01-01',
end_date: '2024-12-31'
});

// 复杂统计查询示例
const { data, error } = await db.rpc('complex_report', {
category: 'technology',
limit_count: 50
});

错误处理

exports.main = async (event, context) => {
try {
const { data, error } = await db.from('users')
.select('*')
.eq('id', event.userId);

if (error) {
// 处理数据库错误
console.error('数据库查询错误:', error);
return {
success: false,
error: '查询用户信息失败',
details: error.message
};
}

if (!data || data.length === 0) {
return {
success: false,
error: '用户不存在'
};
}

return {
success: true,
data: data[0]
};
} catch (error) {
console.error('系统错误:', error);
return {
success: false,
error: '系统内部错误'
};
}
};

最佳实践

1. 查询优化

// ✅ 好的做法:只查询需要的字段
const { data, error } = await db.from('users')
.select('id, name, email')
.eq('status', 'active');

// ❌ 避免:查询所有字段
const { data, error } = await db.from('users')
.select('*')
.eq('status', 'active');

2. 安全性

// ✅ 好的做法:使用参数化查询
const { data, error } = await db.from('users')
.select('*')
.eq('email', userEmail)
.eq('status', 'active');

// ✅ 数据验证
function validateUserInput(userData) {
if (!userData.email || !userData.email.includes('@')) {
throw new Error('无效的邮箱地址');
}

if (!userData.name || userData.name.length < 2) {
throw new Error('用户名至少需要2个字符');
}
}

3. 性能监控

// 查询性能监控
async function monitoredQuery(queryFunction) {
const startTime = Date.now();

try {
const result = await queryFunction();
const duration = Date.now() - startTime;

if (duration > 1000) {
console.warn(`慢查询检测: ${duration}ms`);
}

return result;
} catch (error) {
const duration = Date.now() - startTime;
console.error(`查询失败: ${duration}ms`, error);
throw error;
}
}

// 使用监控
const result = await monitoredQuery(() =>
db.from('articles').select('*').limit(100)
);

相关文档

提示
  • 所有的更新和删除操作都必须与过滤器结合使用,以防止误操作
  • 建议在生产环境中对所有数据库操作进行错误处理
  • 使用关联查询可以减少数据库请求次数,提高性能
  • 定期监控查询性能,优化慢查询
注意
  • 避免在循环中执行数据库查询,考虑使用批量操作
  • 大数据量查询时注意使用分页,避免内存溢出
  • 生产环境中务必对用户输入进行验证和过滤
安全提醒
  • 始终使用参数化查询,避免 SQL 注入风险
  • 不要在客户端代码中暴露数据库连接信息
  • 遵循最小权限原则,只授予必要的数据库权限