平台支持两种内部数据库:文档型数据库MongoDB、关系型数据库PostgreSQL。
接下来几章讲述的是基于MongoDB查询语言MQL的数据操作API,它在操作JSON数据方面强大而又易用。
这些API也适用于内部PostgreSQL,支持常用的MQL关键字,不支持的关键字请查阅文档;内部PostgreSQL还支持后端用pg(sql, values)
直接执行SQL。
平台不直接管理外部数据库,得靠开发者写SQL来管理数据。
内部数据库有5个供用户直接使用的集合/表:product
产品表user
用户表resource
资源表,存放用户上传的图片、视频、文件order
订单表xdb
通用表,不能归类到上表的才存入此表
使用这些表时我们都以$
打头,比如用$product.get(_id)
或$product.name("db_outline")
来获取正在阅读的这篇文档。
$me
:当用户在user
表操作自己的用户信息时,我们使用$me
可以使操作更加便捷。$xtk
:同样的道理,由于xdb
表必然有type
和key
两个字段,我们可以据此用$xtk
直接操作xdb
表而避免使用难记的_id
每条记录都有一个唯一ID,即_id
。
它是24位的16进制字符串,可以用isId()
来判断一个字符串是否是有效ID。
它前8位代表创建该记录时的时间(精确到秒),可以用date()
把_id
转换成时间。还可以用_id()
通过一个时间来构建符合格式的_id
,以此来搜索数据库。
数据库操作返回的数据都会放入$c
对应的表名下面,比如通过$c.product[_id].x.title可以拿到标题。
第一个参数是path的API会把返回结果放入$c.x
指定的path下,search返回的arr
是指搜到的数组,平台会把多次的搜索得到的数组合并到all
里。
特别地,当前登录用户数据除了放入$c.user还会放入$c.me
。
同理,xdb的数据也会根据其type和key放入$c.xtk
中。
在编辑模式下我们可以在开发者工具的控制台上用log($c)
把所有数据打印出来。
新的数据库操作会影响原先获得的数据:
get()、modify()、search()返回的数据会合并到对应的旧数据中。例如$proudct.modify(_id, {…})会更新$c.proudct[_id],如果先前做过搜索$proudct.search(“A.B”, {…})那也会更新$c.x.A.B.arr和$c.x.A.B.all里对应的数据。
delete会删除对应的旧数据,也会删除search返回数组中的对应数据。比如先搜索然后马上把返回的数组依次删除:$c.x[path].arr.forEach(‘$proudct.delete($x._id)’)会有不稳定问题,因为每删除一次都会删除数组里的对应数据项从而改变数组长度,把数组先克隆再循环就没问题了:$c.x[path].arr.clone().forEach(‘$proudct.delete($x._id)’)。
接口调用需要花费时间、网络、服务器和数据库资源,平台是据此来收取流量费的,我们应尽量减少接口调用的次数和频次,不做无谓的消耗。
在浏览器端平台会自动缓存从服务器获取的资源,以最大限度节省流量费。当一个接口已被缓存后再次以完全一样的参数调用时平台将直接从浏览器缓存读取而跳过接口调用,如果想再次从服务器端获取数据可以传入0
作为cache
参数,表示不要缓存。cache也可以传入大于0的小时数(范围:0.1 ~ 5)来指示服务器把查询的结果缓存起来,(其他用户的)在这个缓存时间内以完全一样的参数调用此接口就可以直接从缓存中读取,从而大大提高查询速度。
总结:默认(无cache参数时)仅浏览器端缓存,cache为0时都不缓存,大于0时服务器端缓存(浏览器当然也缓存)。
一个接口请求发出去需要一段数据才能从服务器端返回来,所以应该避免在极短的时间内多次触发完全相同的接口(接口名、参数数量和参数值都相同)。为此平台会自动跳过3秒内触发的完全相同的接口,而等待最近触发的接口返回后才继续执行后续表达式。
可以通过clearCache(path)
清除前端缓存,$api.clearCache(path)
清除服务器端缓存。
传入path只清除指定路径的缓存,未传入则会清除所有缓存(由数据库search,count,distinct,aggregate接口留下的缓存)。
相关联的数据是嵌套存储在同一条数据里还是分表存储到不同类型的数据里呢?
通常无需单独拎出来查询的、信息量少的、记录条数有限的数据才适合嵌套,否则就应该分表存储。
比如简历中的工作经历列表就可以嵌套,因为一个人的工作经历数量较少、且不会出现单独查工作经历而不查人的情况。再比如会计凭证中的分录也可以嵌套,每个凭证都有至少一个借和一个贷分录,但总量不会太多。
而一个用户发布的文章就不应该嵌套的用户表中,一篇文章的评论也不应该嵌套的文章表里,因为文章/评论需要单独查询,而且它们的数量也难以估量。
对于一个严肃的应用,加强数据安全控制是值得高度重视的。虽然在每个应用在创建时都预设了基础安全控制,但还是远远不够的。请到接口安全文档中学习。