与祖先一起设计数据存储模型
Datastore model design with ancestors
我现在已经将 Datastore 用于两个项目,但是对于这两个项目我都未能利用祖先关系。经过大量阅读和研究,我相信我终于明白了如何设计出色的 Datastore 模型。
想象一个类似于 Reddit/Instagram 的站点,用户可以在其中创建自己的类别(类似于 Subreddits),其他用户可以订阅这些类别。用户可以相互关注,不同用户上传的图片将被上传到这些类别,并显示在特定用户的个人资料下(如 Instagram)。考虑到这一点,这就是我认为的理想设计:
Category
- User
- - Image
- Subscriber
User
- Follower
- Following
使用此数据存储模型,我相信应该可以轻松检索 'user id' 或 'category id' 上传的所有图像、订阅 'category id' 的所有用户、上传到 'category id'。所有关注或被关注 'user id' 的用户,所有被 'user id' 关注的用户上传的图片。
我非常感谢一些数据存储专家的反馈和改进它的潜在方法(我特别好奇在两个不同的位置使用 'User' 作为祖先是否有任何问题,这是一个child 到 'Category' 在一个地方而不是另一个地方)..
我希望这会有助于使问题更详细understandable/answerable :)
我有以下实体:
Category
- ID int64
- Name string
- etc..
User
- Username string (NameKey)
- Password []byte
- etc..
Image
- ID int64
- StorageID string
- MD5Hash string
- etc..
Follow
- ID int64
- Follower string
- Following string
其中类别、用户、图像和关注是实体,ID、名称、用户名等是 属性 名称。
因此图像实体将是用户(上传图像的人)和类别祖先的后代
Follow 实体将继承自 User 祖先
至于 Subscriber 我不确定是否最好创建一个类似于 Follow 的全新实体(在这种情况下它可能包括用户首次订阅的日期),或者让它成为 属性
实体组(具有相同根祖先的所有实体,包括根祖先)在查询时更多的是一致性单元。这种设计的一个问题是扩展,因为实体组被限制为每秒持续 1 个事务(您可以突发更高)。
使用当前的设计,您在单个类别中的所有查询都将高度一致,但您将被限制为每秒 1 张新图像。
由于对一个类别中的所有图像拥有高度一致的视图可能不如确保您可以处理增长那么重要,因此最好让图像从根用户实体下降(这样用户看起来因为他们自己的图像是高度一致的)并且在图像实体的 属性 中有类别只是一个 id。
Category
- ID int64
- Name string
- OwnerUserID string
- etc..
User
- Username string (NameKey)
- Password []byte
- etc..
Image (descends from User)
- ID int64
- StorageID string
- MD5Hash string
- CategoryID int64
- etc..
现在列出用户 123 的所有图像(高度一致):
SELECT * FROM Image WHERE __key__ HAS ANCESTOR (User, 123)
列出类别 456 中用户 123 的所有图像(高度一致):
SELECT * FROM Image WHERE __key__ HAS ANCESTOR (User, 123) AND CategoryID = 456
列出类别456中的所有图像(最终一致):
SELECT * FROM Image WHERE CategoryID = 456
列出所有图片(最终一致)
SELECT * FROM Image
我现在已经将 Datastore 用于两个项目,但是对于这两个项目我都未能利用祖先关系。经过大量阅读和研究,我相信我终于明白了如何设计出色的 Datastore 模型。
想象一个类似于 Reddit/Instagram 的站点,用户可以在其中创建自己的类别(类似于 Subreddits),其他用户可以订阅这些类别。用户可以相互关注,不同用户上传的图片将被上传到这些类别,并显示在特定用户的个人资料下(如 Instagram)。考虑到这一点,这就是我认为的理想设计:
Category
- User
- - Image
- Subscriber
User
- Follower
- Following
使用此数据存储模型,我相信应该可以轻松检索 'user id' 或 'category id' 上传的所有图像、订阅 'category id' 的所有用户、上传到 'category id'。所有关注或被关注 'user id' 的用户,所有被 'user id' 关注的用户上传的图片。
我非常感谢一些数据存储专家的反馈和改进它的潜在方法(我特别好奇在两个不同的位置使用 'User' 作为祖先是否有任何问题,这是一个child 到 'Category' 在一个地方而不是另一个地方)..
我希望这会有助于使问题更详细understandable/answerable :)
我有以下实体:
Category
- ID int64
- Name string
- etc..
User
- Username string (NameKey)
- Password []byte
- etc..
Image
- ID int64
- StorageID string
- MD5Hash string
- etc..
Follow
- ID int64
- Follower string
- Following string
其中类别、用户、图像和关注是实体,ID、名称、用户名等是 属性 名称。
因此图像实体将是用户(上传图像的人)和类别祖先的后代
Follow 实体将继承自 User 祖先
至于 Subscriber 我不确定是否最好创建一个类似于 Follow 的全新实体(在这种情况下它可能包括用户首次订阅的日期),或者让它成为 属性
实体组(具有相同根祖先的所有实体,包括根祖先)在查询时更多的是一致性单元。这种设计的一个问题是扩展,因为实体组被限制为每秒持续 1 个事务(您可以突发更高)。
使用当前的设计,您在单个类别中的所有查询都将高度一致,但您将被限制为每秒 1 张新图像。
由于对一个类别中的所有图像拥有高度一致的视图可能不如确保您可以处理增长那么重要,因此最好让图像从根用户实体下降(这样用户看起来因为他们自己的图像是高度一致的)并且在图像实体的 属性 中有类别只是一个 id。
Category
- ID int64
- Name string
- OwnerUserID string
- etc..
User
- Username string (NameKey)
- Password []byte
- etc..
Image (descends from User)
- ID int64
- StorageID string
- MD5Hash string
- CategoryID int64
- etc..
现在列出用户 123 的所有图像(高度一致):
SELECT * FROM Image WHERE __key__ HAS ANCESTOR (User, 123)
列出类别 456 中用户 123 的所有图像(高度一致):
SELECT * FROM Image WHERE __key__ HAS ANCESTOR (User, 123) AND CategoryID = 456
列出类别456中的所有图像(最终一致):
SELECT * FROM Image WHERE CategoryID = 456
列出所有图片(最终一致)
SELECT * FROM Image