Vapor 3: Использование нескольких баз данных - PullRequest
0 голосов
/ 03 марта 2019

Используя Vapor 3, существует ли простой способ переключения баз данных при работающем сервере?

Например, пользователь входит в систему, используя базу данных 'login'.Затем я установил базу данных для этого пользователя в их куки.Любые последующие запросы от этого пользователя затем используют базу данных, указанную в файле cookie («пользователь» в этом сценарии действительно будет компанией).

Все базы данных будут принадлежать к одному семейству баз данных (например, MySQL).Это позволит хранить данные каждой компании в своих собственных БД и ограничивать размер каждого БД (и, надеюсь, в целом операции с БД будут выполняться быстрее).Кроме того, любая необходимость в восстановлении БД повлияет только на одну компанию, и резервное копирование будет проще.

  1. Как этого добиться?
  2. Это будет очень неэффективно?

Есть ли другие лучшие способы добиться этого?

1 Ответ

0 голосов
/ 03 марта 2019

Насколько я понимаю, вы можете создать несколько разных идентификаторов базы данных, таких как:

extension DatabaseIdentifier {
    static var db1: DatabaseIdentifier<MySQLDatabase> {
        return .init("db1")
    }
    static var db2: DatabaseIdentifier< MySQLDatabase > {
        return .init("db2")
    }
}

, а затем зарегистрировать их в configure.swift, как это

let db1 = MySQLDatabase(config: MySQLDatabaseConfig(hostname: "localhost", username: "root", database: "db1"))
let db2 = MySQLDatabase(config: MySQLDatabaseConfig(hostname: "localhost", username: "root", database: "db2"))
var databaseConfig = DatabasesConfig()
databaseConfig.add(database: db1, as: .db1)
databaseConfig.add(database: db2, as: .db2)
services.register(databaseConfig)

, после этого незабудьте использовать идентификаторы .db1 и .db2 везде вместо значений по умолчанию .mysql (для MySQL), например, в миграциях

migrations.add(model: User.self, database: .db1)

с пулами соединений

return req.requestPooledConnection(to: . db1).flatMap { conn in
    defer { try? req.releasePooledConnection(conn, to: . db1) }
    return User.query(on: conn).all()
}

и в транзакциях

return req.transaction(on: .db1) { conn in
    return User.query(on: conn).all()
}

Извините, если я не ответил на ваши вопросы.Я понимаю, что было бы замечательно, если бы Fluent мог поддерживать передачу имени базы данных для каждого запроса, но я не нашел этого в нем.(или не совсем понятно, как передать имя базы данных по запросу)

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

...