简体   繁体   English

Google云数据存储区仅存储唯一的实体

[英]Google cloud datastore only store unique entity

I am trying to learn NoSQL with Google Datastore but I am running into a problem with uniqueness. 我正在尝试使用Google Datastore学习NoSQL,但我遇到了一个独特的问题。

Consider an ecommerce store, it has categories and products. 考虑一个电子商务商店,它有类别和产品。

You do not want two products of the same SKU in the database. 您不希望数据库中有两个相同SKU的产品。

So I insert an entity with JSON: 所以我插入一个带有JSON的实体:

{"sku": 1234, "product_name": "Test product"}

And it shows up with two fields. 它显示有两个字段。 But then I can do that again and I have two or more identical products. 但是我可以再次这样做,我有两个或更多相同的产品。

How do you avoid this? 你怎么避免这个? Can you make the sku field unique? 你能让sku领域独一无二吗?

Do I need to do a query before insert? 在插入之前我是否需要进行查询?

The same issue arises with categories. 类别也会出现同样的问题。 Should I just use one entity for ALL my categories and stucture it in my JSON? 我应该只为我的所有类别使用一个实体并将其构建在我的JSON中吗?

What is a good common practice here? 这里有什么好的常见做法?

Create a new kind called 'sku'. 创建一种名为'sku'的新类型。 When you create a new product, you'll want to do a transactional insert of both the product entity and the sku entity. 创建新产品时,您需要对产品实体和sku实体进行事务性插入。

For example, let's say you want to add a new product with the kind name product with the id of abc : 例如,假设您要添加ID为abc的类型名称product的新产品:

  • "product/abc" = {"sku": 1234, "product_name": "Test product"}

To ensure uniqueness on the property "sku", you'll always want to insert an entity with the kind name sku and the id that equals the property's value: 为了确保属性“sku”的唯一性,您总是希望插入一个名称为sku且id等于属性值的实体:

  • "sku/1234" = {"created": "2017-05-11"}

The above example entity has a property for created date - just something optional I threw in as part of the example. 上面的示例实体具有创建日期的属性 - 只是我作为示例的一部分投入的可选项。

Now, as long as you insert both of these as part of the same transaction, you will be ensuring that the "sku" property has a unique value. 现在,只要您将这两个插入作为同一事务的一部分,您将确保“sku”属性具有唯一值。 This works because: 这是因为:

  • Insert ensures write will fail if the sku entity for that number already exists 插入确保如果该数字的sku实体已存在,则写入将失败
  • The transaction ensures writing the product entity (with the sku value) and the sku entity are atomic - so if the sku isn't unique, writing the sku entity will fail, causing the product entity write to also fail. 事务确保编写产品实体(使用sku值)并且sku实体是原子的 - 因此如果sku不是唯一的,则写入sku实体将失败,导致产品实体写入也失败。

You can use "sku" as an "id" (if it's a number) or "name" (if it's a string) for your entity, instead of storing "sku" as a property. 您可以将“sku”用作实体的“id”(如果是数字)或“name”(如果它是字符串),而不是将“sku”存储为属性。 Then it's guaranteed to be unique as it becomes part of the unique entity key. 然后它保证是唯一的,因为它成为唯一实体键的一部分。

Data model is a big subject but IMO there are two approaches you can choose. 数据模型是一个很大的主题,但IMO有两种方法可供选择。 This is more fundamental rather specific to your question. 这对您的问题更具基础性。 It gives some ideas. 它提供了一些想法。

The first approach – storing a reference as a property 第一种方法 - 将引用存储为属性

Same as thinking of product contains product variants ... 与思考产品包含产品变体相同......

This approach sort of the same from RDBMS world. 这种方法与RDBMS世界的方法相同。 You can create products separately, and each product will have a reference in each product variants. 您可以单独创建产品,每个产品将在每个产品变体中都有参考。 It is similar to how foreign keys work in databases. 它类似于外键在数据库中的工作方式。 So, you will have a new property for the product variant entities, which will contain a reference to the product to which it belongs. 因此,您将拥有产品变体实体的新属性,该属性将包含对其所属产品的引用。 The product attribute will actually contain the key of an entity of the Product Kind. product属性实际上包含Product Kind实体的密钥。 If it sounds confusing this is how u can dissect it. 如果这听起来令人困惑,那么你可以解剖它。 I will use python as example: 我将以python为例:

