云数据库是什么?
云开发提供了一个 NoSQL 数据库,数据库中的每条记录都是一个 JSON 格式的对象。一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录(或称为文档),记录的格式是 JSON 对象。
关系型数据库和 JSON 数据库的概念对应关系如下表:
关系型 | 文档型 |
---|---|
数据库 database | 数据库 database |
表 table | 集合 collection |
行 row | 记录 record / doc |
列 column | 字段 field |
- 需要区别的是,云数据库,可以存不一样的json对象,不要求field一致都能储存。
- 数据库建表需要同时创建字段,只有创建的字段可以使用,云函数不需要定义初始字段,任意缩减。
- 腾讯云云数据库可以前端直接通过SDK发起调用。
- 云数据库不需要会sql语句,通过SDK操作一切。
数据库嘛,首先有增删改查四种基本能力,那么接下来就详细介绍一下,云数据库的增删改查。
前置条件
1、创建数据集
云开发控制台》数据库》集合列表点击加号新增数据集
2、拿到数据库操作对象
代码语言:javascript复制//web端
const tcb = require('tcb-js-sdk')//任意方式引用web端tcb的sdk
const app = tcb.init({env: 'xxxx'})//初始化和授权
var db = app.database()// 获取数据库对象
//小程序端
const db = wx.cloud.database();//直接获取数据库对象
//小程序的云函数端-使用wx-server-sdk
const cloud = require('wx-server-sdk')//引用SDK
cloud.init({env: cloud.DYNAMIC_CURRENT_ENV})//初始化
const db = cloud.database();//获取数据库对象
//web的云函数端-使用@cloudbase/node-sdk
const tcb = require('@cloudbase/node-sdk')//引用SDK
const app = tcb.init({env: 'xxxx'})//初始化
var db = app.database()//获取数据库对象
3、拿到数据集处理对象(已经拿到数据库操作对象db
)
这一步一般不会单独操作,都是级联的写法,当然如果对同一个数据集操作频繁,也可以先获取数据集对象。
1、小程序端或者小程序端的云函数(wx-server-sdk)
代码语言:javascript复制const db_test = db.collection('test');
2、web端或者web端云函数(@cloudbase/node-sdk)
增(插入数据)
1、web端或者web端云函数(@cloudbase/node-sdk)
代码语言:javascript复制let data = {name:'name',age:18};//要操作的数据对象
db.collection('test').add(data)//对test数据集新增数据data列
2、小程序端或者小程序端的云函数(wx-server-sdk)
代码语言:javascript复制let data = {name:'name',age:18};//要操作的数据对象
db.collection('test').add({data:data})//对test数据集新增数据data列
发现区别了吗?这两种情况需要多套一层data,否则会出现诡异报错,亲测出现过data不存在的错,也出现过add方法找不到的错,一定要切记这两种情况要多套一层data数据层
3、批量新增(仅在服务器端可以批量新增操作【云函数】
)
代码语言:javascript复制let datas = [{name:'name',age:18},{name:'name',age:18}];//要操作的数据对象数组
//web端云函数
db.collection('test').add(datas)//对test数据集新增数组里的两条数据
//小程序端云函数,批量的也一样要多套一层data数据层
db.collection('test').add({data:datas})//对test数据集新增数组里的两条数据
删(删除数据)
1、单个删除
代码语言:javascript复制db.collection('test').doc('doc-id').remove()//删除test数据集中id为'doc-id'的值
2、批量删除(只支持服务器端【云函数】)
代码语言:javascript复制const _ = db.command//获取数据库筛选器方法对象
db.collection('test').where({//对数据集test进行where条件筛选
age:_.gt(18)//筛选集合中年龄大于18的所有数据对象
}).remove()//删除筛选出来的所有结果
改(修改行数据)
1、局部修改(修改数据对象中一部分列)
代码语言:javascript复制db.collection('todos').doc('doc-id').update({//对test数据集中id为'doc-id'的数据进行更新操作
age: 16//将年龄修改为16
});
//同样的,小程序端和小程序端的云函数,请多包一层data
db.collection('todos').doc('doc-id').update({//对test数据集中id为'doc-id'的数据进行更新操作
data:{age: 16}//将年龄修改为16
});
2、覆盖修改(替换一整条数据,直接覆盖)
代码语言:javascript复制db.collection('todos').doc('doc-id').set({//对test数据集中id为'doc-id'的数据进行更新操作
name:'ceshi1',age: 16//将数据替换为新的对象
})
//同样的,小程序端和小程序端的云函数,请多包一层data
db.collection('todos').doc('doc-id').set({//对test数据集中id为'doc-id'的数据进行更新操作
data:{name:'ceshi1',age: 16}//将数据替换为新的对象
});
3、批量修改(这次前端和服务器端都支持了
)
代码语言:javascript复制//将doc查询换成where查询就是啦
db.collection('todos').where(//对数据集test进行where条件筛选
age:_.gt(18)//筛选集合中年龄大于18的所有数据对象
).set({//对筛选出来的的数据进行更新操作
age: 16//将年龄修改为16
})
//同样的,小程序端和小程序端的云函数,请多包一层data
db.collection('todos').where(//对数据集test进行where条件筛选
age:_.gt(18)//筛选集合中年龄大于18的所有数据对象
).set({//对筛选出来的的数据进行更新操作
data:{age: 16}//将年龄修改为16
});
查(查询数据)
查询指令,应用于构建查询条件。以下指令皆挂载在 db.command
下:
类型 | 接口 | 说明 |
---|---|---|
比较运算 | eq | 字段 == |
neq | 字段 != | |
gt | 字段 > | |
gte | 字段 >= | |
lt | 字段 < | |
lte | 字段 <= | |
in | 字段值在数组里 | |
nin | 字段值不在数组里 | |
逻辑运算 | and | 表示需同时满足指定的所有条件 |
or | 表示需同时满足指定条件中的至少一个 |
简单查询
代码语言:javascript复制const _ = db.command
db.collection('test').where({//对数据集test进行where条件筛选
age: _.gt(18)//筛选集合中年龄大于18的所有数据对象
}).get()//获取筛选到的所有数据(默认100条)
逻辑查询
代码语言:javascript复制const _ = db.command
db.collection('test').where({//对数据集test进行where条件筛选
_.or([
{age: _.gt(18)},
{gender: _.eq('男')}
])//筛选集合中年龄大于18的或者性别为男的所有数据对象
}).get()//获取筛选到的所有数据(默认100条)
分页查询
代码语言:javascript复制db.collection('test').where({//对数据集test进行where条件筛选
age: _.gt(18)//筛选集合中年龄大于18的所有数据对象
}).limit(10).skip(20).get()//获取筛选到第20条数据开始拉取10条。
排序查询
代码语言:javascript复制db.collection('test').where({//对数据集test进行where条件筛选
age: _.gt(18)//筛选集合中年龄大于18的所有数据对象
}).orderBy('age','asc').orderBy('gender','desc').get()//获取筛选到的所有数据(默认100条)
//先对年龄进行正序排序,再对性别倒叙排序。
查询指定列(不能true和false混用,否则会报错)
代码语言:javascript复制db.collection('test').where({//对数据集test进行where条件筛选
age: _.gt(18)//筛选集合中年龄大于18的所有数据对象
}).field({ age: true }).get()//获取筛选到的所有数据,只查询age列(默认100条)
.field({ age: false})//只屏蔽age列
.field({ age: true,gender:true})//只查询age和gender列
.field({ age: false,gender:false})//只屏蔽age和gender列
聚合查询
代码语言:javascript复制 const $ = db.command.aggregate //获取聚合方法组对象
db.collection('test').aggregate()//进行聚合查询
.sort({//聚合阶段。根据指定的字段,对输入的文档进行排序
score: 1,//从小到大
age: -1//从大到小
})
.group({//分组设定
_id: '$age',// 按 age 字段分组
// 每组有一个 avgSales 字段,其值是组内所有记录的 sales 字段的平均值
avgSales: $.avg('$sales'),//对sales字段进行求平均值操作,返回为avgSales
sumPeople: $.sum(1),//统计总数量
first:$.first('$score')//第一个分数,从小到大所以是最低分
last:$.last('$score')//最后一个分数,从小到大所以是最高分
})
.limit(20)//默认统计完后返回前20条数据
.end()//结束聚合返回结果
联表查询
1、基本结构
代码语言:javascript复制const $ = db.command.aggregate//获取聚合方法组对象
lookup({//单条件查询
from: <要连接的集合名>,
localField: <输入记录的要进行相等匹配的字段>,
foreignField: <被连接集合的要进行相等匹配的字段>,
as: <输出的数组字段名>
})
//这样,查询出来的被链接的对象就是一个数组
2、示例
代码语言:javascript复制db.collection('test').lookup({//单条件查询
from: 'test2',//连接test2表
localField: 'a',//test1表的a字段
foreignField: 'b',//连接test2表的b字段
as: 'test2List'//关联到的test2表的集合
})
//查询结果的结构大概是这样
[
{
...,//test表的数据
test2List:[{},{}]//这里是关联到的2表的数据列表
},
{
...,//test表的数据
test2List:[{},{}]//这里是关联到的2表的数据列表
},
]
更多详情请查看官方文档
数据库事务说明
当出现事务繁忙的报错时,请检查是否再同一个事务内,是否有并发数据库操作。
总结
- 作为一个懂绝大多数sql语言的前端开发,我觉得其余的都很方便,就查询这块学习成本很高,并且也没有写sql方便,官方文档还不全。所以,对数据查询处理要求比较高的,不是很实用。要联合云控制台的mysql使用。
- 能在前端直接操作数据库真的是太幸福了,真的有很多很简单的场景每次都要和后台进行交接真的是太麻烦了,云数据库算是完美的解决了这个痛点啊!我还记得我以前写过一个公用查询接口,不就是想让后台少点接口嘛。
- 数据储存也好完美啊,数组、对象等各种数据都能直接往里面扔,取出来就可以直接用,真的各种数据转换的问题也解决了!
- 数据更新也很完美啊,sdk提供了好多的直接更新数据的运算方法,都不用取出数据计算好再更新,巨方便的。
- 还是查询,查询这一块真的是我看的时间最长的,最终我还是认为很复杂的那种几十行几百行的查询sql要转换成SDK的写法,我会哭的,对大数据这一块我觉得真的不合适丫。不知道这边用的算法是怎样的,联表查询什么的性能怎么样,后续再研究吧。