uniCloud 云数据库(万字长文带你通关-入门~冲冲冲)

云数据库学习🛵🛵🛵上车

1:云数据库入门,基本概念了解💕

1.1 云数据库是关系型还是Nosql?

uniCloud提供了一个 JSON 格式的文档型数据库。顾名思义,数据库中的每条记录都是一个 JSON 格式的文档,它是 nosql
非关系型数据库。

1.2 uniCloud 云数据库和关系型数据库的对比

关系型JSON 文档型
数据库 database数据库 database
表 table集合 collection。但行业里也经常称之为“表”。无需特意区分
行 row记录 record / doc
字段 column / field字段 field
使用sql语法操作使用MongoDB语法或jql语法操作

一个uniCloud服务空间,有且只有一个数据库,这一点和关系型数据库还是有区别的。像mysql和sqlserver 都是多数据库可以创建.

1.3 官方文档传送门

传送门

2: 基本操作表 创建 && CRUD💕

2.1: 创建表的三种方式

1:在uniCloud web控制台 进行创建

🚗🚗🚗🚗🚗🚗🚗

在uniCloud web控制台 进行创建,传送门

在这里插入图片描述

2:在项目根目录/uniCloud/database

在项目根目录/uniCloud/database点右键新建schema,如果没有database自行创建,如果是最新版本,默认是有这个文件夹。
在这里插入图片描述
创建好右击表名.schema.json点击上传
在这里插入图片描述
在控制台查看刚才创建好的表:
在这里插入图片描述

3:在代码中创建表(不是很推荐)

在代码中也可以创建表,官方不是很推荐这种创建方式了解即可,有兴趣的可以自行学习,这里只给出阿里云服务空间的创建方式

  • 阿里云

调用add方法,给某数据表新增数据记录时,如果该数据表不存在,会自动创建该数据表。如下代码给table1数据表新增了一条数据,如果table1不存在,会自动创建。
const db = uniCloud.database();
db.collection(“table1”).add({name: ‘Ben’})

官方学习链接

2.2:在项目根目录创建关联表练习💖

创建`user`表和`articles`文章表练习,其中`articles`表中关联`user` 表ID

1:user 表结构

{
	"bsonType": "object", 
	"required": [],
	"permission": {
		"read": false,
		"create": false,
		"update": false,
		"delete": false
	},
	"properties": {
		"_id": {
			"description": "ID,系统自动生成"
		},
		"username": {
			"bsonType": "string",
			"title": "用户名",
			"description": "用户名,不允许重复",
			"trim": "both"
		},
		"password": {
			"bsonType": "password",
			"title": "密码",
			"description": "密码,加密存储",
			"trim": "both"
		}
	}
}

2: articles 表结构

{
	"bsonType": "object",
	"required": [],
	"permission": {
		"read": true,
		"create": true,
		"update": true,
		"delete": true
	},
	"properties": {
		"_id": {
			"description": "ID,系统自动生成"
		},
		"user_id": {
			"bsonType": "string",
			"description": "文章作者ID, 参考`user` 表",
			"foreignKey": "user._id"
		},
		"title": {
			"bsonType": "string",
			"title": "标题",
			"description": "标题",
			"label": "标题",
			"trim": "both"
		},
		"content": {
			"bsonType": "string",
			"title": "文章内容",
			"description": "文章内容",
			"label": "文章内容",
			"trim": "right"
		}
	}
}

其中 articles 表中的user_id是关联user表中的ID,如果是后端数字MySQL的可能知道两表查询是有 join
leftjoin 等关联查询,在云数据库里面是没有的,通过foreignKey 属性就可以定义关联关系。

创建好之后根据上面创建表的第二种方式上传到uniCloud 控制台。

3:上述表结构属性分析

基本表结构

{
	"bsonType": "object", // 固定节点
	"description": "该表的描述",
	 "permission": {
	    "read": true, // 任何用户都可以读
	    "create": false, // 禁止新增数据记录(admin权限用户不受限)
	    "update": false, // 禁止更新数据(admin权限用户不受限)
	    "delete": false, // 禁止删除数据(admin权限用户不受限)
	    "count": false // 禁止查询数据条数(admin权限用户不受限),新增于HBuilderX 3.1.0
  	},
	"required": [], // 必填字段列表
	"properties": { // 该表的字段清单
		"_id": { // 字段名称,每个表都会带有_id字段
			"description": "ID,系统自动生成"
			// 这里还有很多字段属性可以设置
		},
		"field2": { // 字段2,每个表都会带有_id字段
			"description": ""
			// 这里还有很多字段属性可以设置
			"foreignKey":""//关联表
		}
	}
}

