Firebase结构:平坦和不对称或突破

时间:2014-05-05 19:27:14

标签: firebase

我希望将Firebase(和AngularJS)用于包含不同类型活动的音乐节网站。我是分层次设计数据结构的新手,并已阅读Stackoverflow和firebase博客上的许多引用,这些都有助于引导我解决这个问题。

这个音乐节有音乐活动,电影活动,讲座活动等,所有这些都有一些重叠的属性(名称,日期,描述),但也有不同的属性,具体取决于事件类型。根据我在Firebase中构建数据的知识,我到目前为止考虑了两个模型:

模型1 - 扁平和不对称:

ROOT
|
+--EVENTS
    |
    +-- EventID_1
    |    |-- EventType: "Music"
    |    |-- Name: "The Beatles"
    |    |-- Description: "Description goes here."
    |    |-- Date: "2012-04-23T18:25:43.511Z"
    |    |-- Mp3Url: "http://some.music.url"
    |    |-- OtherMusicOnlyAttrib: "..."
    |
    +-- EventID_2
    |    |-- EventType: "Movie"
    |    |-- Name: "A Light That Never Goes Out"
    |    |-- Description: "Description goes here."
    |    |-- Date: "2012-04-23T18:25:43.511Z"
    |    |-- YouTubePreview: "http://youtube.com/somevideo"
    |    |-- OtherMovieOnlyAttrib: "..."
    |
    +-- EventID_3
        |-- EventType: "Lecture"
        |-- Name: "Cornelius Northshire"
        |-- Description: "Summary of lecture topic."
        |-- Date: "2012-04-23T18:25:43.511Z"
        |-- Bio: "Biography of lecturer."
        |-- OtherLectureOnlyAttrib: "..."

好处:此结构明显且直接的好处是所有事件都位于一个Firebase网址上。创建一次列出所有事件的主计划视图非常简单。然后我可以通过EventType在客户端过滤仅用于音乐的视图,或者如果用户希望仅在主时间表上看到音乐或仅看电影。

缺点:拥有不对称模型感觉不对劲。我也关注客户端过滤的速度,因为可能会有大约500个条目,但也许它不会成为问题。

模型2 - 分解:

ROOT
|
+-- EVENTS
     |
     +-- MUSIC
     |    |
     |    +-- MusicEventID_1
     |         |
     |         |-- Name: "The Beatles"
     |         |-- Description: "Description goes here."
     |         |-- Date: "2012-04-23T18:25:43.511Z"
     |         |-- Mp3Url: "http://some.music.url"
     |         |-- OtherMusicAttrib: "..."
     |
     +-- MOVIES
     |    |
     |    +-- MovieEventID_1
     |         |
     |         |-- Name: "A Light That Never Goes Out"
     |         |-- Description: "Description goes here."
     |         |-- Date: "2012-04-23T18:25:43.511Z"
     |         |-- YouTubePreview: "http://youtube.com/somevideo"
     |         |-- OtherMovieAttrib: "..."
     |
     +-- LECTURES
          |
          +-- LectureEventID_1
               |
               |-- Name: "Cornelius Northshire"
               |-- Description: "Summary of lecture topic."
               |-- Date: "2012-04-23T18:25:43.511Z"
               |-- Bio: "Biography of lecturer."
               |-- OtherLectureAttrib: "..."

好处:每种事件类型都有自己的Firebase网址。因此,对于仅音乐视图的客户端事件过滤将是不必要的。此外,每个事件模型对于每个项目都是一致的,这可以使显示事件详细信息视图更容易。

缺点:列出所有事件类型(可能)的主计划视图变得更加困难。我不熟悉迭代所有事件类型及其子事件的好方法,尽管我确信它是可能的。

结论:

我想在这里学到一些东西。如果有人有关于哪种方式会更好的反馈(并且我对这些更开放,"更好"意味着),我将不胜感激。当然,如果它出现,我也会对第三种选择开放。我希望以后能够阻止自己后悔这个决定。我希望沿着可以最大限度地提高灵活性的道路前进。

2 个答案:

答案 0 :(得分:0)

我没有使用Firebird的经验(我总是在SQL Server上工作),但我认为你问的是一般的数据库设计问题。我会使用你发布的第一个选项的变体。特别是如果您需要列出事件类型。我唯一要改变的是,有一个基表(例如事件),包含所有共享属性(名称,描述,日期,事件类型等等),然后有特定事件类型属性的小表。在这些表上,您需要一个事件ID来与主事件相关联。您可以拥有一个包含事件类型的表,这样您就可以轻松添加新类型的事件。这有点去规范化,因为具有事件特定属性的表只与事件表的子集相关,但在这种情况下(我认为)最好使用这种模式。

我不明白为什么你提到作为回顾关注客户端过滤速度的原因。你不应该这样做。对于过滤器事件,您始终可以调用服务器,过滤并将过滤后的信息重新发送到客户端。

我希望它可以帮助你,让我知道我是否可以帮助你做任何事情。

答案 1 :(得分:0)

鉴于我并不完全了解您的使用案例和需求,并且仅在此处使用仿制药进行讨论,我对方法的首选将是您的平面和不对称的变体。

NoSQL与SQL的不同之处在于它允许创建嵌套层次结构,但是在大多数情况下我坚持使用相当扁平的结构并且正如我希望SQL那样对索引进行索引时,我会很幸运。

示例:

/events/$event_id/ (type, name, etc)
/index/by_type/<music|movies|lectures>/$event_id/true
/index/recent/$event_id/true

对于recent索引,我会按Date优先处理记录,这样我就可以使用recentIndexRef.endAt().limit(10)等内容获取最新的X记录。

要从索引中获取记录列表,我可以执行以下操作:

var fbRef = new Firebase(URL);

function fetchRecentMusic(numberToFetch, callback) {
   var idxRef = fbRef.child('index/by_type/music').limit(numberToFetch);
   idxRef.once('value', function(snap) {
      var results = [];
      snap.forEach(function(ss) {
         results.push(ss.val());
      });
      callback(results);
   });
}

当然,这个主题有很多变种,具体取决于这些数据的实时性以及我希望如何显示它。它还涉及其他几个高级主题,如normalizing records through a cachepagination

一旦我们进入每秒数百次读取/数百万条记录,还需要考虑许多优化措施;此时,在每个索引上存储一些元数据可能会很有用,因此我不必获取读取记录(例如,用true属性替换Name,例如)

希望有所帮助。