Como pensar em armazenamentos de dados em vez de bancos de dados?

183

Como exemplo, o Google App Engine usa o Google Datastore, não um banco de dados padrão, para armazenar dados. Alguém tem alguma dica para usar o Google Datastore em vez de bancos de dados? Parece que eu treinei minha mente para pensar 100% nos relacionamentos de objetos que são mapeados diretamente para as estruturas da tabela, e agora é difícil ver algo diferente. Entendo alguns dos benefícios do Google Datastore (por exemplo, desempenho e capacidade de distribuir dados), mas algumas boas funcionalidades do banco de dados são sacrificadas (por exemplo, associações).

Alguém que trabalhou com o Google Datastore ou BigTable tem algum bom conselho para trabalhar com eles?

Jim
fonte
O DataSource é uma API antiga que estamos removendo gradualmente - estava muito ligada a um modelo de conexão com o banco de dados. O DataStore é a API de baixo nível que permite o acesso a uma abordagem baseada em streaming "bruta" do conteúdo GIS, usando o FeatureReaders e o FeatureWriter.
Mural
Agora, o Google Cloud SQL fornece suporte de banco de dados relacional para o Google App Engine. Se você ainda procura uma solução para armazenamentos de dados, pode usar o Google Cloud SQL .
Chandana
Você pode querer verificar a API do Mungo Datastore: bit.ly/13eSDpr
quarks

Respostas:

149

Há duas coisas principais a se acostumar no armazenamento de dados do App Engine quando comparado aos bancos de dados relacionais 'tradicionais':

  • O armazenamento de dados não faz distinção entre inserções e atualizações. Quando você chama put () em uma entidade, essa entidade é armazenada no armazenamento de dados com sua chave exclusiva e qualquer coisa que tenha essa chave é sobrescrita. Basicamente, cada tipo de entidade no armazenamento de dados age como um mapa enorme ou uma lista classificada.
  • A consulta, como você mencionou, é muito mais limitada. Sem junções, para começar.

A principal coisa a entender - e a razão por trás dessas duas diferenças - é que o Bigtable basicamente age como um enorme dicionário ordenado. Portanto, uma operação put apenas define o valor para uma determinada chave - independentemente de qualquer valor anterior para essa chave, e as operações de busca são limitadas à busca de chaves únicas ou intervalos contíguos de chaves. As consultas mais sofisticadas são possíveis com índices, que são basicamente apenas tabelas próprias, permitindo implementar consultas mais complexas como varreduras em intervalos contíguos.

Depois de absorver isso, você terá o conhecimento básico necessário para entender os recursos e as limitações do armazenamento de dados. Restrições que podem parecer arbitrárias provavelmente fazem mais sentido.

O principal aqui é que, embora haja restrições sobre o que você pode fazer em um banco de dados relacional, essas mesmas restrições são o que torna prático escalar para o tipo de magnitude que o Bigtable foi projetado para lidar. Você simplesmente não pode executar o tipo de consulta que fica bem no papel, mas é atrozmente lenta em um banco de dados SQL.

Em termos de como alterar a forma como você representa os dados, o mais importante é o pré-cálculo. Em vez de fazer associações no momento da consulta, pré-calcule os dados e armazene-os no armazenamento de dados sempre que possível. Se você deseja escolher um registro aleatório, gere um número aleatório e armazene-o em cada registro. Há todo um livro de receitas desse tipo de dicas e truques aqui Editar: O livro de receitas não existe mais.

Nick Johnson
fonte
4
Boas notícias, a Internet não se esqueceu do livro de receitas, ou seja, o arquivo da Internet não se esqueceu. O fantasma do site ainda existe aqui: web.archive.org/web/20090416113704/http://…
EasilyBaffled
42

A maneira como eu ando com a mudança de mente é esquecer completamente o banco de dados.

No mundo do banco de dados relacional, você sempre precisa se preocupar com a normalização de dados e sua estrutura de tabela. Abandone tudo. Basta fazer o layout da sua página da web. Coloque todos eles fora. Agora olhe para eles. Você já está 2/3 lá.