具体可参考官方文档表结构属性参考

2.3:JQL描述(操作数据库的语法)💖

  • JQL,全称 javascript query language,是一种js方式操作数据库的规范
  • JQL大幅降低了js工程师操作数据库的难度,比SQL和传统MongoDB API更清晰、易掌握
  • JQL支持强大的DB Schema,内置数据规则和权限。DB Schema 支持uni-id,可直接使用其角色和权限。无需再开发各种数据合法性校验和鉴权代码
  • QL利用json数据库的嵌套特点,极大的简化了联表查询和树查询的复杂度,并支持更加灵活的虚拟表

1:几种场景使用JQL

  • 客户端clientDB,包括js内以及unicloud-db组件内
  • HBuilderX JQL数据库管理器
  • 启用了jql扩展的云函数

更多请参考文档:

以下操作数据使用第二种方式在database 里面会有一个JQL查询.jql 在里面执行就可以
在这里插入图片描述

2.4:添加数据 add()方法💖

1:user 表添加一条数据

写好语句之后全选右击执行即可

db.collection('user').add({
	username:'李四',
	password:'123456'
});

在这里插入图片描述

成功之后会返回一个ID

2:user 表添加多条数据

db.collection('user').add([
	{
		username:'王五',
		password:'123456'
	},
	{
		username:'赵六',
		password:'123456'
	}
]);

成功之后:
在这里插入图片描述

3: articles 表添加数据(单条多条同上,注意)

db.collection('articles').add({
	user_id:'65814f6f652341901b75d140',//需要注意user_id 是上面添加返回的ID
	title:'西游记',
	content:'猪八戒打孙悟空'
});

4:添加数据响应格式

// 添加一条记录成功之后响应的数据格式(其实返回的比官方给的文档多):

{
	errCode: 0,
	errMsg: '',
	id: '' // 新增数据的id
}
//多条记录添加之后返回响应的数据格式:
{
	errCode: 0,
	errMsg: '',
	ids: [], // 新增数据的id列表
	inserted: 3 // 新增成功的条数
}

``

2.5: 删除数据的两种方式 remove()💖

1: 通过指定ID删除 doc(id).remove()

//删除user表 id等于65815902e0ec19b5049cf812 的数据

db.collection('user').doc('65815902e0ec19b5049cf812').remove() 

2: 条件查找之后删除 where().remove()

//删除user 表 username=王五 的数据

db.collection('user').where({
username:"王五"
}).remove()

3: 删除数据返回响应格式

{
	errCode: 0,
	errMsg: '',
	deleted: 1 // 删除的条数
}

2.6 :更新数据 update()💖

1:使用doc(id).update()

//更新user表 id等于 6581582ef082105ea4d87127 的数据

db.collection('user').doc('6581582ef082105ea4d87127')
	.update({
		username: "李四1"
	})

2: 使用where(条件).update()

//更新user表 id等于 6581582ef082105ea4d87127 的数据

db.collection('user').where({
		_id: '6581582ef082105ea4d87127'
	})
	.update({
		username: "李四2"
	})

3: 更新数组类型通过集合下标进行更新(注意jql是没有这个语法的)

参考:云函数传统方式操作数据库
在这里插入图片描述

//articles 增加数组类型字段
"type":{
			"bsonType": "array",
			"title": "类型"
		}
//添加数据
db.collection('articles').add({
	user_id: '65814f6f652341901b75d140',
	title: '西游记',
	content: '猪八戒打孙悟空',
	type:['a','b']
});

在控制台查看结果:
在这里插入图片描述
修改type 字段的数据:

	//这块代码写在云对象方法中进行调用

	const db = uniCloud.database();
	const collection = db.collection('articles');
		let res = await collection.doc('658239f655b337cfad67fd84').update({
				arr: {
					1: "uniCloud"
				}
			}).then((res) => {
				return {
					mess: res.deleted
				}
			})
			.catch((err) => {
				return {
					mess: 'err'.err.message
				}
			})

在这里插入图片描述

4:更新数据响应的格式

{
	errCode: 0,
	errMsg: '',
	updated: 1 // 更新的条数,数据更新前后无变化则更新条数为0
}

2.7: 查询数据(重要)🍭

1:查询条件预览

