Идиоматический способ быстрой загрузки — как заполнить глубокую вложенную ассоциацию с базой данных / sql и pq

#go #eager-loading #populate #sqlx #pq

#Вперед #быстрая загрузка #заполнить #sqlx #pq

Вопрос:

Мне просто интересно, как справиться с запросами на быструю загрузку для извлечения данных с несколькими ассоциациями, позвольте мне объяснить мои модели:

 type User struct {
  Id uint
  Name string
  Username string
  Image string
}

type Post struct {
  Id unit
  Content string
  Author *User // I use user_id in author column for the posts table
  Comments []Comments
}

type Comments struct {
  Id unit
  PostId uint
  Message string
  CommentBy *User // I use user_id in comment_by column for the comments table
}
  

Это пример извлеченных данных:

 {
    "Posts": [
        {
            "Id": 1,
            "Content": "test post",
            "Author": {
                  "Id": 1,
                  "Name": "author",
                  "Username": "h3ll0",
                  "Image": "author.png"
            },
            "Comments": [
                {
                    "Id": 1,
                    "PostId": 1,
                    "Message": "good article",
                    "CommentBy": {
                        "Id": 2,
                        "Name": "second user",
                        "Username": "r3ader",
                        "Image": "reader.png"
                    }
                },
                {
                    "Id": 2,
                    "PostId": 1,
                    "Message": "bad article",
                    "CommentBy": {
                        "Id": 3,
                        "Name": "third user",
                        "Username": "thirD",
                        "Image": "third.png"
                    }
                }
            ]
        }
    ]
}
  

Я хочу получить данные post со всеми вложенными ассоциациями и сопоставить их со структурой Post. Как бы вы это сделали с базой данных / sql и pq (драйвер Postgres)?

Я вообще не хочу использовать какой-либо ORM, я использую только database / SQL и SQLx.

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

Комментарии:

1. Я бы сказал, что вы делаете 3 вызова: получаете пользователя, получаете все сообщения для пользователя и получаете все комментарии для всех идентификаторов сообщений, которые вы получили в предыдущем вызове. Затем объединить на клиенте. Выполнить один вызов, который объединяет 3 таблицы в базе данных, вероятно, медленнее (особенно если таблицы большие), но я бы написал тест, чтобы убедиться, что он действительно медленнее. Последний вариант — использовать другую базу данных, которая лучше подходит для этого типа данных. Одна вещь, в которой реляционная база данных плоха, это relations . Графическая база данных или база данных на основе документов могли бы быть более подходящими. Поскольку я не знаю всего вашего варианта использования, я не могу принять это решение.

2. спасибо за комментарий, я работаю над информационно-ориентированным приложением. Я рассматривал возможность использования NoSQL DB, такого как Cassandra, или даже графических баз данных, таких как dgraph , но в настоящее время я использую Postgres. Я упростил модели в примере, реальные модели данных имеют сложную структуру, представьте, что у сообщения может быть несколько вложений, участников, комментариев, а само вложение имеет несколько ссылок, и я хочу сразу заполнить агрегированные данные, было бы здорово, если бы вы помогли мне и предложили правильное решение для базы данных, мы находимся на ранней стадии, миграция БД не составит труда.

3. draph — отличный способ работать с данными, которые имеют множество связей по идентификатору. Похоже, это может сработать для вашего варианта использования. Недавно мы использовали ее в проекте, но были вынуждены отказаться от нее, поскольку у нас была связь по временным рамкам, которая на самом деле не подходила для dgraph (или мы не нашли способ правильно выполнить это).

4. отлично, а что насчет клиента dgraph go? Достаточно ли он зрелый, чтобы использовать его на производстве?

5. У нас также есть cassandra в производстве. Вариант использования cassandra — это надежное время отклика на таймфрейме 10-20 мс при огромных объемах данных. В Cassandra нет объединений, и вы не можете запрашивать данные, кроме как по первичному ключу (который может состоять из нескольких столбцов). Могут быть вторичные ключи, но это может значительно снизить производительность.