Se você esquecer a noção de que o tamanho do banco de dados é importante e os dados não devem ser duplicados, você estará lá 3/4 e nem precisará escrever nenhum código! Deixe suas opiniões ditarem seus modelos. Você não precisa pegar seus objetos e torná-los bidimensionais, como no mundo relacional. Você pode armazenar objetos com forma agora.

Sim, esta é uma explicação simplificada da provação, mas me ajudou a esquecer os bancos de dados e apenas fazer um aplicativo. Até agora, criei 4 aplicativos do Google App Engine usando essa filosofia e ainda há mais por vir.

user19087
fonte
2
Gosto do "Deixe suas opiniões ditarem seus modelos". mordeu. Eu acho que é um desligamento vindo do RDBMS, mas simplifica tudo.
precisa saber é o seguinte
23

Eu sempre rio quando as pessoas aparecem - não é relacional. Eu escrevi cellectr no django e aqui está um trecho do meu modelo abaixo. Como você verá, tenho ligas que são gerenciadas ou treinadas pelos usuários. Eu posso de uma liga conseguir todos os gerentes, ou de um determinado usuário eu posso devolver a liga que ela treina ou dirige.

Só porque não há suporte específico à chave estrangeira não significa que você não pode ter um modelo de banco de dados com relacionamentos.

Meus dois centavos.


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()    
Phil Stollery
fonte
12

Eu vim do mundo do banco de dados relacional e encontrei essa coisa do armazenamento de dados. demorou vários dias para pegar o jeito. Bem, existem algumas das minhas descobertas.

Você já deve saber que o armazenamento de dados é construído em escala e é isso que o separa do RDMBS. Para dimensionar melhor com um grande conjunto de dados, o App Engine fez algumas alterações (algumas significam muitas alterações).


Estrutura do RDBMS VS DataStore
No banco de dados, geralmente estruturamos nossos dados em Tabelas, Linhas, que no Datastore se tornam Tipos e Entidades .

Relações
no RDBMS, a maioria das pessoas segue o relacionamento Um-para-Um, Muitos-para-Um, Muitos-para-Muitos, No Datastore, como possui a opção "Sem junções", mas ainda podemos alcançar nossa normalização usando " ReferenceProperty "por exemplo, Exemplo de relacionamento individual .

Índices
Normalmente, no RDMBS, fazemos índices como Chave Primária, Chave Externa, Chave Única e Chave de Índice para acelerar a pesquisa e aumentar o desempenho do banco de dados. No armazenamento de dados, você deve especificar pelo menos um índice por tipo (ele será gerado automaticamente,quer você goste ou não), porque o armazenamento de dados pesquisa sua entidade com base nesses índices e acredita que é a melhor parte. No RDBMS, você pode pesquisar usando campo não indexado, embora demore algum tempo, mas No armazenamento de dados, você não pode pesquisar usando propriedades que não são de índice.

Contagem
No RDMBS, é muito mais fácil contar (*), mas no armazenamento de dados, por favor, nem pense da maneira normal (sim, existe uma função de contagem), pois ela tem 1000 Limit e custará tantas operações pequenas quanto a entidade que não é bom, mas sempre temos boas escolhas, podemos usar contadores de fragmentos .

