我是数据库的新手,现在我需要使用 MySQL 来构建 Web 服务器。
总之,我有一个用 Python 开发的 web 框架。它将从/向 MySQL 读取/写入数据。
现在我不知道如何处理 multithreading 的情况insert
。
假设有很多用户正在将他们的数据写入一张表中。我会使用一个线程池来处理这些请求,也就是说同时会有多个insert
s。
我的问题是:
如果我已经设置了concurrent_insert=2
,multiple insert
-s 是否仍然会导致 table 的锁定,这样我会得到一个非常糟糕的性能(所有的insert
s 都必须一个一个处理)?或者 MySQL 本身可以insert
正确处理倍数,因此我可以获得不错的性能?
对于倍数,“共享一个连接对象”和“每个都有自己的连接对象”insert
有什么区别吗?insert
没做什么。
说真的,MySQL 被设计为默认提供并发性。它可以处理各种可能发生的“冲突”。
MySQL 支持多个“引擎”。除非您使用的是旧版本,否则默认为
ENGINE=InnoDB
. (参见CREATE TABLE
.)concurrent_insert
涉及旧的、已弃用的ENGINE=MyISAM
;不要使用那个引擎。您应该始终做一件事:在执行 SQL 语句后检查错误。(这可以通过“try...catch”来完成。)如果没有别的,用错误消息中止,这样错误就不会被忽视——这可能很难调试。
一个功能齐全的网站甚至不需要“线程池”。(如果您的网站变得非常受欢迎,这可能很重要。)
正常的 Web 使用情况是:为一个想要一个网页的用户启动一个进程。然后它应该有一个与 MySQL 的连接。时期。(这是否解决了您的“共享一个连接对象”?)当另一个用户打开同一个网页时,网络服务器会启动另一个 python 副本,它将与 MySQL 建立单独的连接。
MyISAM 引擎陈旧过时,现在不应该使用。您应该改用 InnoDB 事务存储引擎。
InnoDB 没有多线程插入,但有一种不同的机制,称为“事务隔离级别”。默认情况下,InnoDB 不会在 INSERT / UPDATE / DELETE 上锁定表。这意味着某些查询可以同时读取表(包括正在修改的行)。事务的隔离级别决定了更改对检索数据的影响。
进一步阅读:
https ://dev.mysql.com/doc/refman/8.0/en/sql-transactional-statements.html https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-隔离级别.html