如何管理与MySQL实例和多个数据库的数据库连接?

huangapple go评论56阅读模式
英文:

How to manage database connections to a MySQL instance and multiple databases?

问题

我有一个 MySQL 实例,为每个用户创建了一个数据库。
我想构建一个 API,应该连接到调用它的用户相应的数据库。

针对这种设置,管理数据库连接的最佳方式是什么?

在 mysql 节点包的文档中,我找到了以下两个选项:

1)为整个实例创建一个连接池,然后使用changeUser连接到数据库,例如这样:

const pool = createPool({
    connectionLimit: 10,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    port: 3306, // 默认
    host: process.env.SQL_INSTANCE_HOST,
  })

const connection = await pool.getConnection();
connection.changeUser({ database: userDatabase }, (err) => {
    throw new Error(`Could not connect to database: ${err}`);
  });
// 使用连接,使用后释放

2)使用PoolCluster为每个数据库创建一个连接池,然后使用调用与用户对应的池:

const poolCluster = mysql.createPoolCluster();
poolCluster.add('USER1', config1);
poolCluster.add('USER2', config2);
poolCluster.add('USER3', config3);

const pool = poolCluster.of('USER1');
pool.query(function (error, results, fields) {
  // 执行查询
});

对早期问题的回答中,有人表示倾向于使用 PoolCluster 而不是 changeUser,但没有确切解释原因。

使用一种选项而不是另一种选项可能有哪些优缺点?
还有其他需要考虑的选项吗?

英文:

I have one MySQL instance with one database for each user.
I want to build an API that should connect to the right database depending on the user calling it.

For this setup what is the best way to manage database connections?

In the documentation of the mysql node package I found the following two options:

  1. Create one pool for the whole instance, then use changeUser to connect to the database,
    for example like this:
const pool = createPool({
    connectionLimit: 10,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    port: 3306, // default
    host: process.env.SQL_INSTANCE_HOST,
  })

const connection = await pool.getConnection();
connection.changeUser({ database: userDatabase }, (err) => {
    throw new Error(`Could not connect to database: ${err}`);
  });
// use connection, release it after usage
  1. Use PoolCluster to create one pool for each database, then use the call the pool corresponding to the user:
const poolCluster = mysql.createPoolCluster();
poolCluster.add('USER1', config1);
poolCluster.add('USER2', config2);
poolCluster.add('USER3', config3);

const pool = poolCluster.of('USER1');
pool.query(function (error, results, fields) {
  // perform query
});

In an answer to an earlier question someone expressed the preference for using PoolCluster over changeUser but without exactly explaining why.

What might be the pros and cons of using one option over another?
Are there other options to consider?

答案1

得分: 0

Creating 1 database per user is a pretty unusual design. There's some cases where this may make sense, so I want to give you the benefit of the doubt and assume you have a really good reason to.

My assumption is that you're using Node to build some API or webservice, so broadly I think you have 2 options:

  1. If you need to make a separate connection per user, then I think I would not use any pools at all because users will hit your service sparingly and it's just not worth keeping any connections open.
  2. If you can re-use the connection for multiple users, then just use a regular pool.

For example, if you have 1 username/password to access MySQL you could prefix every table with the database name:

SELECT * FROM databasename.tablename

If you prefix everything, there's not really anything special you need to do. Just make one pool for everyone.

英文:

Creating 1 database per user is a pretty unusual design. There's some cases where this may make sense, so I want to give you the benefit of the doubt and assume you have a really good reason to.

My assumption is that you're using Node to build some API or webservice, so broadly I think you have 2 options:

  1. If you need to make a separate connection per user, then I think I would not use any pools at all because users will hit your service sparingly and it's just not worth keeping any connections open.
  2. If you can re-use the connection for multiple users, then just use a regular pool.

For example, if you have 1 username/password to access MySQL you could prefix every table with the database name:

SELECT * FROM databasename.tablename

If you prefix everything, there's not really anything special you need to do. Just make one pool for everyone.

答案2

得分: 0

池用于同类连接。例如,对同一数据库有多个待机连接。

这里有两种情况 -

  1. 所有数据库使用相同的用户名和密码 - 您应该避免定期轮询。您可以使用Redis来重用连接。

  2. 所有数据库使用不同的用户名和密码 -

    • 首先,您需要将数据库凭据存储在主数据库中,与用户映射到相应的数据库。
    • 您可以将数据库连接存储在Redis中,而不是每次都创建数据库。
    • 您可以检查Redis中是否有可用于此特定数据库的连接,如果有,则使用它,否则创建它并将其存储在Redis中以供将来使用。
英文:

Pools are used for homogenous connections. e.g. Multiple stand-by connections to the same database.

Here is two scenarios -

  1. Same username and password for all the Databases - You should avoid regular polling. You can use Redis to reuse the connections.

  2. Different username and password for all the Databases -

    • First you need to store the database credentials in master DB with mapped database with user.
    • You can store your database connection in Redis instead of creating database every time.
    • You can check connection is available in Redis for this particular database use it otherwise create it and store it in Redis for future use.

答案3

得分: 0

I suggest using Devart's MySQL ODBC driver to manage database connections in the API. After the link is established, users who can call API can dynamically switch databases. Configuration items are also very simple. Simply configure your API to accept user credentials or identifiers as input and use them to determine the appropriate database to connect to. I think this should be the most flexible and efficient solution.

英文:

Proceed from the demand (manage multiple databases under the same instance through API, and use unused users).
I suggest using Devart's MySQL ODBC driver to manage database connections in the API. After the link is established, users who can call API can dynamically switch databases. Configuration items are also very simple. Simply configure your API to accept user credentials or identifiers as input and use them to determine the appropriate database to connect to. I think this should be the most flexible and efficient solution.

huangapple
  • 本文由 发表于 2023年5月15日 01:44:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76248898.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定