Comment penser dans des data stores plutôt que dans des bases de données?

183

Par exemple, Google App Engine utilise Google Datastore, et non une base de données standard, pour stocker des données. Quelqu'un a-t-il des conseils pour utiliser Google Datastore au lieu des bases de données? Il semble que j'ai entraîné mon esprit à penser à 100% dans les relations d'objets qui correspondent directement aux structures de table, et maintenant il est difficile de voir quoi que ce soit différemment. Je peux comprendre certains des avantages de Google Datastore (par exemple les performances et la capacité de distribuer des données), mais certaines bonnes fonctionnalités de base de données sont sacrifiées (par exemple les jointures).

Quelqu'un qui a travaillé avec Google Datastore ou BigTable a-t-il de bons conseils pour travailler avec eux?

Jim
la source
DataSource est une ancienne API que nous supprimons progressivement - elle était très liée à un modèle de connexion à une base de données. DataStore est l'API de bas niveau qui permet d'accéder à une approche "brute" basée sur le streaming du contenu SIG, en utilisant FeatureReaders et FeatureWriter.
murali
Désormais, Google Cloud SQL prend en charge les bases de données relationnelles pour Google App Engine. Si vous recherchez toujours une solution pour les magasins de données, vous pouvez utiliser Google Cloud SQL .
Chandana
Vous voudrez peut-être consulter l'API Mungo Datastore: bit.ly/13eSDpr
quarks

Réponses:

149

Il y a deux choses principales auxquelles s'habituer à propos de la banque de données App Engine par rapport aux bases de données relationnelles `` traditionnelles '':

  • Le magasin de données ne fait aucune distinction entre les insertions et les mises à jour. Lorsque vous appelez put () sur une entité, cette entité est stockée dans le magasin de données avec sa clé unique, et tout ce qui a cette clé est écrasé. Fondamentalement, chaque type d'entité dans la banque de données agit comme une énorme carte ou une liste triée.
  • L'interrogation, comme vous l'avez mentionné, est beaucoup plus limitée. Pas de jointure, pour commencer.

La chose clé à réaliser - et la raison derrière ces deux différences - est que Bigtable agit essentiellement comme un énorme dictionnaire ordonné. Ainsi, une opération put définit simplement la valeur d'une clé donnée - quelle que soit la valeur précédente pour cette clé, et les opérations d'extraction sont limitées à l'extraction de clés uniques ou de plages de clés contiguës. Des requêtes plus sophistiquées sont rendues possibles avec des index, qui ne sont en fait que des tables qui leur sont propres, vous permettant d'implémenter des requêtes plus complexes sous forme d'analyses sur des plages contiguës.

Une fois que vous avez absorbé cela, vous avez les connaissances de base nécessaires pour comprendre les capacités et les limites de la banque de données. Des restrictions qui peuvent avoir semblé arbitraires ont probablement plus de sens.

L'essentiel ici est que bien qu'il s'agisse de restrictions sur ce que vous pouvez faire dans une base de données relationnelle, ces mêmes restrictions sont ce qui rend pratique la mise à l'échelle jusqu'au type de grandeur que Bigtable est conçu pour gérer. Vous ne pouvez tout simplement pas exécuter le type de requête qui a l'air bien sur papier mais qui est atrocement lent dans une base de données SQL.

En ce qui concerne la manière de modifier la façon dont vous représentez les données, le plus important est le précalcul. Au lieu de faire des jointures au moment de la requête, précalculez les données et stockez-les dans la banque de données dans la mesure du possible. Si vous souhaitez choisir un enregistrement aléatoire, générez un nombre aléatoire et stockez-le avec chaque enregistrement. Il y a tout un livre de cuisine de ce genre de trucs et astuces ici Edit: Le livre de cuisine n'existe plus.

Nick Johnson
la source
4
Bonne nouvelle, Internet n'a pas oublié le livre de cuisine, à savoir que l'archive Internet n'a pas oublié. Le fantôme du site existe toujours ici: web.archive.org/web/20090416113704/http
//...
42

La façon dont j'ai procédé au changement de mentalité est d'oublier complètement la base de données.

