uniCloud 云数据库操作

153 阅读9分钟

云数据库操作

云数据库是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中,可以通过以下方式创建索引:

  1. 在HBuilderX中,右键点击集合,选择"创建索引"
  2. 在云函数中,使用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中,可以通过以下方式设置权限:

  1. 在HBuilderX中,右键点击集合,选择"权限设置"
  2. 在云函数中,使用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中,可以通过以下方式创建触发器:

  1. 在HBuilderX中,右键点击集合,选择"创建触发器"
  2. 在云函数中,使用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提供的核心服务之一,它提供了强大的数据存储和查询能力。通过本文的介绍,您应该已经了解了云数据库的基本概念、操作方法、查询技巧、索引管理、权限控制、事务操作和触发器功能。在实际开发中,根据业务需求,合理使用这些功能,可以构建高效、安全、可靠的数据库应用。