Я занимаюсь разработкой веб-сайта и храню данные каждого веб-сайта в разных базах данных.
Мой вопрос заключается в том, как обращаться с несколькими подключениями к базе данных правильно и эффективно. Все базы данных и код находятся на одном сервереЛучший способ подключения к нескольким базам данных в go postgress
1
A
ответ
1
Я создал свой собственный способ подключения к базе данных нескольких подключений.
первым создать базовый файл для postgre:
type PostgreHost struct {
Driver string
Database string
Username string
Ssl string
Password string
}
type PostgreSystem interface {
Init()
Connect() (*sqlx.DB, error)
}
var logger *log.Logger
func (p PostgreHost) Init() {
logger = log.New(os.Stderr,
"Postgre",
log.Ldate|log.Ltime|log.Lshortfile)
}
func (p *PostgreHost) Connect() (*sqlx.DB, error) {
connection := fmt.Sprintf("user=%v password= %v dbname=%v sslmode=%v", p.Username, p.Password, p.Database, p.Ssl)
db, err := sqlx.Connect(
p.Driver,
connection)
if err != nil {
logger.Fatal(err)
return nil, err
}
return db, nil
}
func GetPostgreDb(postgre PostgreSystem) (*sqlx.DB, error) {
return postgre.Connect()
}
, а затем вызвать его, чтобы создать список соединения, как this:
//we create different types of databse connection here
func SystemConnection() map[string]interface{} {
listConnection := make(map[string]interface{})
var err error
// create redis connection
redisConn := RedisHost{
Address: "localhost:6379",
Password: "",
DB: 0,
}
redisConnection, err := redisConn.Connect()
if err != nil {
panic(err)
}
// create postgre connection
postgreConn := PostgreHost{
Driver: "postgres",
Database: "postgres",
Username: "postgres",
Ssl: "disable",
Password: "root",
}
// you can create your another connection here :
postgreConn2 := PostgreHost{
Driver: "postgres",
Database: "postgres",
Username: "postgres",
Ssl: "disable",
Password: "root",
}
postgreConnection, err := GetPostgreDb(&postgreConn)
if err != nil {
panic(err)
}
postgreConnection2, err := GetPostgreDb(&postgreConn2)
if err != nil {
panic(err)
}
listConnection["redis"] = redisConnection
listConnection["postgre"] = postgreConnection
listConnection["postgre2"] = postgreConnection2
return listConnection
}
и, наконец, назвать все соединения с карты:
//getting list of all the connection.
listConnection := database.SystemConnection()
//getting redis connection convert it from interface to *redisClient.
redisConn := listConnection["redis"].(*redis.Client)
// get postgre connection.
postgreConn := listConnection["postgre"].(*sqlx.DB)
postgreConn2 := listConnection["postgre2"].(*sqlx.DB)
Вы можете получить весь исходный код код от here. он все еще идет вперед, но, надеюсь, вы можете получить эту идею. Надеюсь, поможет.
1
- Иметь контекстную-структуру для представления на сайт
- Этот контекст структура имеет соединение с базой данных
- Когда пользователь вошел в систему, также установить, какой сайт является активным для него/нее (я предполагаю, что учетная запись пользователя может иметь более одного сайта).
- Когда пользователь обращается к серверу, проверьте кук для сайта
- Осторожно использовать семафор, чтобы получить контекст из глобального списка/карты (карта будет
map[string]Context
) на основе имени сайта, полученном из печенья. - Если контекст не существует, создайте экземпляр. Внутри он создает соединение с БД с соответствующей таблицей для сайта и регистрируется в глобальном списке (используйте мьютекс).
- В каждом экземпляре контекста есть таймер на определенные минуты, который сбрасывается при доступе. Когда он истечет (например, когда он не будет доступен в течение определенных минут) или последний пользователь, который владеет сайтом, выйдет из системы, он удалит себя из глобального списка (опять же, используя мьютекс) и отбросит его соединение с БД.