Извлечение множества связанных данных в единую структуру - PullRequest
1 голос
/ 18 апреля 2019

Я пытаюсь встроить систему авторизации RBAC в приложение. Пользователи, роли и разрешения хранятся в базе данных. Каждая роль может быть назначена каждому пользователю. Вот почему у меня есть таблицы user_account и role, склеенные во взаимосвязь «многие ко многим» с помощью соединительной таблицы user_role. Урезанный, настройка базы данных выглядит следующим образом:

CREATE TABLE user_account (
    id    uuid NOT NULL DEFAULT uuid_generate_v1mc(),
    email character varying(128) NOT NULL,
    CONSTRAINT user_account_pkey PRIMARY KEY (id),
    CONSTRAINT user_account_email_key UNIQUE (email)
);

CREATE TABLE role (
    id   uuid NOT NULL DEFAULT uuid_generate_v1mc(),
    name character varying(128) NOT NULL,
    CONSTRAINT role_pkey PRIMARY KEY (id),
    CONSTRAINT role_name_key UNIQUE (name)
);

CREATE TABLE user_role (
    user_id uuid NOT NULL,
    role_id uuid NOT NULL,
    CONSTRAINT user_role_pkey PRIMARY KEY (user_id, role_id),
    CONSTRAINT user_role_fkey_user FOREIGN KEY (user_id) REFERENCES user_account (id) ON DELETE CASCADE,
    CONSTRAINT user_role_fkey_role FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE CASCADE
);

Очевидно, я настроил соответствующие структуры го:

type User struct {
    ID    string `db:"id"`
    Email string `db:"email"`
}

type Role struct {
    ID   string `db:"id"`
    Name string `db:"name"`
}

Пока все хорошо. Извлечение одной или нескольких строк по отдельности в соответствующую структуру go не является проблемой. Но я бы предпочел получить пользователя и все назначенные ему роли. Полученная структура go будет выглядеть примерно так:

type User struct {
    ID    string `db:"id"`
    Email string `db:"email"`
    Roles []Role 
}

Что я спрашиваю: какова лучшая стратегия для извлечения данных в структуру?

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

или

  1. Получить запись пользователя и все назначенные ему роли одним запросом.

Я знаю, как сделать первый случай, но бороться со вторым. Я использую sqlx и PostgreSQL. Возможно ли даже то, чего я пытаюсь достичь? Если да, то как? Какой тег db использовать?

Мой наивный запрос для второго подхода выглядит следующим образом, но, очевидно, не работает должным образом:

SELECT user_account.id, user_account.email, role.id, role.name
  FROM user_account
LEFT OUTER JOIN user_role
  ON user_account.id = user_role.user_id
LEFT OUTER JOIN role
  ON user_role.role_id = role.id

Есть предложения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...