例如,Google App Engine使用Google Datastore而不是标准数据库来存储数据。有没有人有使用Google数据存储而不是数据库的提示?似乎我已经训练了我的思想,在直接映射到表结构的对象关系中100%思考,现在很难看到任何不同的东西。我可以理解Google数据存储区的一些好处(例如性能和分发数据的能力),但牺牲了一些好的数据库功能(例如连接)。
使用Google Datastore或BigTable的人是否有任何与他们合作的好建议?
答案 0 :(得分:148)
与“传统”关系数据库相比,关于App Engine数据存储区有两个主要的习惯:
要实现的关键 - 以及这两种差异背后的原因 - 是Bigtable基本上就像一个巨大的有序字典。因此,put操作只是设置给定键的值 - 无论该键的任何先前值如何,并且获取操作仅限于获取单个键或连续的键范围。使用索引可以实现更复杂的查询,这些索引基本上只是它们自己的表,允许您在连续范围内扫描时实现更复杂的查询。
一旦掌握了这一点,您就拥有了解数据存储区功能和限制所需的基本知识。可能看似随意的限制可能更有意义。
这里的关键是虽然这些限制是你在关系数据库中可以做的事情,但是这些相同的限制使得扩展到Bigtable旨在处理的那种规模的实用性。你根本无法执行那种在纸上看起来很好但在SQL数据库中非常慢的查询。
就如何更改表示数据的方式而言,最重要的是预先计算。而不是在查询时进行连接,而是预先计算数据并尽可能将其存储在数据存储区中。如果要选择随机记录,请生成随机数并将其与每条记录一起存储。 这是一本关于这些提示和技巧的完整食谱here 编辑:食谱不再存在。
答案 1 :(得分:41)
我一直关注思维转换的方法是完全忘记数据库。
在关系数据库世界中,您总是要担心数据规范化和表结构。放弃一切。只需布置您的网页即可。全力以赴。现在看看他们。你已经2/3了。
如果你忘记了数据库大小很重要且数据不应该重复的概念那么你就是3/4而你甚至不需要编写任何代码!让您的观点决定您的模型。你不必像对待世界一样把你的物体变成二维。您现在可以存储具有形状的对象。
是的,这是对苦难的简化解释,但它帮助我忘记了数据库,只是做了一个应用程序。到目前为止,我已经使用这种理念制作了4个App Engine应用程序,还有更多应用程序。
答案 2 :(得分: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()
答案 3 :(得分:12)
我来自关系数据库世界然后我发现了这个数据存储区的事情。花了好几天才搞定它。我有一些调查结果。
您必须已经知道Datastore是按比例构建的,这是将它与RDMBS分开的东西。为了更好地使用大型数据集进行扩展,App Engine已经做了一些更改(其中一些意味着很多更改)。
RDBMS VS DataStore
结构
在数据库中,我们通常在数据存储区中的表中构建数据,它在数据存储区中变为Kinds and Entities。
关系
在RDBMS中,大多数人都处于一对一,多对一,多对多的关系,在数据存储中,因为它有“无连接”的东西,但我们仍然可以使用“ ReferenceProperty “例如One-to-One Relationship Example。
Indexes
通常在RDMBS中,我们制作索引,如主键,外键,唯一键和索引键,以加快搜索速度并提高数据库性能。在数据存储区中,您必须为每种类型创建至少一个索引(无论您是否愿意,它都将自动generate),因为数据存储区会根据这些索引搜索您的实体并相信我这是最好的部分,在RDBMS中你可以使用非索引字段进行搜索,虽然它需要一些时间,但它会。在数据存储区中,您无法使用非索引属性进行搜索。
计数
在RDMBS中,计算(*)要容易得多,但是在数据存储区中,请不要以正常的方式考虑它(是的,有一个计数函数),因为它有1000 Limit并且它将花费尽可能多的{{3}作为不好的实体但我们总是有很好的选择,我们可以使用small opertion。
Shard Counters
在RDMBS中,我们喜欢这个功能吗?但Datastore有自己的方式。你不能将属性定义为唯一:(。
查询
GAE Datatore提供了更好的功能Unique Constraints(哦不!数据存储区没有LIKE关键字)SQL LIKE。
数据插入/更新/删除/选择
这是我们都感兴趣的地方,因为在RDMBS中我们需要一个查询,就像RDBMS一样,插入,更新,删除和选择,数据存储已经放,删除,得到(不要太兴奋),因为数据存储放置或得到{{ 3}}(读取数据存储调用的成本)以及数据建模开始运作的地方。您必须最小化这些操作并保持您的应用程序运行。要减少GQL,您可以使用Write, Read, Small Operations。
答案 4 :(得分:6)
查看Objectify文档。页面底部的第一条评论说:
“很好,虽然你写这篇文章描述Objectify,但它也是我读过的最简洁的appengine数据存储区解释之一。谢谢。”
答案 5 :(得分:3)
如果您习惯于考虑ORM映射实体,那么基本上就像Google的App Engine这样基于实体的数据存储区是如何工作的。对于类似连接的内容,您可以查看reference properties。您实际上并不需要担心它是否将BigTable用于后端或其他内容,因为后端是由GQL和数据存储区API接口抽象的。
答案 6 :(得分:0)
我查看数据存储区的方式是,类型标识表本身,实体是表中的单独行。如果谷歌只拿出一个没有结构的大表,你可以在实体中转储你想要的任何东西。换句话说,如果实体没有绑定到一种类型,那么你几乎可以将任何结构存储到一个实体并存储在一个位置(一种没有结构的大文件,每一行都有自己的结构)。
现在回到原始评论,谷歌数据存储和bigtable是两个不同的东西,所以不要混淆谷歌数据存储与数据存储数据存储感。 Bigtable比bigquery更昂贵(主要原因我们没有用它)。 Bigquery确实有正确的连接和RDBMS,比如sql语言和它更便宜,为什么不使用bigquery。话虽如此,bigquery确实有一些限制,具体取决于您可能会或可能不会遇到的数据大小。
此外,就数据存储方面的思考而言,我认为适当的陈述将是根据NoSQL数据库进行的思考"。这些天有太多可用的东西,但是当谈到谷歌产品,除了谷歌云SQL(这是mySQL),其他一切都是NoSQL。
答案 7 :(得分:-6)
根植于数据库世界,我的数据存储将是一个巨大的表(因此名称为“bigtable”)。 BigTable是一个糟糕的例子,因为它执行了许多典型数据库可能不会执行的其他操作,但它仍然是一个数据库。除非你知道你需要建立类似Google的“bigtable”之类的东西,否则你可能会对标准数据库很好。他们之所以需要这样,是因为他们正在处理大量的数据和系统,而且没有任何商用系统可以真正完成这项工作,他们可以证明他们需要完成这项工作。
(bigtable reference:http://en.wikipedia.org/wiki/BigTable)