运算符说明示例示例解释(集合查询)
==等于name == 'abc'查询name属性为abc的记录,左侧为数据库字段
!=不等于name != 'abc'查询name属性不为abc的记录,左侧为数据库字段
>大于age>10查询条件的 age 属性大于 10,左侧为数据库字段
>=大于等于age>=10查询条件的 age 属性大于等于 10,左侧为数据库字段
<小于age<10查询条件的 age 属性小于 10,左侧为数据库字段
<=小于等于age<=10查询条件的 age 属性小于等于 10,左侧为数据库字段
in存在在数组中status in ['a','b']查询条件的 status 是['a','b']中的一个,左侧为数据库字段
!(xx in [])在数组中不存在!(status in ['a','b'])查询条件的 status 不是['a','b']中的任何一个
&&uid == auth.uid && age > 10查询记录uid属性 为 当前用户uid 并且查询条件的 age 属性大于 10
||uid == auth.uid||age>10查询记录uid属性 为 当前用户uid 或者查询条件的 age 属性大于 10
test正则校验/abc/.test(content)查询 content字段内包含 abc 的记录。可用于替代sql中的like。还可以写更多正则实现更复杂的功能

2:User 表批量添加测试数据

db.collection('user').add([{
		username: '王五',
		password: '123456'
	},
	{
		username: '赵六',
		password: '123456'
	},
	{
		username: '孙悟空',
		password: '123456'
	},
	{
		username: '猪八戒',
		password: '123456'
	},
	{
		username: '小猪佩奇',
		password: '123456'
	},
	{
		username: 'GGboy',
		password: '123456'
	}
]);

3:单表查询💕

3.1:查询全部数据 get()
db.collection('user').get()
3.2: 带查询条件 where()
//查询 username 等于zhangsan
db.collection('user').where({
		username:'zhangsan',
	}).get()
// 查询 username 等于zhangsan 和猪八戒
	db.collection('user')
	.where("username in ['zhangsan','猪八戒']").get()
//查询 username 等于zhangsan 或者_id==65814f6f652341901b75d140
	db.collection('user')
	.where("username=='zhangsan' || _id=='65814f6f652341901b75d140'").get()
//查询 username 等于zhangsan 并且_id==65814f6f652341901b75d140
	db.collection('user')
	.where("username=='zhangsan' && _id=='65814f6f652341901b75d140'").get()
//正则匹配 username 里面包含李四的数据
	db.collection('user')
	.where("/李四/.test(username)").get()
3.3:运算方式查询

请添加图片描述

比如有个test 表 数据格式如下
运算方法参考【点击上车🏎️】

{
  "_id": "1",
  "name": "n1",
  "chinese": 60, // 语文
  "math": 60 // 数学
}
{
  "_id": "2",
  "name": "n2",
  "chinese": 60,
  "math": 70
}
{
  "_id": "3",
  "name": "n3",
  "chinese": 100,
  "math": 90
}

//筛选语文数学总分大于150的数据
const db = uniCloud.database()
const res = await db.collection('test')
.where('add(chinese,math) > 150')
.get()

// 返回结果如下
res = {
  result: {
    data: [{
      "_id": "3",
      "name": "n3",
      "chinese": 100,
      "math": 90
    }]
  }
}

3.4:分页查询 skip()+limit()
  • skip 跳过前多少条
  • limit 获得多少条

limit不设置的情况下默认返回100条数据;设置limit有最大值,腾讯云限制为最大1000条,阿里云限制为最大1000条。

// 跳过前面两条返回一条数据
	db.collection('user').skip(2).limit(1).get()
//只返回一条数据
db.collection('user').limit(1).get()
3.5:只查询指定字段 field()
//只返回username 字段
	db.collection('user').field('username').get()

🤠复杂嵌套json数据过滤

如果数据库里的数据结构是嵌套json,比如book表有个价格字段,包括普通价格和vip用户价格,数据如下:

{
  "_id": "1",
  "title": "西游记",
  "author": "吴承恩",
  "price":{
	  "normal":10,
	  "vip":8
  }
}

那么使用db.collection(‘book’).field(“price.vip”).get(),就可以只返回vip价格,而不返回普通价格。查询结果如下

{
  "_id": "1",
  "price":{
	  "vip":8
  }
}

3.6:字段别名 as
//返回字段名不再是username 而是 username1
	db.collection('user').field('username as username1').get()
3.7: 对查询的数据进行排序 orderby()

orderBy每个字段可以指定 asc(升序)、desc(降序)。默认是升序