Restrições exclusivas
No RDMBS, adoramos esse recurso, certo? mas o Datastore tem seu próprio caminho. você não pode definir uma propriedade como única :(.

Consulta
GAE Datatore fornece um recurso melhor muito COMO (Oh não! Armazenamento de dados não tem COMO palavra-chave) SQL que é GQL .

Inserção / Atualização / Exclusão / Seleção de Dados
Aqui onde todos estamos interessados, como no RDMBS, solicitamos uma consulta para Inserir, Atualizar, Excluir e Selecionar, exatamente como RDBMS, o Datastore colocou, excluiu, obteve (não fique muito animado) porque o Datastore colocar ou obter em termos de gravação, leitura, pequenas operações ( custos de leitura para chamadas do armazenamento de dados ) e é aí que entra em ação a Modelagem de Dados. você precisa minimizar essas operações e manter seu aplicativo em execução. Para a operação de redução de leitura, você pode usar o Memcache .

sanjay kushwah
fonte
6

Dê uma olhada na documentação do Objectify. O primeiro comentário na parte inferior da página diz:

"Bom, embora você tenha escrito isso para descrever o Objectify, também é uma das explicações mais concisas do próprio armazenamento de dados de aplicativos que eu já li. Obrigado."

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

Jon Stevens
fonte
3

Se você está acostumado a pensar em entidades mapeadas pelo ORM, é basicamente assim que funciona um armazenamento de dados baseado em entidades como o Google App Engine do Google. Para algo como junções, você pode consultar as propriedades de referência . Você realmente não precisa se preocupar se ele usa o BigTable para o back-end ou algo mais, pois o back-end é abstraído pelas interfaces de API do GQL e do Datastore.

Mark Cidade
fonte
1
Um problema com as propriedades de referência é que elas podem criar rapidamente um problema de consulta 1 + N. (Puxe 1 consulta para encontrar 100 pessoas e faça outra consulta para cada uma delas para obter o person.address.)
0124816 22/08/08/0
O link para 'propriedades de referência' está quebrado, provavelmente pela adição do suporte a Java. Tente: code.google.com/appengine/docs/python/datastore/…
Spike0xff 2/09/09
link fixo. fique à vontade para editar qualquer resposta se / quando você tiver representante suficiente.
Mark Cidade
0

A maneira como olho para o armazenamento de dados é: tipo identifica tabela, por si só, e entidade é linha individual dentro da tabela. Se o Google escolher um tipo diferente de sua única tabela grande sem estrutura, você poderá despejar o que quiser em uma entidade. Em outras palavras, se as entidades não estão vinculadas a um tipo, você pode praticamente ter qualquer estrutura para uma entidade e armazenar em um local (tipo de arquivo grande sem estrutura, cada linha tem estrutura própria).

Agora, voltando ao comentário original, o armazenamento de dados do Google e o bigtable são duas coisas diferentes; portanto, não confunda o armazenamento de dados do Google com o senso de armazenamento de dados. Bigtable é mais caro que bigquery (a principal razão pela qual não concordamos). O Bigquery possui junções adequadas e RDBMS, como a linguagem sql e é mais barato, por que não usar o bigquery. Dito isto, o bigquery tem algumas limitações, dependendo do tamanho dos seus dados, você pode ou não encontrá-los.

Além disso, em termos de pensamento em termos de armazenamento de dados, acho que a declaração adequada teria sido "pensando em termos de bancos de dados NoSQL". Atualmente, existem muitos deles disponíveis no mercado atualmente, mas quando se trata de produtos do Google, exceto o Google Cloud SQL (que é mySQL), todo o resto é NoSQL.

ringadingding
fonte
-6

Sendo enraizado no mundo dos bancos de dados, um armazenamento de dados para mim seria uma tabela gigante (daí o nome "bigtable"). O BigTable é um mau exemplo, porque faz muitas outras coisas que um banco de dados típico pode não fazer, e ainda assim é um banco de dados. As chances são de que, a menos que você saiba que precisa criar algo como a "bigtable" do Google, você provavelmente ficará bem com um banco de dados padrão. Eles precisam disso porque estão lidando com quantidades insanas de dados e sistemas juntos, e nenhum sistema comercialmente disponível pode realmente fazer o trabalho da maneira exata em que pode demonstrar que precisa que o trabalho seja feito.

(referência de tabela grande: http://en.wikipedia.org/wiki/BigTable )

devinmoore
fonte
A pergunta está relacionada especificamente ao Google App Engine, que usa o Bigtable; usar um banco de dados relacional não é uma opção.
Nick Johnson