데이터베이스 대신 데이터 저장소에서 생각하는 방법?


183

예를 들어 Google App Engine은 표준 데이터베이스가 아닌 Google 데이터 스토어를 사용하여 데이터를 저장합니다. 데이터베이스 대신 Google Datastore를 사용하기위한 팁이 있습니까? 테이블 구조에 직접 매핑되는 객체 관계를 100 % 생각하도록 마음을 훈련 한 것 같습니다. 이제는 다르게 볼 수 없습니다. Google 데이터 스토어의 이점 (예 : 성능 및 데이터 배포 기능)을 이해할 수 있지만 데이터베이스 기능이 뛰어납니다 (예 : 조인).

Google Datastore 또는 BigTable과 함께 일한 사람이 그들과 협력 할 때 좋은 조언이 있습니까?


DataSource는 점진적으로 제거하는 오래된 API이며 데이터베이스 연결 모델과 매우 관련이 있습니다. DataStore는 FeatureReaders 및 FeatureWriter를 사용하여 GIS 컨텐츠에 대한 "원시"스트리밍 기반 접근 방식에 액세스 할 수있는 저수준 API입니다.
murali

이제 Google Cloud SQL은 Google App Engine에 대한 관계형 데이터베이스 지원을 제공합니다. 여전히 데이터 저장소 솔루션을 찾고 있다면 Google Cloud SQL을 사용할 수 있습니다 .
Chandana

Mungo Datastore API를 확인하고 싶을 수도 있습니다 : bit.ly/13eSDpr
쿼크

답변:


149

'전통적인'관계형 데이터베이스와 비교할 때 App Engine 데이터 저장소에 익숙해 져야 할 두 가지 주요 사항이 있습니다.

  • 데이터 스토어는 삽입과 업데이트를 구분하지 않습니다. 엔터티에서 put ()을 호출하면 해당 엔터티가 고유 키로 데이터 스토어에 저장되고 해당 키가있는 모든 항목을 덮어 씁니다. 기본적으로 데이터 스토어의 각 엔티티 종류는 막대한 맵 또는 정렬 된 목록처럼 작동합니다.
  • 언급했듯이 쿼리는 훨씬 제한적입니다. 시작을위한 조인이 없습니다.

Bigtable이 기본적으로 막대한 순서 사전과 같은 역할을한다는 점을 인식해야합니다. 따라서 넣기 조작은 해당 키의 이전 값에 관계없이 주어진 키의 값을 설정하기 만하며 페치 조작은 단일 키 또는 연속 된 키 범위를 페치하는 것으로 제한됩니다. 기본적으로 자체 테이블 인 인덱스를 사용하면보다 복잡한 쿼리를 수행 할 수 있으므로 더 복잡한 쿼리를 연속 범위의 스캔으로 구현할 수 있습니다.

이를 이해하면 데이터 스토어의 기능과 한계를 이해하는 데 필요한 기본 지식을 얻게됩니다. 임의적으로 보일 수있는 제한 사항이 더 의미가있을 수 있습니다.

여기서 중요한 것은 관계형 데이터베이스에서 수행 할 수있는 작업에 대한 제한 사항이지만 이러한 동일한 제한 사항으로 인해 Bigtable이 처리하도록 설계된 정도까지 확장 할 수 있습니다. 종이에는 좋지만 SQL 데이터베이스에서는 엄청나게 느린 일종의 쿼리를 실행할 수 없습니다.

데이터 표현 방식을 변경하는 방법에서 가장 중요한 것은 사전 계산입니다. 쿼리시 조인을 수행하는 대신 데이터를 미리 계산하여 가능한 경우 데이터 저장소에 저장하십시오. 임의의 레코드를 선택하려면 임의의 숫자를 생성하고 각 레코드와 함께 저장하십시오. 이러한 종류의 팁과 요령에 대한 전체 요리 책이 있습니다. 편집 : 요리 책이 더 이상 존재하지 않습니다.


4
좋은 소식은, 인터넷이 요리 책에 대해 잊어 버리지 않았다는 것입니다. 이 사이트의 유령은 여전히 여기에 존재합니다 web.archive.org/web/20090416113704/http://...
EasilyBaffled에게

42

내가 마음의 전환에 대해 가고있는 방법은 데이터베이스를 모두 잊어 버리는 것입니다.

관계형 db 세계에서는 항상 데이터 정규화 및 테이블 구조에 대해 걱정해야합니다. 다 버려 웹 페이지를 레이아웃하면됩니다. 그들을 모두 배치하십시오. 이제 그들을보십시오. 이미 2/3입니다.

데이터베이스 크기가 중요하고 데이터를 복제해서는 안된다는 개념을 잊어 버린 경우 3/4에 불과하며 코드를 작성할 필요조차 없습니다! 뷰가 모델을 지시하게하십시오. 관계 세계 에서처럼 더 이상 객체를 가져 와서 2 차원으로 만들 필요가 없습니다. 이제 모양이있는 객체를 저장할 수 있습니다.

