Моделирование данных в RethinkDB
Существует два способа моделирования отношений между документами в RethinkDB:
- Использование вложенных массивов.
- Связывание документов, хранящихся в нескольких таблицах (аналогично традиционным реляционным базам данных).
Давайте рассмотрим преимущества и недостатки каждого подхода. Мы будем использовать простую базу данных блога, которая хранит информацию об авторах и их постах, для демонстрации.
Использование вложенных массивов
Мы можем смоделировать отношение между авторами и постами, используя вложенные массивы следующим образом. Рассмотрим пример документа в таблице authors:
{
"id": "7644aaf2-9928-4231-aa68-4e65e31bf219",
"name": "William Adama", "tv_show": "Battlestar Galactica",
"posts": [
{"title": "Decommissioning speech", "content": "The Cylon War is long over..."},
{"title": "We are at war", "content": "Moments ago, this ship received..."},
{"title": "The new Earth", "content": "The discoveries of the past few days..."}
]
}
Таблица authors содержит документ для каждого автора. Каждый документ содержит информацию об авторе и поле posts с массивом постов для этого автора. В этом случае запрос для получения всех авторов с их постами прост:
# Retrieve all authors with their posts
r.db("blog").table("authors").run()
# Retrieve a single author with her posts
r.db("blog").table("authors").get(AUTHOR_ID).run()
Преимущества использования вложенных массивов:
- Запросы для доступа к авторам и постам обычно проще.
- Данные часто размещаются совместно на диске. Если набор данных не помещается в оперативную память, данные загружаются с диска быстрее.
- Любое обновление документа автора атомарно обновляет как данные об авторе, так и данные о постах.
Недостатки использования вложенных массивов:
- Удаление, добавление или обновление поста требует загрузки всего массива
posts, его изменения и записи всего документа обратно на диск.- Из-за предыдущего ограничения лучше всего ограничивать размер массива
postsнесколькими сотнями документов.
Связывание документов в нескольких таблицах
Можно использовать технику реляционного моделирования данных и создать две таблицы для хранения данных. Типичный документ в таблице authors будет выглядеть так:
{
"id": "7644aaf2-9928-4231-aa68-4e65e31bf219",
"name": "William Adama",
"tv_show": "Battlestar Galactica"
}
Типичный документ в таблице posts будет выглядеть так:
{
"id": "064058b6-cea9-4117-b92d-c911027a725a",
"author_id": "7644aaf2-9928-4231-aa68-4e65e31bf219",
"title": "Decommissioning speech",
"content": "The Cylon War is long over..."
}
Каждый пост содержит поле author_id, которое связывает каждый пост с его автором. Мы можем получить все посты для данного автора следующим образом:
# If we have a secondary index on `author_id` in the table `posts`
r.db("blog").table("posts").
get_all("7644aaf2-9928-4231-aa68-4e65e31bf219", index="author_id").
run()
# If we didn't build a secondary index on `author_id`
r.db("blog").table("posts").
filter({"author_id": "7644aaf2-9928-4231-aa68-4e65e31bf219"}).
run()
В реляционной базе данных мы бы здесь использовали JOIN; в RethinkDB мы используем команду eq_join. Чтобы получить все посты вместе с информацией об авторе для Уильяма Адамы:
# In order for this query to work, we need to have a secondary index
# on the `author_id` field of the table `posts`.
r.db("blog").table("authors").get_all("7644aaf2-9928-4231-aa68-4e65e31bf219").eq_join(
'id',
r.db("blog").table("posts"),
index='author_id'
).zip().run()
Обратите внимание, что значения для author_id соответствуют полю id автора, что позволяет нам связать документы.
Преимущества использования нескольких таблиц:
- Операции с авторами и постами не требуют загрузки данных для каждого поста для данного автора в память.
- Нет ограничений на количество постов, поэтому этот подход более подходит для больших объемов данных.
Недостатки использования нескольких таблиц:
- Запросы, связывающие данные между авторами и их постами, имеют тенденцию быть более сложными.
- С этим подходом невозможно атомарно обновить как данные об авторе, так и данные о постах.
Подробнее
Есть отдельная статья Объединения таблиц в RethinkDB со значительно большей информацией о подходе с несколькими таблицами, включая то, как выполнить эквиваленты ReQL для внутренних, внешних и поперечных соединений. Если вы не уверены, какой схему использовать, задайте вопрос на Stack Overflow или присоединитесь к каналу IRC #rethinkdb на Freenode.
© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/docs/data-modeling/