2014-02-09 6 views
15

Я создаю приложение Google App Engine (python), и я узнаю об общей структуре. Я смотрел учебник и документацию для хранилища данных NDB, и у меня возникли трудности с обволакиванием концепций. У меня большой фон с базами данных SQL, и я никогда не работал с какой-либо другой системой хранения данных, поэтому я думаю, что именно там я столкнулся с трудностями.Простое объяснение Google App Engine NDB Datastore

Мое настоящее понимание таково: хранилище данных NDB представляет собой совокупность объектов (аналогичных записям БД), которые имеют свойства (аналогичные полям/столбцам БД). Объекты создаются с использованием модели (аналогичной схеме БД). Каждый объект имеет ключ, который генерируется для него, когда он хранится. Здесь я столкнулся с проблемой, потому что эти ключи, похоже, не имеют аналогии ни с чем в понятиях SQL DB. Они кажутся похожими на первичные ключи для таблиц, но они более тесно связаны с записями и фактически являются полями. Эти ключи NDB не являются свойствами объектов, но считаются отдельными объектами из объектов. Если объект хранится в хранилище данных, вы можете получить этот объект, используя его ключ.

Один из моих больших вопросов - где вы получаете ключи для этого? В некоторых документах, которые я видел, были показаны примеры, в которых ключи были просто созданы. Я этого не понимаю. Казалось, что когда объекты хранятся, метод put() возвращает ключ, который может быть использован позже. Итак, как вы можете просто создавать ключи и определять идентификаторы, если исходные ключи генерируются хранилищем данных?

Еще одна вещь, с которой я, похоже, борюсь, - это концепция родословной с ключами. Вы можете определить родительские ключи любого типа, который вы хотите. Есть ли для этого предопределенная схема? Например, если у меня был подкласс класса под названием «Человек», и я создал ключ вида «Лицо», могу ли я использовать этот ключ в качестве родителя любого другого типа? Например, если бы я хотел, чтобы ключ «Чистка» был ребенком ключа «Человек», могу ли я затем объявить ключ «Автомобиль» дочерним по отношению к этому же «Человеческому» ключу? Или я не смогу после добавления ключа «Обувь»?

Я бы просто просто объяснил хранилище данных NDB и его API для тех, кто поступает из основного фона SQL.

+2

Забыл все, что вы знаете о SQL, думая о хранилище данных. Хранилище данных хранит целые объекты по ключевым словам, включая имена свойств. В отдельности он создает индексы, соответствующие определенным критериям - некоторые автоматические и некоторые определяемые вручную. Сделайте некоторое чтение - https://developers.google.com/appengine/docs/python/datastore/entities –

+2

Лично я считаю, что было огромной ошибкой включать GQL, потому что люди из фона SQL видят «select * from MyEntity» и сразу начните думать в терминах SQL. Это действительно рецепт для плохо ориентированных приложений. Это просто мое мнение. –

ответ

12

Я думаю, что у вас есть проблемы с избытком в вашем уме. Когда вы создаете сущность, вы можете либо дать ей именованный ключ, который вы выбрали сами, либо оставить это, и позволить хранилищу данных выбрать числовой идентификатор. В любом случае, когда вы вызываете put, хранилище данных вернет ключ, который хранится в форме [<entity_kind>, <id_or_name>] (на самом деле это также включает идентификатор приложения и любое пространство имен, но я оставлю это для ясности).

Вы можете сделать сущности членами группы объектов, предоставив им предок. Этот предок на самом деле не должен ссылаться на существующий объект, хотя обычно это происходит. Все, что происходит с предком, состоит в том, что ключ объекта включает в себя ключ предка: теперь он выглядит как [<parent_entity_kind>, <parent_id_or_name>, <entity_kind>, <id_or_name>]. Теперь вы можете получить только объект, включив его родительский ключ. Таким образом, в вашем примере объект Shoe может быть ребенком Лица, независимо от того, было ли это лицо ранее создано: это ребенок, который знает о предке, а не наоборот.

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

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

+0

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

+0

Я просто взглянул на API, и он выглядит так, как я бы это сделал, перейдя 'entity = Entity (properties = ..., id = '')'. Затем ключ, возвращаемый вызовом 'put()', возвращает ключ с этим идентификатором. Это верно? – jchitel

+1

Да, это так. Или вы можете передать полный объект 'ndb.Key' в качестве параметра' key'. –

7

Datastore keys являются немного более похожими на внутренние идентификаторы строк SQL, но, конечно, не полностью. Идентификаторы в Appengine немного похожи на первичные ключи SQL. Чтобы поддерживать децентрализованное одновременное создание новых ключей многими экземплярами приложений в облаке серверов, AppEngine внутренне генерирует ключи, чтобы гарантировать уникальность. Ваше приложение определяет параметры (идентификатор приложения, необязательное пространство имен, вид и необязательный идентификатор объекта), который AppEngine использует для засеивания его генератора ключей. Если вы не указали идентификатор, AppEngine будет generate a unique numeric identifier, что you can read.

Конечная консистенция требует времени, поэтому время от времени более эффективно до request multiple new keys in bulk. Затем AppEngine генерирует для вас ряд идентификаторов числовых объектов. Вы можете read their values from keys как KeyProperty metadata.

Происхождение используется для group together writes связанных лиц всех видов для целей transactions и isolation. Для этого нет предопределенной схемы, но вы ограничены одним родителем на каждого ребенка.

В вашем примере один конкретный ботинок может иметь определенное лицо как родителя. Другой конкретный ботинок может иметь лошадь в качестве родителя. И у другой обуви нет родителя. Многие субъекты всех видов могут иметь одного и того же родителя, поэтому несколько субъектов автомобилей могут также иметь это начальное лицо как родительское. Хранилище данных является схематичным, поэтому до вашего заявления разрешить или запретить автомобиль иметь лошадь в качестве родителя.

Обратите внимание, что ребенок знает своего родителя, но родитель не знает своих детей, потому что реализация будет влиять на масштабируемость.

Смежные вопросы