Dans le monde de la base de données relationnelle, vous devez toujours vous soucier de la normalisation des données et de la structure de votre table. Laissez tomber tout cela. Mettez simplement en page votre page Web. Disposez-les tous. Maintenant, regardez-les. Vous y êtes déjà 2/3.

Si vous oubliez l'idée que la taille de la base de données compte et que les données ne doivent pas être dupliquées, vous êtes aux 3/4 et vous n'avez même pas besoin d'écrire de code! Laissez vos opinions dicter vos modèles. Vous n'avez plus à prendre vos objets et à les rendre 2 dimensions comme dans le monde relationnel. Vous pouvez maintenant stocker des objets avec une forme.

Oui, c'est une explication simplifiée de l'épreuve, mais cela m'a aidé à oublier les bases de données et à créer une application. Jusqu'à présent, j'ai créé 4 applications App Engine en utilisant cette philosophie et il y en a d'autres à venir.

user19087
la source
2
J'aime le "Laissez vos opinions dicter vos modèles". bit. Je pense que c'est un blocage venant du SGBDR, mais cela simplifie tout.
cbednarski
23

Je rigole toujours quand les gens sortent avec - ce n'est pas relationnel. J'ai écrit cellectr en django et voici un extrait de mon modèle ci-dessous. Comme vous le verrez, j'ai des ligues qui sont gérées ou coachées par les utilisateurs. Je peux d'une ligue obtenir tous les managers, ou d'un utilisateur donné, je peux renvoyer la ligue qu'elle entraîne ou manager.

Ce n'est pas parce qu'il n'y a pas de prise en charge de clé étrangère spécifique que vous ne pouvez pas avoir de modèle de base de données avec des relations.

Mes deux pence.


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
la source
12

Je suis venu du monde de la base de données relationnelle, puis j'ai trouvé ce truc Datastore. il a fallu plusieurs jours pour y arriver. Eh bien, il y a certaines de mes découvertes.

Vous devez déjà savoir que Datastore est conçu pour évoluer et c'est ce qui le sépare de RDMBS. pour mieux évoluer avec un ensemble de données volumineux, App Engine a apporté quelques modifications (certaines signifient beaucoup de changements).


Structure du RDBMS VS DataStore
Dans la base de données, nous structurons généralement nos données en tables, lignes qui se trouvent dans le magasin de données et deviennent des types et des entités .

Relations
Dans le SGBDR, la plupart des gens suivent la relation un-à-un, plusieurs-à-un, plusieurs-à-plusieurs, dans le magasin de données, car il n'a pas de jointure, mais nous pouvons toujours réaliser notre normalisation en utilisant " ReferenceProperty " Exemple de relation un à un par exemple .

Index
Habituellement, dans RDMBS, nous créons des index comme la clé primaire, la clé étrangère, la clé unique et la clé d'index pour accélérer la recherche et améliorer les performances de notre base de données. Dans le magasin de données, vous devez créer au moins un index par type (il générera automatiquementque vous le vouliez ou non) car le magasin de données recherche votre entité sur la base de ces index et croyez-moi que c'est la meilleure partie, dans le SGBDR, vous pouvez rechercher en utilisant champ non-index bien que cela prendra un certain temps, mais cela le sera. Dans Datastore, vous ne pouvez pas effectuer de recherche en utilisant une propriété non indexée.

Count
Dans RDMBS, il est beaucoup plus facile de compter (*) mais dans le magasin de données, s'il vous plaît ne le pensez même pas de manière normale (oui, il y a une fonction de comptage) car il a une limite de 1000 et cela coûtera autant de petites opérations que l'entité qui ce n'est pas bon mais nous avons toujours de bons choix, nous pouvons utiliser des compteurs d'éclat .