//根据名称进行升序	db.collection('user').field('username').orderBy('username asc').get()
3.8: 对查询的数据分组 groupby()和 groupField()
  1. groupby 对某个字段进行分组
  2. groupField 里面对file 字段的操作,注意groupField里不能直接写field字段,只能使用分组运算方法来处理字段,常见的累积器计算符包括:count(*)、sum(字段名称)、avg(字段名称)

如果数据库score表为某次比赛统计的分数数据,每条记录为一个学生的分数。学生有所在的年级(grade)、班级(class)、姓名(name)、分数(score)等字段属性 结构如下:

{
  _id: "1",
  grade: "1",
  class: "A",
  name: "zhao",
  score: 5
}
{
  _id: "2",
  grade: "1",
  class: "A",
  name: "qian",
  score: 15
}
{
  _id: "3",
  grade: "1",
  class: "B",
  name: "li",
  score: 15
}
{
  _id: "4",
  grade: "1",
  class: "B",
  name: "zhou",
  score: 25
}
{
  _id: "5",
  grade: "2",
  class: "A",
  name: "wu",
  score: 25
}
{
  _id: "6",
  grade: "2",
  class: "A",
  name: "zheng",
  score: 35
}

使用sum方法可以对数据进行求和统计:

const res = await db.collection('score')
.groupBy('grade,class')
.groupField('sum(score) as totalScore')
.get()

返回结果如下:

{
  data: [{
    grade: "1",
    class: "A",
    totalScore: 20
  },{
    grade: "1",
    class: "B",
    totalScore: 40
  },{
    grade: "2",
    class: "A",
    totalScore: 60
  }]
}

3.9:数据去重distinct()

如果数据库score表为某次比赛统计的分数数据,每条记录为一个学生的分数

{
  _id: "1",
  grade: "1",
  class: "A",
  name: "zhao",
  score: 5
}
{
  _id: "2",
  grade: "1",
  class: "A",
  name: "qian",
  score: 15
}
{
  _id: "3",
  grade: "1",
  class: "B",
  name: "li",
  score: 15
}
{
  _id: "4",
  grade: "1",
  class: "B",
  name: "zhou",
  score: 25
}
{
  _id: "5",
  grade: "2",
  class: "A",
  name: "wu",
  score: 25
}
{
  _id: "6",
  grade: "2",
  class: "A",
  name: "zheng",
  score: 35
}

按照grade、class两字段去重,获取所有参赛班级

const res = await db.collection('score')
.field('grade,class')
.distinct() // 注意distinct方法没有参数
.get()

{
  data: [{
    grade:"1",
    class: "A"
  },{
    grade:"1",
    class: "B"
  },{
    grade:"2",
    class: "A"
  }]
}

3.10: getone() 和 getcount()
  • getone 在get方法内传入参数getOne:true来返回一条数据,getOne其实等价于上一节的limit(1)
  • getcount 根据条件查询到的count
    
//添加     getcount db.collection('user').field('username').limit(1).get({
		getCount:true
	})

只返回一条数据 limit 控制,但是查询出来的count 有8条,如果不加getCount 返回结果是没有这个字段的
在这里插入图片描述

//添加 getOne 就返回一条跟limit(1)效果一样
db.collection('user').field('username').get({
		getOne:true
	})

4:联表查询 ,下面没了,别慌💕

4.1:基本的操作
  • 临时表:getTemp方法返回的结果,例:const articles=
    db.collection(‘articles’).getTemp(),此处 articles就是一个临时表
  • 虚拟联表:主表与副表联表产生的表,例:db.collection(user, ‘articles’).get()
    // user 和 articles 联表
	const user=db.collection('user').getTemp()
	const articles=db.collection('articles').getTemp()
	db.collection(user, articles).get()

返回数据如下:

在这里插入图片描述

4.1:优化上面的查询
    // user 和 articles 联表,但是user 表可以指定where 查询某个数据
	const user=db.collection('user').where("_id=='65814f6f652341901b75d140'").getTemp()
	const articles=db.collection('articles').getTemp()
	db.collection(user, articles).get()

4.3:临时表可以使用的方法
where
field // 关于field的使用限制见下方说明
orderBy
skip
limit

5:查询返回的数据格式🐳

查询数据

{
	errCode: 0,
	errMsg: '',
	data: []
}

批量发送数据库查询请求

{
	errCode: 0,
	errMsg: '',
	dataList: [] // dataList内每一项都是一个查询数据的响应结果 {errCode: 0, errMsg: '', data: []}
}

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃橘子的汤圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值