# product model
class Product(ndb.Model):
    name = ndb.StringProperty()

# product variant model
class ProductVariant(ndb.Model):
    name = ndb.StringProperty()
    price = ndb.IntegerProperty()
    # product key.
    product = ndb.KeyProperty(kind=Product)

hugoboss = Product(name="Hugo Boss", key=ndb.Key(Product, 'hugoboss'))
gap = Product(name="Gap", key=ndb.Key(Gap, 'gap'))

pants1 = ProductVariant(name="Black panst", price=300, product=hugoboss.key)
pants2 = ProductVariant(name="Grey pants", price=200, product=hugoboss.key)
tshirt = ProductVariant(name="White graphic tshirt", price=10, product=gap.key)

pants1.put()
pants2.put()
tshirt.put()

# so lets say give me all pants that has label hugoboss
for pants in ProductVariant.query(ProductVariant.product == hugoboss.key).fetch(10):
    print pants.name

# You should get something:
Black pants
Grey panst

The second approach – a product within the key 第二种方法 - 关键内的产品

To take full advantage of it you need to know about sorting feature of Bigtable(Datastore build on top of Bigtable) row keys and how data manipulated around it. 要充分利用它,您需要了解Bigtable(在Bigtable上构建数据存储)行键的排序功能以及如何围绕它操作数据。 if you want to deep dive there is great paper Bigtable: A Distributed Storage System for Structured Data 如果你想深入研究,那么有很好的论文Bigtable:结构化数据的分布式存储系统

# product model
class Product(ndb.Model):
    name = ndb.StringProperty()

# product variant model
class ProductVariant(ndb.Model):
    name = ndb.StringProperty()
    price = ndb.IntegerProperty()

hugoboss = ndb.Key(Product, 'hugoboss')
gap = ndb.Key(Product, 'gap')

Product(name="Hugo Boss", key=hugoboss).put()
Product(name="Gap", key=gap).put()

pants1 = ProductVariant(name="Black pants", price=300, parent=hugoboss)
pants2 = ProductVariant(name="Grey pants", price=200, parent=hugoboss)
tshirt = ProductVariant(name="White graphic tshirt", price=10, parent=gap)

pants1.put()
pants2.put()
tshirt.put()

# so lets say give me all pants that has label hugoboss
for pants in ProductVariant.query(ancestor=hugoboss).fetch(10):
    print pants.name

# You should get something:
Black pants
Grey pants

Second approach is very powerful! 第二种方法非常强大! I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Google Cloud Datastore-是否可以将交易用于单个根实体? - Google Cloud Datastore - is it possible to use a transaction for a single root entity? 使用带.net api的自定义命名空间在Google Cloud Datastore中存储实体 - Storing entity in Google Cloud Datastore with a custom namespace with .net api Google Cloud Datastore更新实体:Node.js客户端 - Google Cloud Datastore Update Entity: Node.js Client Google数据存储区过度使用实体“种类” - Google Datastore overusing entity “kinds” Google App Engine中的数据存储与云SQL - Datastore vs Cloud SQL in Google App Engine Google Cloud Datastore事务性任务入队 - Google Cloud Datastore transactional task enqueuing 有关为快速写入启动新的Cloud Datastore实体类型的任何提示吗? - Any tips on priming a new Cloud Datastore entity kind for fast write? 谷歌云数据存储 REST API v1 (gqlQuery) - Google Cloud Datastore REST API v1 (gqlQuery) Cloud Firestore相当于AppEngine / Datastore Memcache和Keys-only查询? - Cloud Firestore equivalent of AppEngine/Datastore Memcache and Keys-only queries? 检查Google App Engine数据存储区实体是否具有特定属性 - Check if Google App Engine datastore entity has a particular property
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM