Firebase数据库结构

时间:2016-12-21 17:28:34

标签: database firebase firebase-realtime-database nosql

我刚开始尝试使用Firebase。当你习惯了关系数据库时,它真的很棒!

我正在尝试设计一个应用程序,允许用户通过条形码或名称搜索膳食并检索卡路里数量。此外,我需要能够存储用户食用的食物,并最终每天,每周或每月检索用户食用的食物。

我认为每餐都有一个唯一的ID(例如M1234 for Pizza),然后我有2个查找部分 - 一个是条形码,一个是名字,所以应该有希望覆盖搜索功能。

每个用户都会按照日期在吃完的“表格”中存储食物(Firebase数据库中“表格”的正确用语是什么?),只是按照ID来参考用餐。

这就是我设计数据库的方式。

  {
// Here are the users.
    "users": {
      "mchen": {
        "name": "Mary Chen",
        "email": "mary@chen.com",

        }
      },
      ...
    },
// Here are the meals eaten by date.
    "eaten": {
      "mchen": {
         // index Mary's meals in her profile /eaten/mchen/meals/20161217 should return 'M1234' (pizza) and 'M8765' (chips)
        "meals": {
          "20161217": {
             "M1234": true,
             "M8765": true
          },
          "20161218": {
             "M2222": true,
             "M8765": true
          }
      },
      ...
    },
// Here are the meals with calorie information.
    "meals": {
      "M1234": {
        "name": "Pizza"
        "calories": 400
      },
      "M2222": {
        "name": "Curry"
        "calories": 250
      },
      "M8765": {
        "name": "Chips"
        "calories": 100
      },
    },
// Here is the barcode lookup
    "barcode-lookup": {
      "12345678": {
        "id": "M1234"
      },
      "87654321": {
        "id": "M2222"
      },
      "11223344": {
        "id": "M8765"
      }
    },
// Here is the name lookup
    "name-lookup": {
      "Chips": {
        "id": "M8765"
      },
      "Pizza": {
        "id": "M1234"
      },
      "Curry": {
        "id": "M2222"
      }
    }

  }

看起来合理还是有明显的缺陷?

2 个答案:

答案 0 :(得分:1)

结构看起来很好(虽然我会让firebase生成id)。唯一不会像你期望的那样工作的是搜索。根据您的数据,如果我搜索pizza,您将无法编写将返回Pizza条目的查询。我的建议是使用Algolia(或类似的东西)进行搜索或使用您的名称lowerCased滚动另一个密钥,以使查询可以工作。运行自己的唯一问题是,您将无法搜索izz之类的内容并让Pizza出现。有关如何进行搜索,请参阅我的回答Firebase - How can I filter similarly to equalTo() but instead check if it contains the value?

答案 1 :(得分:1)

您需要利用.childByAutoId()并让Firebase创建父键名称。最佳做法是将您的子数据与父节点取消关联,并允许Firebase创建随机的'父母的关键是这样做。

除此之外,通常创建/ users节点,每个用户的父节点将是Firebase在首次创建用户时创建的uid。

在您的原始结构中,我已经将条形码和名称查找整合到以下结构中以降低复杂性。

dining
  -Yuiia09skjspo
    dining_timestamp: "20161207113010"
    Y79joa90ksss: true
    Yjs9990kokod: true
    user: uid_0
    uid_timestamp: "uid_0_ 20161207113010"
  -Yi9sjmsospkos
    dining_timestamp: "20161207173000"
    Y79joa90ksss: true
    Yjs9990kokod: true
    user: uid_1
    uid_timestamp: "uid_1_ 20161207173000"

然后用餐

meal
  -Y79joa90ksss
    name: "Pizza"
    calories: "400"
    barcode: "008481816164"
  -Yjs9990kokod
    name: "Burger"
    calories: "520"
    barcode: "991994411815"

以及用户可以选择的膳食

All dining for all users by date or range of dates.
All dining that contain a certain meal
All meals by a user
->The cool one<- all dining for a specific user within a date range.

如您所见,用餐节点包含每个用户的用餐活动(因此所有用餐活动都在一个节点中)

这使您可以查询各种事物:

       setInterval(function() {

            var token = $window.localStorage.getItem('token');
            self.parseJwt = function(token) {
                var base64Url = token.split('.')[1];
                var base64 = base64Url.replace('-', '+').replace('_', '/');
                return JSON.parse($window.atob(base64));
            }
            var expireTime = self.parseJwt(token);
            var timeStamp = Math.floor(Date.now() / 1000);
            var timeCheck = expireTime.exp - timeStamp;


            //Set to expire after 15 seconds
            if (timeCheck < 86385) {
                console.log('time expired');
            } else {
                console.log('time not expired');
            }


        }, 3000);

一个遗漏是寻找包含两餐的餐饮,但是,解决方案也是在这个答案中。

总而言之,你的结构很健全 - 只需要稍微调整一下。