【问题标题】:Data structure from MySql to FireBase (NOSQL db)从 MySql 到 FireBase 的数据结构(NOSQL db)
【发布时间】:2018-07-31 08:24:41
【问题描述】:

我已经阅读了大量的教程和 stackoverflow 问答,并开始尝试为 Firebase 设计数据库结构。我试图让它保持平坦(这似乎是一个非常重要的考虑因素)。同时我不知道我将应用于 FireBase 数据库的所有可能的查询(在这篇文章的结尾我给出了一些基本的例子)。因此,我正在寻求已经使用 Firebase 并遇到来自关系数据库的人员的主要问题的人的帮助

给出如下Mysql结构

    TB_USER
    +----+--------+-------------+---------------+-----------------------------+------------------------+------------+
    | id |  name  |     bio     |     link      |           avatar            |         userId         | created_at |
    +----+--------+-------------+---------------+-----------------------------+------------------------+------------+
    |  1 | Fabian | bla...bla.. | www.site.com  | img_on_the_Server.jpg       | StringFromAuthFBGoogle | 20-02-2018 |
    |  2 | Sarah  | bla...bla.. | www.sarah.com | img_on_the_Server_Sarah.jpg | StringFromAuthFBGoogle | 18-02-2018 |
    |  3 | Carl   | bla...bla.. | www.carl.com  | img_on_the_Server_Carl.jpg  | StringFromAuthFBGoogle | 14-02-2018 |
    +----+--------+-------------+---------------+-----------------------------+------------------------+------------+


    TB_JOURNEYS
    +----+----------------------+----------------------+--------+------------+
    | id |     journey_name     |     description      | iduser | created_at |
    +----+----------------------+----------------------+--------+------------+
    | 28 | Traveling to India   | desc of India        |      2 | 21-02-2018 |
    | 34 | A week in China      | desc of China        |      1 | 21-02-2018 |
    | 46 | South America by car | incredible adventure |      3 | 22-02-2018 |
    +----+----------------------+----------------------+--------+------------+


    TB_STAGES
    +----+------------+------------+------------+--------------+------------------------------------------------+-----------------------+-----------------------+
    | id | id_journey |    date    |  latitude  |  longitude   |                      text                      |        picture        |         video         |
    +----+------------+------------+------------+--------------+------------------------------------------------+-----------------------+-----------------------+
    | 10 |         28 | 20-12-2017 | 46.3991665 | -117.0484223 | Fantastic day                                  | image_of_that_day.jpg | video_of_that_day.mp4 |
    | 20 |         28 | 23-12-2017 | 14.6082829 | -90.5528772  | Another beautiful day walking through the city | img_art.jpg           |                       |
    | 30 |         46 | 01-01-2018 | 45.462889  | 9.0376466    | Center of the city                             | pic.jpg               | video.mp4             |
    |    |            |            |            |              |                                                
    |                       |                       |
    +----+------------+------------+------------+--------------+------------------------------------------------+-----------------------+-----------------------+

我想出了这个 FireBase 结构

{
  "users": {
    "1": {
      "name": "Fabian",
      "bio": "bla...bla",
      "link": "www.site.com",
      "avatar": "img_on_the_Server.jpg",
      "userID": "StringFromAuthFBGoogle",
      "created_at": "20-02-2018"
    },
    "2": {
      "name": "Sarah",
      "bio": "bla...bla",
      "link": "www.sarah.com",
      "avatar": "img_on_the_Server_Sarah.jpg",
      "userID": "StringFromAuthFBGoogle",
      "created_at": "18-02-2018"
    },
    "3": {
      "name": "Carl",
      "bio": "bla...bla",
      "link": "www.carl.com",
      "avatar": "img_on_the_Server_Carl.jpg",
      "userID": "StringFromAuthFBGoogle",
      "created_at": "14-02-2018"
    }
  },
  "journeys": {
    "28":{
      "journey_name": "Traveling to India",
      "description": "desc of India ",
      "created_at": "21-02-2018",
      "iduser": 2
    },
    "34": {
      "journey_name": "A week in China ",
      "description": "desc of China ",
      "created_at": "21-02-2018",
      "iduser": 1
    },
    "46":{
      "journey_name": "South America by car",
      "description": "incredible adventure",
      "created_at": "22-02-2018",
      "iduser": 3
    }
  }, 
  "stages": {
    "10": {
      "id_journey": 28,
      "date": "20-12-2017",
      "latitude": "46.3991665",
      "longitude": "-117.0484223",
      "text": "Fantastic day ",
      "picture": "image_of_that_day.jpg",
      "video": "video_of_that_day.mp4"
    },
    "20": {
      "id_journey": 28,
      "date": "23-12-2017",
      "latitude": "14.6082829",
      "longitude": "-90.5528772",
      "text": "Another beautiful day walking through the city",
      "picture": "img_art.jpg"
    },
    "30": {
      "id_journey": 46,
      "date": "01-01-2018",
      "latitude": "45.462889",
      "longitude": "9.0376466",
      "text": "Center of the city",
      "picture": "pic.jpg",
      "video": "video.mp4"
    }
  }

}

