• Официальный сайт SDK
  • Сайт с примерами кода

Ключи и группы объектов

Каждый объект в хранилище имеет ключ - уникальный идентификатор этого объекта внутри одного приложения. Ключ состоит из нескольких компонентов: пути, описывающим родительские отношения между этим объектом и другим, тип объекта и либо его имя, присвоенное приложением, либо числовой идентификатор, присвоенный хранилищем.

Типы и идентификаторы

Каждый объект имеет собственный тип, и над группой из таких однотипных объектов может быть осуществлена операция запроса. В отличии от строк одной таблицы базы данных, два объекта одного типа могут не иметь одного набора свойств, хотя и приложение может устанавливать такие ограничения в модели данных. Интерфейс Datastore API использует для создания моделей одного типа базовые классы Model (или Expando).

К примеру, задано определение класса модели, названного "Story":

CmNsYXNzIFN0b3J5KGRiLk1vZGVsKToKdGl0bGUgPSBkYi5TdHJpbmdQcm9wZXJ0eSgpCmF1dGhvciA9IGRiLlN0cmluZ1Byb3BlcnR5KCkK=

Каждый объект имеет свой идентификатор. Приложение может присваивать объектам собственные идентификаторы (имена объектов) путем передачи их конструктору модели через параметр key_name (значение типа str):

CnMgPSBTdG9yeShrZXlfbmFtZT0mcXVvdDt4enkxMjMmcXVvdDspCg===

Значение параметра key_name сохраняется в качестве юникод строки (с конвертацией из типа str). Значение key_name не должно начинаться на цифру и не может быть вида __*__ (начинаться и заканчиваться двумя символами подчеркивания). Если приложение использует в качестве ключей объектов введенные пользователями значения (например, адреса электронной почты), то оно должно привести их к допустимому виду, к примеру, добавив к ним префикс, заранее удовлетворяющий системным требованиям.

Если значение параметра key_name не было указано, то при первом сохранении в хранилище объекту присваивается цифровой идентификатор.

CnMyID0gU3RvcnkoKSAjINC+0LHRitC10LrRgtGDIHMyINC90LUg0LfQsNC00LDQvSDQuNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgC4KczIucHV0KCkgIyDQvtCx0YrQtdC60YLRgyBzMiDQsNCy0YLQvtC80LDRgtC40YfQtdGB0LrQuCDQt9Cw0LTQsNC10YLRgdGPINC40LTQtdC90YLQuNGE0LjQutCw0YLQvtGALgo==

После того, как объект был создан, его идентификатор не может быть изменен.

Подсказка: Значения идентификаторов объектов не могут быть задействованы параметрах запросов, как это доступно для обычных значений свойств объектов. Однако, вы можете использовать именованный ключ и хранить его значение в отдельном свойстве. Вы можете делать что-то похожее и с числовыми идентификаторами путем сохранения объекта с присвоением ему автоматического идентификатора, получения его с помощью функции obj.key().id(), заданию свойству этого идентификатора и повторного сохранения объекта.

Группы объектов, их предки и пути

Каждый объект принадлежит к группе объектов, набору одного или нескольких объектов, которые могут быть изменены с помощью одной транзакции. Принадлежность объектов к одной группе указывает платформе App Engine на необходимость хранить их в одном месте кластера распределенной сети. Транзакции производят операции над данными хранилища в рамках группы объектов и либо все операции будут применены к этой группе, либо не будет произведено ни одного изменения.

Когда приложение создает новый объект, оно может задать другой объект как родительский по отношению к этому. Выполнение задания родительского объекта помещает новый объект в ту же с ним группу объектов.

Объект без указания родительского является корневым объектом. Объект ,являющийся родительским для другого объекта, также сам может иметь вышестоящего родителя. Цепочка из родительских связей объектов считая от корневого является путем для данного объекта, а все элементы этого пути будут называться предками объекта. Родительский объект может быть определен только при создании нового объекта и не подлежит изменению в дальнейшем.

Каждый объект с заданным корневым объектом в качестве предка относится к одной с ним группе объектов. Все объекты одной группы помещаются на одном узле кластера хранилища. Транзакция может изменять несколько объектов в одной группе или добавлять к ней новые путем указания существующего родительского объекта из этой же группы.

Для получения дополнительной информации о транзакциях, обратитесь к разделу Транзакции.

Если объект, являющийся предком для другого удаляется, его нижестоящий объект автоматически не будет удален. Этот объект остается доступен в хранилище для операций его получения с помощью его ключа или пути.

Вы можете создать объект с указанием пути к предкам без предварительного создания родительских объектов. Чтобы проделать это, создайте ключ для предка с использованием типа и идентификатора, затем используйте его в качестве задания родителя для нового объекта. Все объекты с одинаковым корневым предком будут принадлежать к одной группе, в независимости от того, присутствует ли уже в хранилище корневой элемент.

Подсказки по использованию групп объектов:

  • Используйте группы объектов только в том случае, если для работы приложения требуются транзакции. Для задания других отношений между двумя объектами используйте свойства типа ReferenceProperty и значения класса Key, которые могут быть использованы в запросах.
  • Чем больше групп объектов ваше приложение будет использовать, тем больше будет корневых объектов и тем более эффективнее хранилище сможет распределять данные групп объектов между разными узлами распределенной сети. Более интенсивное распределение улучшает производительность для операций создания и изменения данных. Также, в том в случае если множество пользователей пытаются одновременно произвести изменения объектов одной группы, для некоторых из них возможна ситуация, когда часть транзакций не сможет быть зафиксирована. По этой причине не помещайте все объекты данных приложения под одним корневым элементом.
  • Хорошим правилом будет дробление групп объектов до размера средних данных одного пользователя или того меньше.
  • Разделение объектов на группы не оказывает значительного влияния на скорость работы запросов.

Пути объектов и уникальность их ключей

Полный ключ для объекта, включающий в себя путь, его тип и имя или числовой идентификатор, является уникальным значением для этого объекта. Значение ключа объекта присваивается ему при создании и ни одна из его составляющих частей в дальнейшем не может быть изменена.

Компоненты ключей для двух различных объектов могут частично совпадать, но должны отличаться хотя бы одним элементом. К примеру, два объекта могут иметь один тип и имя в том случае, если они имеют различных родителей. Подобно этому два объекта могут иметь одного и того же родителя (или вообще не иметь его) и совпадающие имена, но быть разных типов.

Приложение не должно полагаться на то, что числовые идентификаторы будут присваиваться объектам в возрастающем порядке по времени создания объектов. Несмотря на то, что это обычно так и бывает, такое поведение системы постоянно не гарантируется.