Замена GQL + Join Table Query для хранилища данных Google App Engine - PullRequest
2 голосов
/ 31 августа 2011

Учитывая следующее отношение «многие ко многим», разработанное в хранилище данных Google App Engine:

Пользователь
ПК : ИД пользователя
Имя

Компания
PK : CompanyID
Имя

CompanyReview
CK CompanyID
CK UserID ReviewContent

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

В настоящее время я делаю следующее:

results = CompanyReview.all().filter('owned_by = ', company).filter('written_by = ', user).fetch(10)

где я могу получить данные из таблицы CompanyReview. Однако в этом случае мне нужно будет сверять данные с UserID из этой таблицы CompanyReview с таблицей User, чтобы получить имена пользователей, которые прокомментировали выбранную компанию.

Есть ли лучшее решение для захвата имени пользователя, все в одном выражении в этом случае или, по крайней мере, лучше оптимизированное решение? Производительность подчеркивается.

1 Ответ

1 голос
/ 02 сентября 2011

Это зависит от того, какая сторона отношения будет иметь больше значений.Как описано в этой статье Google App Engine, документы , вы можете смоделировать отношения «многие ко многим», используя список ключей на одной стороне отношения.«Это означает, что вы должны разместить список на стороне отношения, для которого вы ожидаете, что у вас будет меньше значений».

Если обе стороны отношения будут иметь много значений, то вам действительно понадобится модель CompanyReview.Но обратите внимание на то, что говорится в статье:

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

Это потому, что в модели отношений используется RefereceProperty:

class ContactCompany(db.Model):
    contact = db.ReferenceProperty(Contact,
                                   required=True,
                                   collection_name='companies')
    company = db.ReferenceProperty(Company,
                                   required=True,
                                   collection_name='contacts')
    title = db.StringProperty()

Так что, если в объектах Contact мы попытаемся получить доступ к компаниям, он сделает новый запрос.И если в объектах ContactCompany мы попытаемся получить атрибуты контакта, как в contact_company.contact.name, будет выполнен запрос для этого единственного контакта.Прочитайте ReferencyProperty docs для получения дополнительной информации.

Дополнительно: поскольку вы разбираетесь в производительности, я рекомендую использовать декоратор для возврата в функцию memcaching, и этот превосходный Многоуровневая библиотека хранения для Google App Engine.

...