예, 이것은 시련에 대한 간단한 설명이지만 데이터베이스를 잊어 버리고 응용 프로그램을 만드는 데 도움이되었습니다. 이 철학을 사용하여 지금까지 4 개의 App Engine 앱을 만들었으며 앞으로 더 많은 것이 있습니다.


2
"뷰가 모델을 결정하게하십시오."가 마음에 듭니다. 비트. 나는 그것이 RDBMS에서 오는 끊임없는 것이라고 생각하지만 모든 것을 단순화합니다.
cbednarski

23

사람들이 나올 때 나는 항상 멍청하다-그것은 관계가 없다. 나는 django로 cellectr를 작성했으며 다음은 내 모델의 스 니펫입니다. 보시다시피, 사용자가 관리하거나 코치하는 리그가 있습니다. 리그에서 모든 관리자를 얻거나 지정된 사용자로부터 코치 또는 관리자로 리그를 반환 할 수 있습니다.

특정 외래 키 지원이 없다고해서 관계가있는 데이터베이스 모델을 가질 수 없다는 의미는 아닙니다.

내 두 펜스.


class League(BaseModel):
    name = db.StringProperty()    
    managers = db.ListProperty(db.Key) #all the users who can view/edit this league
    coaches = db.ListProperty(db.Key) #all the users who are able to view this league

    def get_managers(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.managers)

    def get_coaches(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.coaches)      

    def __str__(self):
        return self.name

    # Need to delete all the associated games, teams and players
    def delete(self):
        for player in self.leagues_players:
            player.delete()
        for game in self.leagues_games:
            game.delete()
        for team in self.leagues_teams:
            team.delete()            
        super(League, self).delete()

class UserPrefs(db.Model):
    user = db.UserProperty()
    league_ref = db.ReferenceProperty(reference_class=League,
                            collection_name='users') #league the users are managing

    def __str__(self):
        return self.user.nickname

    # many-to-many relationship, a user can coach many leagues, a league can be
    # coached by many users
    @property
    def managing(self):
        return League.gql('WHERE managers = :1', self.key())

    @property
    def coaching(self):
        return League.gql('WHERE coaches = :1', self.key())

    # remove all references to me when I'm deleted
    def delete(self):
        for manager in self.managing:
            manager.managers.remove(self.key())
            manager.put()
        for coach in self.managing:
            coach.coaches.remove(self.key())
            coaches.put()            
        super(UserPrefs, self).delete()    

12

관계형 데이터베이스 세계에서 왔으며이 데이터 스토어를 찾았습니다. 그것을 끊는 데 며칠이 걸렸습니다. 내 소견 중 일부가 있습니다.

Datastore가 확장 가능한 빌드이며 RDMBS와 분리 된 것임을 이미 알고 있어야합니다. 대규모 데이터 세트로 확장 성을 높이기 위해 App Engine은 일부 변경을 수행했습니다 (일부는 많은 변경을 의미 함).

RDBMS VS DataStore
구조
데이터베이스에서는 일반적으로 데이터를 Datastore에있는 Tables, Rows로 구성 합니다. Kinds and Entities가 됩니다.

관계
RDBMS에서 대부분의 사람들은 일대일, 다 대일, 다 대다 관계를 다음과 같이 처리합니다. 데이터 저장소에서 "조인 없음"항목이 있기 때문에 " ReferenceProperty를 사용하여 정규화를 달성 할 수 있습니다. "예 : 일대일 관계 예 .

인덱스
일반적으로 RDMBS에서는 기본 키, 외래 키, 고유 키 및 인덱스 키와 같은 인덱스를 만들어 검색 속도를 높이고 데이터베이스 성능을 향상시킵니다. 데이터 저장소에서데이터 저장소는 이러한 인덱스를 기반으로 엔티티를 검색하고 가장 중요한 부분이라고 생각하기 때문에종류별로 적어도 하나의 인덱스를 작성해야합니다 (원하는지 여부를자동으로 생성 함 ). RDBMS에서는 다음을 사용하여 검색 할 수 있습니다. 색인이 아닌 필드는 시간이 걸리지 만 시간이 걸립니다. Datastore에서는 인덱스가 아닌 속성을 사용하여 검색 할 수 없습니다.

카운트
가 계산하는 것이 훨씬 쉽다에서는 RDMBS를 (*)하지만, 데이터 저장소, (그래 카운트 기능이) 정상적인 방법으로 그것을 생각도하지 말아주십시오이있다으로 1000 제한 하고 많이 비용이 작은 opertion 엔티티로하는 좋지는 않지만 항상 좋은 선택이 있습니다 . 샤드 카운터를 사용할 수 있습니다 .

고유 한 제약
RDMBS에서이 기능이 마음에 드십니까? 그러나 데이터 스토어에는 고유 한 방법이 있습니다. 속성을 고유 :(.)로 정의 할 수 없습니다.

Query
GAE Datatore 는 GQL 인 LIKE (Oh no! datastore에 LIKE 키워드가 없음) SQL 보다 훨씬 나은 기능을 제공합니다 .

데이터 삽입 / 업데이트 / 삭제 / 선택
RDMBS와 마찬가지로 RDBMS와 마찬가지로 삽입, 업데이트, 삭제 및 선택에 대한 쿼리가 하나 필요합니다. 데이터 스토어는 데이터 스토어가 있기 때문에 데이터를 저장, 삭제, 가져 오기 (너무 흥분하지 않습니다) 쓰기, 읽기, 소규모 작업 ( 데이터 스토어 호출에 대한 읽기 비용 ) 및 데이터 모델링이 적용되는 측면에서 넣거나 가져 옵니다. 이러한 작업을 최소화하고 앱을 계속 실행해야합니다. 읽기 작업 을 줄이기 위해 Memcache 를 사용할 수 있습니다 .


6

Objectify 문서를 살펴보십시오. 페이지 하단의 첫 번째 주석은 다음과 같습니다.

"객관적으로 Objectify를 설명하기 위해이 글을 썼지 만, 내가 읽은 appengine 데이터 저장소 자체에 대한 가장 간결한 설명 중 하나이기도합니다. 감사합니다."

https://github.com/objectify/objectify/wiki/Concepts


3

ORM 매핑 엔터티에 대해 생각하는 데 익숙하다면 기본적으로 Google App Engine과 같은 엔터티 기반 데이터 저장소가 작동하는 방식입니다. 조인과 같은 경우 참조 속성을 볼 수 있습니다 . 백엔드가 GQL 및 Datastore API 인터페이스에 의해 추상화되므로 백엔드에 BigTable을 사용하는지 또는 다른 것에 대해 걱정할 필요가 없습니다.


1
참조 속성의 한 가지 문제는 1 + N 쿼리 문제를 빠르게 만들 수 있다는 것입니다. (100 명을 찾기 위해 1 번의 쿼리를 수행 한 다음 person.address를 얻기 위해 각각에 대해 다른 쿼리를 작성하십시오.)
0124816

Java 지원을 추가하여 '참조 속성'에 대한 링크가 끊어졌습니다. try : code.google.com/appengine/docs/python/datastore/…
Spike0xff

링크 고정. 담당자가 충분할 경우 언제든지 답변을 수정하십시오.
Mark Cidade

0

데이터 저장소를 보는 방식은 종류 자체가 테이블을 식별하며 엔터티는 테이블 내의 개별 행입니다. Google이 구조가없는 하나의 큰 테이블보다 친절하고 엔티티에서 원하는 것을 덤프 할 수 있다면. 즉, 엔티티가 종류에 묶여 있지 않으면 엔티티에 대한 구조를 가지고 한 위치에 저장할 수 있습니다 (구조가없는 큰 파일의 종류마다 각 줄마다 자체 구조가 있음).

이제 원래 의견으로 돌아가서 Google 데이터 저장소와 bigtable은 서로 다른 두 가지이므로 Google 데이터 저장소와 데이터 저장소 데이터 저장 의미를 혼동하지 마십시오. Bigtable은 bigquery보다 비쌉니다 (기본 이유는 사용하지 않았습니다). Bigquery에는 적절한 조인과 SQL 언어와 같은 RDBMS가 있으며 저렴하므로 bigquery를 사용하지 마십시오. 즉, bigquery에는 데이터 크기에 따라 발생할 수있는 데이터 크기에 따라 몇 가지 제한이 있습니다.

또한 데이터 스토어 측면에서 생각할 때 적절한 진술이 "NoSQL 데이터베이스 측면에서 생각할 것"이라고 생각합니다. 요즘에는 너무 많은 것들이 있지만 Google 클라우드 SQL (mySQL)을 제외한 Google 제품의 경우 다른 모든 것은 NoSQL입니다.


-6

데이터베이스 세계에 뿌리를 둔 데이터 저장소는 거대한 테이블이 될 것입니다 (따라서 "bigtable"이라는 이름). BigTable은 일반적인 데이터베이스가 수행 할 수없는 다른 많은 작업을 수행하지만 여전히 데이터베이스이기 때문에 나쁜 예입니다. Google의 "큰 테이블"과 같은 것을 구축해야한다는 사실을 알지 못하면 표준 데이터베이스를 사용하는 것이 좋습니다. 그들은 엄청난 양의 데이터와 시스템을 함께 처리하고 있기 때문에 상업적으로 이용 가능한 시스템은 실제로 작업을 수행해야한다는 것을 보여주는 정확한 방법으로 작업을 수행 할 수 없습니다.

(큰 참조 : http://en.wikipedia.org/wiki/BigTable )


이 질문은 특히 Bigtable을 사용하는 Google App Engine과 관련이 있습니다. 관계형 데이터베이스를 사용하는 것은 옵션이 아닙니다.
Nick Johnson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.