Contraintes uniques
Dans RDMBS, nous aimons cette fonctionnalité, non? mais Datastore a sa propre manière. vous ne pouvez pas définir une propriété comme unique :(.

Requête
GAE Datatore fournit une meilleure fonctionnalité bien COMME (Oh non! Datastore n'a pas aimé les mots - clés) SQL qui est GQL .

Insertion de données / mise à jour / suppression / sélection
Ceci nous intéresse tous, comme dans RDMBS, nous avons besoin d'une requête pour insérer, mettre à jour, supprimer et sélectionner tout comme le SGBDR, Datastore a mis, supprimer, obtenir (ne soyez pas trop excité) parce que Datastore Mettez ou obtenez en termes d' écriture, de lecture, de petites opérations ( coûts de lecture pour les appels au magasin de données ) et c'est là que la modélisation des données entre en action. vous devez minimiser ces opérations et maintenir votre application en cours d'exécution. Pour réduire l' opération de lecture, vous pouvez utiliser Memcache .

sanjay kushwah
la source
6

Jetez un œil à la documentation Objectify. Le premier commentaire en bas de page dit:

"Bien, bien que vous ayez écrit ceci pour décrire Objectify, c'est aussi l'une des explications les plus concises du magasin de données appengine lui-même que j'ai jamais lu. Merci."

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

Jon Stevens
la source
3

Si vous avez l'habitude de penser aux entités mappées ORM, c'est en gros ainsi que fonctionne une banque de données basée sur des entités comme App Engine de Google. Pour quelque chose comme les jointures, vous pouvez consulter les propriétés de référence . Vous n'avez pas vraiment besoin de vous demander s'il utilise BigTable pour le backend ou autre chose puisque le backend est abstrait par les interfaces API GQL et Datastore.

Mark Cidade
la source
1
Un problème avec les propriétés de référence est qu'elles peuvent créer rapidement un problème de requête 1 + N. (Tirez 1 requête pour trouver 100 personnes, puis effectuez une autre requête pour chacune d'elles pour obtenir person.address.)
0124816
Le lien vers les «propriétés de référence» est rompu, probablement par l'ajout du support Java. Essayez: code.google.com/appengine/docs/python/datastore/…
Spike0xff
lien corrigé. n'hésitez pas à modifier n'importe quelle réponse si / lorsque vous avez suffisamment de représentants.
Mark Cidade
0

La façon dont je regarde le magasin de données est, kind identifie la table, en soi, et l'entité est une ligne individuelle dans la table. Si Google prenait un peu plus que sa seule grande table sans structure et vous pouvez vider ce que vous voulez dans une entité. En d'autres termes, si les entités ne sont pas liées à un genre, vous pouvez à peu près avoir n'importe quelle structure pour une entité et stocker dans un seul endroit (sorte de gros fichier sans structure, chaque ligne a sa propre structure).

Maintenant, revenons au commentaire d'origine, google datastore et bigtable sont deux choses différentes, alors ne confondez pas google datastore avec le sens de stockage de données de datastore. Bigtable est plus cher que bigquery (raison principale pour laquelle nous ne l'avons pas suivi). Bigquery a des jointures appropriées et un SGBDR comme le langage SQL et son moins cher, pourquoi ne pas utiliser bigquery. Cela étant dit, bigquery présente certaines limites, selon la taille de vos données, vous pouvez ou non les rencontrer.

Aussi, en termes de réflexion en termes de magasin de données, je pense qu'une déclaration appropriée aurait été "penser en termes de bases de données NoSQL". Il y en a trop de disponibles ces jours-ci, mais en ce qui concerne les produits Google, à l'exception de Google Cloud SQL (qui est mySQL), tout le reste est NoSQL.

baguette magique
la source
-6

Étant enraciné dans le monde des bases de données, un magasin de données serait pour moi une table géante (d'où le nom «bigtable»). BigTable est un mauvais exemple car il fait beaucoup d'autres choses qu'une base de données typique pourrait ne pas faire, et pourtant c'est toujours une base de données. Il y a de fortes chances que, à moins que vous ne sachiez que vous avez besoin de créer quelque chose comme le "bigtable" de Google, vous serez probablement très bien avec une base de données standard. Ils en ont besoin parce qu'ils gèrent ensemble des quantités insensées de données et de systèmes, et aucun système disponible dans le commerce ne peut vraiment faire le travail de la manière exacte dont ils peuvent démontrer qu'ils ont besoin que le travail soit fait.

(référence bigtable: http://en.wikipedia.org/wiki/BigTable )

devinmoore
la source
La question concerne spécifiquement Google App Engine, qui utilise Bigtable; l'utilisation d'une base de données relationnelle n'est pas une option.
Nick Johnson le