2016-12-21 3 views
1

Firebase를 실험하기 시작했습니다. 관계형 데이터베이스에 익숙해지면 진정한 헤드 벤더입니다!Firebase 데이터베이스 구조

사용자가 바코드 또는 이름으로 식사를 검색하고 칼로리 수를 검색 할 수있는 앱을 디자인하려고합니다. 또한, 나는 사용자가 먹은 식사를 저장할 수 있어야하고, 매일 사용자가 먹는 음식을 매일, 주 또는 한 달에 검색 할 수 있어야합니다.

각 식사에는 고유 한 ID (예 : 피자 용 M1234)가 있다고 생각했는데 바코드와 이름별로 2 개의 조회 섹션이 있으므로 검색 기능을 포함해야합니다.

각 사용자는 먹는 '테이블'(Firebase 데이터베이스의 '테이블'에 대한 올바른 용어는 무엇입니까?)에 저장된 식사를 날짜별로 표시하고 ID로 식사를 참조합니다.

데이터베이스를 설계 한 방법입니다.

{ 
// Here are the users. 
    "users": { 
     "mchen": { 
     "name": "Mary Chen", 
     "email": "[email protected]", 

     } 
     }, 
     ... 
    }, 
// 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" 
     } 
    } 

    } 

명백한 결함이 있습니까?

+0

이것은 도움이 될 수 있습니다. [NoSQL 데이터 모델링 기법] (https://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/) – Kato

답변

1

.childByAutoId()를 활용하여 Firebase가 부모 키 이름을 생성하게하는 것이 좋습니다. 부모 노드로부터 자식 데이터의 연결을 해제하고 부모가 해당 작업을 수행 할 수 있도록 Firebase에 '임의의'키를 생성하는 것이 가장 좋습니다.

이와 함께/users 노드를 만드는 것이 일반적이며, 각 사용자의 부모 노드는 사용자가 처음 생성 될 때 Firebase에 의해 생성 된 uid가됩니다.

원래 구조에는 복잡성을 줄이기 위해 다음 구조에 통합 된 바코드 및 이름 조회가 있습니다.

users 
    uid_0 
    name: "Mary Chen", 
    email: "[email protected]" 
    uid_1 
    name: "Larry David" 
    email: "[email protected]" 

다음 식사

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. 

한 가지 누락은 두 번의 식사가 포함 된 식사에 대한 검색이지만 그 해결책도이 대답에 포함됩니다.

모두 구조가 적절합니다. 약간의 조정 만 있으면됩니다.

+0

깊이있는 답변을 주셔서 감사합니다. Jay. 귀하의 구조를 사용하면 바코드 만 알면 식사에 포함 된 칼로리를 빠르게 검색 할 수 있습니까? 죄송합니다. 어리석은 질문이라면 - AngularJS를 사용하여이 앱을 작성하려고하지만 아직 실제로 할 수있는 것에 대해서는별로 이해하지 못했습니다. 데이터베이스 디자인을 시도하는 것이 가장 좋습니다. – Damian

+0

@Damian 나는 올바른 방향으로 가고 있다고 생각합니다! 이름 노드, 칼로리 노드 또는 바코드를 쿼리 노드에 쿼리 할 수 ​​있습니다. 그렇습니다. 또한 예를 들어 .startingAt 및 .endingAt 쿼리를 사용하여 식사 노드에 300 ~ 500 칼로리의 식사를 쿼리 할 수 ​​있습니다. 또한 한 번의 식사 ​​경험에서 총 칼로리를 알고 싶다면 해당 식사 노드를 읽고 타임 스탬프, uid 및 식사 (참조 기준)가 포함되어 있는지 확인하십시오. 그런 다음 각각의 식사에 대한 칼로리를 얻기 위해 참조로 각 식사를 질의합니다. – Jay

+0

기술적으로 바코드는 고유해야하므로 식사 노드에서 식사의 열쇠로 사용할 수 있습니다. 그러나 하위 데이터에서 상위 이름의 연결을 해제하는 것이 가장 좋습니다. – Jay

1

구조가 멋지게 보이지만 (파이어베이스가 ID를 생성하도록합니다). 네가 기대하는 것처럼 작동하지 않는 유일한 방법은 검색 뿐이다. pizza을 검색하면 데이터를 기반으로 피자 항목을 반환하는 쿼리를 작성할 수 없습니다. 내 제안은 Algolia (또는 이와 비슷한 것)를 사용하여 쿼리를 수행 할 수 있도록 이름을 lowerCased로 바꾸거나 다른 키를 굴리는 것입니다. 자신 만의 유일한 문제는 izz 같은 것을 검색 할 수없고 피자가 나오게됩니다. 검색 방법은 내 대답 Firebase - How can I filter similarly to equalTo() but instead check if it contains the value?을 참조하십시오.

+0

구조를 기반으로 생각하지 않습니다. OP는 피자를 검색 할 것입니다. 그는 M1234를 찾고있을 것이고, 괜찮습니다. – Jay

+0

Mathew에게 감사드립니다. 파이어베이스가 나를 위해 ID를 생성하도록하고, 검색 정보를 주셔서 감사합니다. 검색 문자열로 시작하는 식사를 검색하는 것만으로도 충분할 수 있습니다. '\ uf8ff'로 끝나는 것은 내 경우에 잘 작동 할 것입니다! – Damian