简单SQL查询 在野狗中的对应实现
发布于 9 年前 作者 ye123456 3330 次浏览 最后一次编辑是 8 年前 来自 分享

SQL2.png

野狗实时后端云主要提供的是一个实时通信的通道,但是毕竟也提供了数据存储的功能。因此野狗也可以被看作是一个具有实时同步数据功能的云端数据库。

这个数据库是NoSQL的,数据的存储是树型的,类似一个巨大的JSON,而不是关系型的二维表结构。对于有SQL技术背景的用户来说,使用野狗需要一个思维转换的过程。需要注意的是,虽然今天我们来讨论一些常见的SQL查询在野狗中如何对应的实现,我们仍然不建议待着关系型数据库的思维使用野狗云。

我们将会讨论如下几种查询:

  • 根据一个用户的id查询用户(WHERE id = x)
  • 根据email查询用户(WHERE email = x)
  • 查询昨天发表的消息(WHERE time BETWEEN x AND y)
  • 排序取x条(ORDER BY time LIMIT x)
  • 通过id字段关联查询(FROM table1 JOIN table2 USING id)

我们同样以JavaScript为例,Android和iOS平台类似。本文中所讲述的内容严重依赖于下列API的正确理解和使用,对这些API还不了解的用户,请参考API文档( https://z.wilddog.com/web/api):

  • orderByChild:按照指定子节点的值排序。
  • startAt:查询值范围的起点。如果没有明确的指定orderBy属性,则默认按照数据的priority排序。
  • endAT:与startAt对应,查询值范围的结束点。
  • limitToFirst/limitToLast:返回多少条数据记录,相当与sql中的limit。

根据一个用户的id查询用户(WHERE id = x)

根据id查询用户,这是最基础的查询。在野狗中,所有的数据都拥有一个唯一的URL,数据是存储在一个path路径下的,path中的字段名key即可被认为是记录的主键id。例如我们在/user路径下存储了每个用户的信息:

数据中的123,234,345,456就是四条记录的id。那么当根据id查询user的时候,我们只需要使用数据的URL进行查询:

var ref = new Wilddog(“https://.wilddogio.com/user/2”);

ref.once(‘value’, function(snapshot) {

console.log(‘I fetched a user!’, snapshot.val());

});

根据email查询用户(WHERE email = x)

使用id对数据进行查询是很简单的,因为id已经在数据的URL中。如果我们要查询的字段不再URL中呢?我们查找email为zhangsan@wilddog.com的用户,需要结合使用orderByChild()方法和startAt()和endAt()方法:

var ref = new Wilddog(“https://<appId>.wilddogio.com/user”);

ref.orderByChild(‘email’)

.startAt(‘zhangsan@wilddog.com’)

.endAt(‘zhangsan@wilddog.com’)

.once(‘value’, function(snapshot) {

console.log(‘accounts matching:’, snapshot.val())

});

查询昨天发表的消息(WHERE time BETWEEN x AND y)

假设数据结构如下:

要对time字段进行范围查询,同样结合使用orderByChild()方法和startAt()和endAt()方法:

ref.orderByChild(‘time’)

.startAt(startTime)

.endAt(endTime)

.once(‘value’, function(snapshot) {

console.log('messages found : ', snapshot.val())

});

排序取x条(ORDER BY time LIMIT x)

假设每个用户都有一个age字段,要按age排序,查询年龄最小的两个user,可以构造如下的查询:

var ref = new Wilddog(“https://<appId>.wilddogio.com”);

ref.child(‘user’).orderByChild(‘age’).limitToFirst(2).on(‘child_added’, function(userSnap) {

console.log('find user : ’ + JSON.stringify(userSnap.val()));

});

如果要取年龄最大的2个user,将limitToFirst(2)改为limitToLast(2)即可。

通过id字段关联查询(FROM table1 JOIN table2 USING id)

有时候我们出于查询性能的考虑,为了避免一次从云端传输太大的数据量,我们将一部分数据拆分出去存储在另外的数据路径下。假设我们的每位user都有自己的media属性,而我们将media属性拆分出去存储,数据如下:

这时候可能需要在查询的时候进行一个类似关系数据库中的JOIN查询:

var ref = new Wilddog(“https://<appId>.wilddogio.com”);

ref.child(‘user/123’).once(‘value’, function(userSnap) {

ref.child(‘media/123’).once(‘value’, function(mediaSnap) {

console.log(‘user:’ + userSnap.val().name + ', media : ’ + mediaSnap.val().weibo);

});

});

如果不是指定id为123的用户,而是查询所有的用户:

var ref = new Wilddog(“https://<appId>.wilddogio.com”);

ref.child(‘user’).on(‘child_added’, function(userSnap) {

var id = userSnap.key();

ref.child(‘media’).child(id).once(‘value’, function(mediaSnap) {

console.log(‘user:’ + userSnap.val().name + ', media : ’ + mediaSnap.val().weibo);

});

});

出于性能的考虑,在“关联查询”的时候,应当在“外层查询”使用startAt(),endAt()等方法增加筛选条件,只对较少数据量进行“内层查询”。野狗为实时进行了许多优化,只要数据量不是太大,实时性和性能就不用太担心。

本文中我们讲述了一些最简单和基础的查询,更多高级查询和特性我们将在后续的文章中为大家讲述。

qrcode_for_gh_55dcc2c31752_258 (2).jpg 关注野狗官方微信,获取更多技术干货

1 回复

有 mongoose 的感觉

回到顶部