Вопрос

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

Есть ли у кого-нибудь, кто работал с Google Datastore или BigTable, какие-нибудь полезные советы по работе с ними?

Это было полезно?

Решение

Есть две основные вещи, к которым нужно привыкнуть в хранилище данных App Engine по сравнению с "традиционными" реляционными базами данных:

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

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

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

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

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

Другие советы

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

В мире реляционных баз данных вам всегда приходится беспокоиться о нормализации данных и структуре вашей таблицы.Откажись от всего этого.Просто верстайте свою веб-страницу.Выложите их все.А теперь взгляните на них.Ты уже на 2/3 там.

Если вы забудете о том, что размер базы данных имеет значение и данные не должны дублироваться, то вы на 3/4 продвинулись вперед, и вам даже не пришлось писать никакого кода!Позвольте вашим взглядам диктовать ваши Модели.Вам больше не нужно брать свои объекты и делать их двумерными, как в мире отношений.Теперь вы можете хранить объекты с формой.

Да, это упрощенное объяснение тяжелого испытания, но оно помогло мне забыть о базах данных и просто создать приложение.На данный момент я создал 4 приложения App Engine, используя эту философию, и впереди еще больше.

Я всегда посмеиваюсь, когда люди говорят... это не похоже на отношения.Я написал cellectr на django, и вот фрагмент моей модели ниже.Как вы увидите, у меня есть лиги, которыми управляют или тренируют пользователи.Я могу из лиги получить всех менеджеров, или от данного пользователя я могу вернуть лигу, которую она тренирует или менеджеры.

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

Мои два пенса.


class League(BaseModel):
    name = db.StringProperty()    
    managers = db.ListProperty(db.Key) #all the users who can view/edit this league
    coaches = db.ListProperty(db.Key) #all the users who are able to view this league

    def get_managers(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.managers)

    def get_coaches(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.coaches)      

    def __str__(self):
        return self.name

    # Need to delete all the associated games, teams and players
    def delete(self):
        for player in self.leagues_players:
            player.delete()
        for game in self.leagues_games:
            game.delete()
        for team in self.leagues_teams:
            team.delete()            
        super(League, self).delete()

class UserPrefs(db.Model):
    user = db.UserProperty()
    league_ref = db.ReferenceProperty(reference_class=League,
                            collection_name='users') #league the users are managing

    def __str__(self):
        return self.user.nickname

    # many-to-many relationship, a user can coach many leagues, a league can be
    # coached by many users
    @property
    def managing(self):
        return League.gql('WHERE managers = :1', self.key())

    @property
    def coaching(self):
        return League.gql('WHERE coaches = :1', self.key())

    # remove all references to me when I'm deleted
    def delete(self):
        for manager in self.managing:
            manager.managers.remove(self.key())
            manager.put()
        for coach in self.managing:
            coach.coaches.remove(self.key())
            coaches.put()            
        super(UserPrefs, self).delete()    

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

Вы, должно быть, уже знаете, что хранилище данных создается с возможностью масштабирования, и это то, что отличает его от RDMBS.чтобы лучше масштабироваться с большим набором данных, App Engine внес некоторые изменения (некоторые означают множество изменений).

СУБД ПРОТИВ хранилища данных
Структура
В базе данных мы обычно структурируем наши данные в виде таблиц, строк, которые находятся в хранилище данных, становятся Виды и сущности.

Отношения
В СУБД большинство людей придерживаются отношений "Один к одному", "Многие к одному", "Многие ко многим" в хранилище данных, поскольку в нем нет "Соединений", но все же мы можем добиться нашей нормализации, используя "Ссылочное свойство" например , Пример отношения "Один к одному" .

Индексы
Обычно в RDMBS мы создаем индексы, такие как Primary Key, Foreign Key, Unique Key и Index key, чтобы ускорить поиск и повысить производительность нашей базы данных.В хранилище данных вы должны создать по крайней мере один индекс для каждого вида (это будет автоматически генерировать нравится вам это или нет) поскольку datastore выполняет поиск вашей сущности на основе этих индексов, и, поверьте мне, это лучшая часть, в RDBMS вы можете выполнять поиск, используя поле без индекса, хотя это займет некоторое время, но это произойдет.В хранилище данных вы не можете выполнять поиск с использованием неиндексного свойства.

Считать
В RDMBS намного проще подсчитывать (*), но в хранилище данных, пожалуйста, даже не думайте об этом обычным способом (да, есть функция подсчета), поскольку она имеет Лимит в 1000 и стоить это будет столько же небольшая операция как сущность, которая нехороша, но у нас всегда есть хороший выбор, мы можем использовать Счетчики Осколков.

Уникальные ограничения
В RDMBS нам нравится эта функция, не так ли?но у хранилища данных есть свой собственный путь.вы не можете определить свойство как уникальное :(.

Запрос
GAE Datatore предоставляет гораздо более качественную функцию Нравится(О нет!в хранилище данных нет ключевого слова LIKE) SQL, который является GQL.

Вставка/Обновление/Удаление/Выбор данных
Это то, что нас всех интересует, так как в RDMBS нам требуется один запрос для вставки, обновления, удаления и выбора точно так же, как в RDBMS, Datastore имеет put, delete, get (не волнуйтесь слишком), потому что Datastore помещает или получает в терминах Запись, Чтение, Небольшие операции(Читать Затраты на вызовы в хранилище данных) и вот тут-то в действие вступает Моделирование данных.вы должны свести к минимуму эти операции и поддерживать работоспособность вашего приложения.Для Уменьшения Операция чтения вы можете использовать Кэш памяти.

Взгляните на документацию Objectify.В первом комментарии внизу страницы говорится:

"Приятно, хотя вы написали это для описания Objectify, это также одно из самых кратких объяснений самого хранилища данных appengine, которое я когда-либо читал.Благодарю вас."

https://github.com/objectify/objectify/wiki/Concepts

Если вы привыкли думать о объектах, отображенных ORM, то, по сути, именно так работает хранилище данных на основе сущностей, такое как Google App Engine.Для получения чего-то вроде joins вы можете посмотреть на ссылочные свойства.На самом деле вам не нужно беспокоиться о том, использует ли он BigTable для серверной части или что-то еще, поскольку серверная часть абстрагируется интерфейсами GQL и Datastore API.

То, как я смотрю на хранилище данных, заключается в том, что kind идентифицирует таблицу как таковую, а entity - это отдельная строка внутри таблицы.Если бы Google выбрала kind, то это была бы всего лишь одна большая таблица без структуры, и вы могли бы поместить в объект все, что захотите.Другими словами, если сущности не привязаны к виду, вы в значительной степени можете иметь любую структуру для сущности и хранить в одном месте (что-то вроде большого файла без структуры, каждая строка имеет свою собственную структуру).

Теперь вернемся к первоначальному комментарию: Google datastore и bigtable - это две разные вещи, поэтому не путайте Google datastore с datastore data storage sense.Bigtable стоит дороже, чем bigquery (Основная причина, по которой мы его не использовали).В Bigquery действительно есть соответствующие объединения и СУБД, такие как язык sql, и это дешевле, почему бы не использовать bigquery.Тем не менее, bigquery действительно имеет некоторые ограничения, в зависимости от размера ваших данных, с которыми вы можете столкнуться, а можете и не столкнуться.

Кроме того, с точки зрения мышления в терминах хранилища данных, я думаю, правильным утверждением было бы "мышление в терминах баз данных NoSQL".В наши дни их доступно слишком много, но когда дело доходит до продуктов Google, за исключением Google cloud SQL (который является MySQL), все остальное - NoSQL.

Будучи внедренным в мир баз данных, хранилище данных для меня было бы гигантской таблицей (отсюда и название "bigtable").BigTable - плохой пример, хотя и потому, что он делает много других вещей, которые обычная база данных могла бы не делать, и все же это все еще база данных.Скорее всего, если вы не знаете, что вам нужно создать что-то вроде "bigtable" от Google, вас, вероятно, устроит стандартная база данных.Им это нужно, потому что они обрабатывают безумные объемы данных и систем вместе, и ни одна коммерчески доступная система не может действительно выполнить эту работу в точности так, как они могут продемонстрировать, что им нужно, чтобы эта работа была выполнена.

(ссылка на большую таблицу: http://en.wikipedia.org/wiki/BigTable)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top