如何在AppEngine的Datastore中使用Go语言建模多对多关系?

huangapple go评论78阅读模式
英文:

How do I model a many-to-many relationship in AppEngine's Datastore in Go?

问题

我正在努力理解如何在Go编程语言的AppEngine Datastore中表示多对多关系。我更习惯于传统的关系型数据库。

我的系统中有两种类型的实体。我们称它们为AB。每个A实体与一些B实体相关联。同样,每个B实体与一些其他A实体相关联。我希望能够高效地查询给定A实体的所有B实体,以及给定B实体的所有A实体。

在Python SDK中,似乎有一种方法可以将实体中的字段标记为ReferenceProperty,引用其他实体。然而,在Go的AppEngine SDK中,我找不到类似的东西。Go似乎只使用基本的struct来表示实体。

处理这个问题的最佳实践是什么?

英文:

I'm trying to wrap my head around how I can represent a many-to-many relationship inside of AppEngine's Datastore in the Go Programming Language. I'm more used to traditional relational databases.

I have two types of entities in my system. Let's call them A and B. Every A entity is related to some number of B entities. Similarly, every B entity is related to some other number of A entities. I'd like to be able to efficiently query for all B entities given an A entity, and for all A entities given a Bentity.

In the Python SDK, there seems to be a way to note fields in an entity can be ReferencePropertys which reference some other entity. However, I can't find something similar in Go's AppEngine SDK. Go seems to just use basic structs to represent entities.

What's the best practice for dealing with this?

答案1

得分: 1

根据您希望查询的方式,您可以执行以下操作:

在您的结构体A中添加一个字段:

BIds []int64

在您的结构体B中添加一个字段:

AIds []int64

现在,每当您在A和B之间建立关系时,只需将相应的id添加到您的两个变量中。

当您现在需要查询与A1相关的所有B时,您可以按如下方式进行查询:

SELECT * FROM B where AIds = 'A1'

对于与B1相关的所有A,您可以类似地进行查询:

SELECT * FROM A where BIds = 'B1'

更新:
根据dragonx的建议修改了查询语句。

英文:

based on how you which to query you could do the following:

in your struct A add a field:

BIds []int64

in your struct B add a field:

AIds []int64

now any time you add a relation between A and B you just need to add the corresponding ids to your two variables

when you need to query now for all B which are related to this A1 you do your query like this:

SELECT * FROM B where AIds = 'A1'

for all A wich are related to this B1 your do it similar:

SELECT * FROM A where BIds = 'B1'

update:
altered querys on suggestion from dragonx

答案2

得分: 1

一个Python的ReferenceProperty实际上存储了对另一个实体的键。这类似于在Go中使用Key字段。

解决你的问题至少有两种方法。一种是存储有限数量的引用的廉价方法,另一种是针对较大数据集的昂贵方法。

fmt.Println.MKO提供了廉价方法的答案,除了他建议的查询比他建议的更简单,实际上应该是:

SELECT * FROM B where AIds = 'A1'

这种方法受限于每个实体的索引条目数量以及实体大小。因此,AIds或BIds的列表将限制实体的数量为20000个或更少。

如果你有大量的数据,你会想要一个映射实体来表示给定A和B实体之间的M2M关系。它只需包含对A和B的键。然后你将查询映射实体,然后获取你需要的相应的A或B实体。这将更加昂贵,但可以突破实体大小限制。

英文:

A python ReferenceProperty essentially stores a key to another entity. It's similar to using a Key field in Go.

There's at least two ways to solve your problem. A cheap way to store a limited number of references, and an expensive way for larger data sets.

fmt.Println.MKO provided the answer for the cheap way, except the query is simpler than what he suggests, it should actually be:

SELECT * FROM B where AIds = 'A1'

This method is limited to the number of indexed entries per entity, as well as the entity size. So the list of AIds or BIds will limit the number of entities to 20000 or less.

If you have an insane amount of data, you would want a mapping entity to represent the M2M relationship between a given A & B entity. It would simply contain a key to an A and a key to a B. You would then query for map entities, and then fetch the corresponding A or B entities you need. This would be much more expensive, but breaks past the entity size limit.

huangapple
  • 本文由 发表于 2013年6月29日 02:22:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/17371244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定