Database 如何在数据存储而不是数据库中思考?
例如,GoogleAppEngine使用Google数据存储而不是标准数据库来存储数据。有人对使用谷歌数据存储而不是数据库有什么建议吗?似乎我已经训练了我的思维,让我100%地思考直接映射到表结构的对象关系,现在很难看到任何不同的东西。我可以理解Google数据存储的一些好处(例如性能和分发数据的能力),但牺牲了一些好的数据库功能(例如连接)Database 如何在数据存储而不是数据库中思考?,database,google-app-engine,google-cloud-platform,google-cloud-datastore,Database,Google App Engine,Google Cloud Platform,Google Cloud Datastore,例如,GoogleAppEngine使用Google数据存储而不是标准数据库来存储数据。有人对使用谷歌数据存储而不是数据库有什么建议吗?似乎我已经训练了我的思维,让我100%地思考直接映射到表结构的对象关系,现在很难看到任何不同的东西。我可以理解Google数据存储的一些好处(例如性能和分发数据的能力),但牺牲了一些好的数据库功能(例如连接) 任何曾经使用过Google数据存储或BigTable的人对使用它们有什么好的建议吗?植根于数据库世界,对我来说,数据存储将是一个巨大的表(因此被称为“Bi
任何曾经使用过Google数据存储或BigTable的人对使用它们有什么好的建议吗?植根于数据库世界,对我来说,数据存储将是一个巨大的表(因此被称为“BigTable”)。BigTable是一个糟糕的例子,因为它做了很多典型数据库可能不做的事情,但它仍然是一个数据库。除非你知道你需要建立像谷歌的“bigtable”这样的东西,否则你很可能可以使用标准数据库。他们需要这样做,因为他们同时处理大量的数据和系统,而且没有一个商用系统能够真正以他们能够证明他们需要完成这项工作的确切方式来完成这项工作
(bigtable参考资料:)关于思维转换,我一直采取的方式是完全忘记数据库 在关系数据库世界中,您总是需要担心数据规范化和表结构。别管它了。只需布局您的网页。把它们都摆出来。现在看看他们。你已经是三分之二了 如果您忘记了数据库大小很重要,数据不应该被复制的概念,那么您就达到了3/4,甚至不需要编写任何代码!让您的视图决定您的模型。你不必再像在关系世界中那样把你的对象变成二维的。现在可以存储具有形状的对象
是的,这是对痛苦的一个简单解释,但它帮助我忘记了数据库,只是制作了一个应用程序。到目前为止,我已经使用这一理念制作了4个应用程序引擎应用程序,还有更多的应用程序要开发。如果你习惯于考虑ORM映射实体,那么这就是基于实体的数据存储(如谷歌的应用程序引擎)的基本工作原理。对于类似连接的内容,您可以查看。您不必担心它是否使用BigTable作为后端,因为后端是由GQL和数据存储API接口抽象的。与“传统”关系数据库相比,App Engine数据存储有两个主要方面需要习惯:
- 数据存储区不区分插入和更新。对实体调用put()时,该实体将使用其唯一键存储到数据存储中,并且具有该键的任何内容都将被覆盖。基本上,数据存储中的每种实体都像一个巨大的地图或排序列表
- 正如您所提到的,查询要有限得多。首先,不要加入
就如何更改数据表示方式而言,最重要的是预计算。与其在查询时进行连接,不如预先计算数据并尽可能将其存储在数据存储中。如果您想要选取一条随机记录,请生成一个随机数并将其与每条记录一起存储。这类技巧和窍门有一整本食谱。当人们出来时,我总是咯咯地笑——这不是关系。我已经用django编写了cellectr,下面是我模型的一个片段。正如您将看到的,我有一些由用户管理或指导的联盟。我可以从一个联盟得到所有的经理,或者从一个给定的用户我可以返回她所指导或经理的联盟 仅仅因为没有特定的外键支持,并不意味着不能有一个具有关系的数据库模型 我的两便士
看看Objectify文档。页面底部的第一条评论是: “不错,虽然您写这篇文章是为了描述Objectify,但它也是我读过的appengine数据存储本身最简洁的解释之一。谢谢。”
我来自关系数据库世界,然后我发现了这个数据存储。这件事花了好几天时间才弄明白。这是我的一些发现 您一定已经知道数据存储是按比例构建的,这就是它与RDMBS的区别所在。为了更好地扩展大型数据集,AppEngine做了一些更改(有些更改意味着很多更改) RDBMS与数据存储的对比
结构
在数据库中,我们通常以表、行的形式构造数据,而表、行就是数据存储中的数据 关系
在RDBMS中,大多数人在数据存储中遵循一对一、多对一、多对多的关系,因为它具有“无连接”的特性,但我们仍然可以使用“Ref”实现规范化
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()