真正的问题是我从未使用过 NOSQL 数据库,所以我不知道该结构是否可以回答我们在使用关系数据库时必须回答的基本问题。 在应用程序中,我必须检索属于特定用户的所有旅程,并且肯定我必须检索属于特定旅程的所有阶段。 我将搜索特定用户(按名称搜索)

【问题讨论】:

    标签: android mysql database firebase-realtime-database


    【解决方案1】:

    当然,NoSQL 对于多年使用关系数据库的程序员来说并不容易。但是就像在 self 中的 SQL 一样,您可以在 self 的应用程序中进行大量编程。

    这是一个例子: 您想查找带有“城市中心”的文本。

    SQL

    SELECT * FROM TB_STAGES WHERE text='Center of the city'

    NoSQL

    您必须遍历属性“旅程”中包含的每个对象,并检查文本是否等于您正在搜索的文本。

    这是一个伪代码,如何实现:

    for(i = 0; i < journey.length; i++){
       curr = journey.get(i);
       if(curr.text == search_text){
          //Do what you want
       }
    }
    

    我希望这可能有助于您理解,您始终可以在自己的应用程序/客户端应用程序上解决问题。它并不总是最好的解决方案,但它确实有效。

    【讨论】:

      【解决方案2】:

      看来你是在正确的轨道上:

      • 您意识到这与关系数据库不同。
      • 您已经学会了保持数据结构平坦。

      根据您分享的内容总结了一些经验教训:

      • 您使用数字(通常是连续的)值作为键。为了获得最佳的可扩展性,最好为键使用更多固有的唯一值,例如:

        • 如果您使用 Firebase 身份验证,每个用户都有一个唯一的 UID。由于每个用户只能在/users 下使用一次,将它们存储为/users/$uid 意味着您会自动强制执行此唯一性。
        • 如果项目还没有唯一 ID,请考虑使用 Firebase 的推送 ID。虽然它们不像您使用的“数组索引”那样便于人类阅读,但它们在可扩展性和离线行为方面具有优势,使其更适合在 Firebase 中使用。
      • 对于多对多关系,您可能希望在两个方向上创建“索引节点”:例如从用户到他们所在的旅程,从旅程到在其中的用户。有关更多信息,请在此处查看我的答案:Many to Many relationship in Firebase
      • 一般来说,您最终会为应用程序的用例建模数据。由于您还不知道所有这些(这很正常),因此您还无法确定最终的数据模型。那也很好。随着您发现更多用例,您将扩展/更改您的数据模型。
      • 显示在应用程序屏幕上的模型数据。例如。如果您有一个包含用户名列表的屏幕,请考虑在您的数据库中拥有该用户名列表。当然,您也可以加载用户配置文件并显示名称,但如果您只有名称,您将浪费更少的带宽。
      • 我不能推荐您阅读 NoSQL data modeling 并观看 Firebase for SQL developers,它们是该主题的精彩介绍/入门/大开眼界。

      【讨论】:

      • 嗨弗兰克,根据您的观点,我想澄清一下。使用更本质上唯一的键值的想法,我将使用由 Firebase 生成的“神秘”字符串,因此名称为“Fabian”的用户而不是键 1,它将具有类似于“L50G9QloKwPEvAaerSo”的内容,因此在“中国一周”的旅程中,iduser 将使用刚刚提到的相同字符串“L50G9QloKwPEvAaerSo”。旅程 ID 和阶段的概念相同?
      • 我会通过用户的 UID 对用户进行关键操作。例如StringFromAuthFBGoogle
      • 关于ManyToMany关系,你建议多加2个TopLevelNodes吗? JourneyUser 和 UserJourney? "JourneyUser": { "PijkZ(journey_id)":{ "djoi(Lee_id)": true, "dskj(Lucas_id)": true }, "jfizH(journey_id)":{ "jwij(Alice_id)": true } }, "UserJourney": { "djoi(Lee_id)":{ "PijkZ(journey_id)": true }, "dskj(Lucas_id)":{ "PijkZ(journey_id)": true }, "jwij(Alice_id)":{ "jfizH(journey_id)": true } } 如果我有一对多的关系,TopLevelNode 将只是一个,对吗?
      • 我想介绍的最后一点是关于建模数据,我提前道歉,因为我没有经常使用 Firebase。但是提出了一个问题,假设我已经用数千个“记录”填充了 Firebase 数据库,突然间我意识到我还想创建一些额外的顶级节点来处理一些我没想到的视图。推断已经可用的数据并生成所需的节点有多难?
      • 抱歉,你真的想一次性覆盖太多内容。是的,如果您想在两个方向上导航它们,您将需要两个新的用于多对多关系的顶级集合。这也完全取决于您的应用程序的用例。更改数据结构只是工作,除非您已经达到数百万个节点(在这种情况下:恭喜您的应用成功!)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-14
      • 2019-11-09
      • 1970-01-01
      • 2019-12-06
      • 2011-03-17
      相关资源
      最近更新 更多