云数据库操作
云数据库是uniCloud提供的核心服务之一,它基于MongoDB,提供了强大的数据存储和查询能力。本文将详细介绍云数据库的操作方法,帮助开发者更好地使用云数据库功能。
1. 云数据库概述
1.1 什么是云数据库
云数据库是uniCloud提供的一种NoSQL数据库服务,基于MongoDB实现。它具有以下特点:
- 无服务器架构:无需管理服务器,自动扩展
- 高性能:支持高并发读写,低延迟
- 灵活的数据模型:支持文档型数据存储,无需预定义表结构
- 强大的查询能力:支持复杂查询、聚合操作、地理位置查询等
- 安全可靠:内置权限控制,数据自动备份
1.2 数据库结构
云数据库的基本结构如下:
- 数据库(Database):数据的顶层容器
- 集合(Collection):类似于关系型数据库中的表,用于存储文档
- 文档(Document):集合中的一条记录,类似于关系型数据库中的行
- 字段(Field):文档中的属性,类似于关系型数据库中的列
1.3 数据类型
云数据库支持以下数据类型:
- String:字符串
- Number:数字(整数或浮点数)
- Boolean:布尔值
- Date:日期时间
- Object:对象
- Array:数组
- Null:空值
- Binary:二进制数据
- ObjectId:对象ID
2. 数据库基本操作
2.1 获取数据库实例
在云函数或云对象中,可以通过以下方式获取数据库实例:
// 获取默认服务空间的数据库实例
const db = uniCloud.database();
// 获取指定服务空间的数据库实例
const db = uniCloud.database({
provider: 'aliyun', // 服务商,可选值:aliyun、tencent
spaceId: 'your-space-id' // 服务空间ID
});
2.2 集合操作
2.2.1 获取集合引用
// 获取集合引用
const collection = db.collection('collection-name');
2.2.2 创建集合
在uniCloud中,集合是自动创建的,无需显式创建。当向不存在的集合中添加文档时,集合会自动创建。
2.2.3 删除集合
// 删除集合
const result = await db.collection('collection-name').remove();
2.3 文档操作
2.3.1 添加文档
// 添加单条文档
const result = await db.collection('users').add({
name: '张三',
age: 25,
city: '北京',
createTime: Date.now()
});
console.log(result.id); // 新增文档的ID
// 添加多条文档
const result = await db.collection('users').add([
{
name: '张三',
age: 25,
city: '北京',
createTime: Date.now()
},
{
name: '李四',
age: 30,
city: '上海',
createTime: Date.now()
}
]);
console.log(result.ids); // 新增文档的ID数组
2.3.2 查询文档
// 查询单条文档
const result = await db.collection('users').doc('document-id').get();
console.log(result.data); // 文档数据
// 查询多条文档
const result = await db.collection('users')
.where({
age: db.command.gt(18), // 年龄大于18
city: '北京' // 城市为北京
})
.field({
name: true, // 只返回name字段
age: true // 只返回age字段
})
.orderBy('age', 'desc') // 按年龄降序排序
.skip(0) // 跳过0条记录
.limit(10) // 最多返回10条记录
.get();
console.log(result.data); // 文档数据数组
2.3.3 更新文档
// 更新单条文档
const result = await db.collection('users').doc('document-id').update({
age: 26,
updateTime: Date.now()
});
console.log(result.updated); // 更新的文档数
// 更新多条文档
const result = await db.collection('users').where({
city: '北京'
}).update({
city: '广州',
updateTime: Date.now()
});
console.log(result.updated); // 更新的文档数
2.3.4 删除文档
// 删除单条文档
const result = await db.collection('users').doc('document-id').remove();
console.log(result.deleted); // 删除的文档数
// 删除多条文档
const result = await db.collection('users').where({
age: db.command.lt(18)
}).remove();
console.log(result.deleted); // 删除的文档数
3. 数据库查询
3.1 查询条件
uniCloud提供了丰富的查询条件操作符,可以构建复杂的查询条件:
// 等于
db.collection('users').where({
name: '张三'
})
// 不等于
db.collection('users').where({
age: db.command.neq(18)
})
// 大于
db.collection('users').where({
age: db.command.gt(18)
})
// 大于等于
db.collection('users').where({
age: db.command.gte(18)
})
// 小于
db.collection('users').where({
age: db.command.lt(18)
})
// 小于等于
db.collection('users').where({
age: db.command.lte(18)
})
// 在数组中
db.collection('users').where({
city: db.command.in(['北京', '上海', '广州'])
})
// 不在数组中
db.collection('users').where({
city: db.command.nin(['北京', '上海', '广州'])
})
// 逻辑与
db.collection('users').where({
age: db.command.gt(18),
city: '北京'
})
// 逻辑或
db.collection('users').where(db.command.or([
{
age: db.command.gt(18)
},
{
city: '北京'
}
]))
// 逻辑非
db.collection('users').where(db.command.not({
age: db.command.lt(18)
}))
// 正则表达式
db.collection('users').where({
name: db.RegExp({
regexp: '张',
options: 'i' // i表示不区分大小写
})
})
3.2 查询方法
3.2.1 获取查询结果
// 获取查询结果
const result = await db.collection('users')
.where({
age: db.command.gt(18)
})
.get();
console.log(result.data); // 查询结果
3.2.2 统计查询结果数量
// 统计查询结果数量
const result = await db.collection('users')
.where({
age: db.command.gt(18)
})
.count();
console.log(result.total); // 查询结果数量
3.2.3 分页查询
// 分页查询
const pageSize = 10;
const page = 1;
const result = await db.collection('users')
.where({
age: db.command.gt(18)
})
.skip((page - 1) * pageSize)
.limit(pageSize)
.get();
console.log(result.data); // 当前页的查询结果
3.2.4 排序
// 排序
const result = await db.collection('users')
.orderBy('age', 'desc') // 按年龄降序排序
.get();
console.log(result.data); // 排序后的查询结果
// 多字段排序
const result = await db.collection('users')
.orderBy('age', 'desc') // 先按年龄降序排序
.orderBy('name', 'asc') // 再按姓名升序排序
.get();
console.log(result.data); // 排序后的查询结果
3.2.5 字段过滤
// 字段过滤
const result = await db.collection('users')
.field({
name: true, // 只返回name字段
age: true // 只返回age字段
})
.get();
console.log(result.data); // 过滤后的查询结果
3.3 聚合操作
聚合操作可以对数据进行分组、计算和转换,常用于统计分析场景。
// 聚合操作
const result = await db.collection('orders')
.aggregate()
.match({
status: 'completed'
})
.group({
_id: '$userId',
totalAmount: db.command.aggregate.sum('$amount'),
orderCount: db.command.aggregate.count()
})
.sort({
totalAmount: -1
})
.limit(10)
.end();
console.log(result.data); // 聚合结果
常用的聚合操作符包括:
- $sum:求和
- $avg:平均值
- $max:最大值
- $min:最小值
- $count:计数
- $first:第一个值
- $last:最后一个值
4. 数据库索引
4.1 索引概述
索引是提高数据库查询性能的重要手段,它可以加快数据的检索速度。在uniCloud中,可以为集合创建索引,以优化查询性能。
4.2 创建索引
在uniCloud中,可以通过以下方式创建索引:
- 在HBuilderX中,右键点击集合,选择"创建索引"
- 在云函数中,使用
db.collection('collection-name').createIndex()方法
// 创建单字段索引
await db.collection('users').createIndex({
name: 1 // 1表示升序,-1表示降序
});
// 创建复合索引
await db.collection('users').createIndex({
age: 1,
city: 1
});
// 创建唯一索引
await db.collection('users').createIndex({
email: 1
}, {
unique: true
});
4.3 索引类型
uniCloud支持以下类型的索引:
- 单字段索引:基于单个字段创建的索引
- 复合索引:基于多个字段创建的索引
- 唯一索引:确保索引字段的值在集合中是唯一的
- 稀疏索引:只索引包含索引字段的文档
- TTL索引:基于时间自动删除文档的索引
4.4 索引管理
// 获取集合的索引列表
const indexes = await db.collection('users').getIndexes();
console.log(indexes); // 索引列表
// 删除索引
await db.collection('users').dropIndex('index-name');
5. 数据库权限
5.1 权限概述
数据库权限控制是保护数据安全的重要手段,它可以限制用户对数据的访问权限。在uniCloud中,可以为集合设置权限,以控制数据的访问。
5.2 权限类型
uniCloud支持以下类型的权限:
- read:读取权限
- write:写入权限
- update:更新权限
- delete:删除权限
- count:计数权限
- aggregate:聚合权限
5.3 权限设置
在uniCloud中,可以通过以下方式设置权限:
- 在HBuilderX中,右键点击集合,选择"权限设置"
- 在云函数中,使用
db.collection('collection-name').setPermission()方法
// 设置集合权限
await db.collection('users').setPermission({
read: true, // 所有用户可读
write: false, // 所有用户不可写
update: 'auth.uid != null', // 已登录用户可更新
delete: 'auth.uid == doc.userId' // 只有文档所有者可删除
});
5.4 权限表达式
权限表达式是一个JavaScript表达式,用于判断用户是否有权限执行操作。在表达式中,可以使用以下变量:
- auth:当前用户信息
- doc:当前文档信息
- now:当前时间
// 权限表达式示例
'auth.uid != null' // 已登录用户
'auth.uid == doc.userId' // 文档所有者
'doc.status == "published"' // 已发布的文档
'now > doc.expireTime' // 未过期的文档
6. 数据库事务
6.1 事务概述
事务是数据库操作的基本单位,它可以确保一组操作要么全部成功,要么全部失败,保证数据的一致性。在uniCloud中,支持数据库事务,可以保证数据操作的原子性。
6.2 事务操作
// 开启事务
const transaction = await db.startTransaction();
try {
// 在事务中执行操作
await transaction.collection('users').doc('user-id').update({
balance: db.command.inc(-100) // 减少余额
});
await transaction.collection('orders').add({
userId: 'user-id',
amount: 100,
createTime: Date.now()
});
// 提交事务
await transaction.commit();
} catch (error) {
// 回滚事务
await transaction.rollback();
throw error;
}
6.3 事务限制
在uniCloud中,事务有以下限制:
- 事务中的操作必须在同一个集合内
- 事务中的操作不能超过10个
- 事务的执行时间不能超过10秒
7. 数据库触发器
7.1 触发器概述
触发器是数据库中的一种特殊对象,它可以在特定事件发生时自动执行。在uniCloud中,支持数据库触发器,可以在数据变更时自动执行云函数。
7.2 触发器类型
uniCloud支持以下类型的触发器:
- insert:插入文档时触发
- update:更新文档时触发
- delete:删除文档时触发
7.3 创建触发器
在uniCloud中,可以通过以下方式创建触发器:
- 在HBuilderX中,右键点击集合,选择"创建触发器"
- 在云函数中,使用
db.collection('collection-name').createTrigger()方法
// 创建触发器
await db.collection('users').createTrigger({
name: 'user-trigger',
type: 'insert',
function: 'user-function'
});
7.4 触发器示例
// 用户注册触发器
exports.main = async function(event) {
const { type, doc } = event;
if (type === 'insert') {
// 新用户注册时,自动创建用户配置
const db = uniCloud.database();
await db.collection('user-configs').add({
userId: doc._id,
theme: 'light',
notifications: true,
createTime: Date.now()
});
}
return { success: true };
};
8. 数据库最佳实践
8.1 数据模型设计
良好的数据模型设计是数据库操作的基础,以下是一些设计原则:
- 避免过深的嵌套:过深的嵌套会增加查询复杂度
- 避免过大的文档:过大的文档会影响读写性能
- 适当冗余:适当冗余可以提高查询性能
- 使用引用而非嵌入:对于一对多关系,优先使用引用而非嵌入
8.2 查询优化
查询优化是提高数据库性能的关键,以下是一些优化技巧:
- 使用索引:为常用查询字段创建索引
- 限制返回字段:只返回需要的字段,减少数据传输量
- 使用分页:对于大量数据,使用分页查询
- 避免全表扫描:尽量使用索引字段进行查询
8.3 安全考虑
数据库安全是应用安全的基础,以下是一些安全建议:
- 设置适当的权限:为集合设置适当的权限,限制数据访问
- 验证输入数据:在写入数据库前,验证输入数据的合法性
- 使用参数化查询:避免SQL注入等安全问题
- 加密敏感数据:对敏感数据进行加密存储
8.4 性能优化
数据库性能优化是提高应用响应速度的关键,以下是一些优化建议:
- 使用缓存:对于频繁访问的数据,使用缓存减少数据库访问
- 批量操作:对于多条数据操作,使用批量操作减少网络请求
- 异步操作:对于非关键操作,使用异步操作提高响应速度
- 定期维护:定期清理无用数据,优化索引结构
9. 总结
云数据库是uniCloud提供的核心服务之一,它提供了强大的数据存储和查询能力。通过本文的介绍,您应该已经了解了云数据库的基本概念、操作方法、查询技巧、索引管理、权限控制、事务操作和触发器功能。在实际开发中,根据业务需求,合理使用这些功能,可以构建高效、安全、可靠的数据库应用。