为啥 django 和 python MySQLdb 每个数据库有一个游标?

Posted

技术标签:

【中文标题】为啥 django 和 python MySQLdb 每个数据库有一个游标?【英文标题】:Why django and python MySQLdb have one cursor per database?为什么 django 和 python MySQLdb 每个数据库有一个游标? 【发布时间】:2013-02-05 19:47:46 【问题描述】:

示例场景:

mysql 运行单个服务器 -> 主机名

该服务器上有两个 MySQL 数据库 -> USERS , GAMES 。

任务 -> 从 GAMES.my_games_table 获取 10 个最新游戏,并从 USERS.my_users_table 获取玩这些游戏的用户(假设没有加入)

在 Django 和 Python MySQLdb 中,为什么每个数据库都有一个游标更可取?

每个 MySQL 服务器单个的扩展游标的缺点是什么,可以切换数据库(例如通过查询“use USERS;”),然后在相应的数据库上工作

MySQL 连接很便宜,但如果存在线性流且没有可能需要两个游标的复杂事务,那么单个连接不比多个连接更好吗?

【问题讨论】:

Django 支持多个数据库连接 - docs.djangoproject.com/en/dev/topics/db/multi-db @JonathanVanasco 是的,这正是我的问题,为什么位于 SAME SERVER 上的 2 个数据库应该有两个连接。例如。在 settings.py 我必须同时定义用户和游戏,django 将建立 2 个连接而不是一个。 @dm03514 这是一个示例场景。假设逻辑分片,或只读其他数据库的从属。底线是,单个 mysql 实例上有多个数据库。 我明白了。我把你的问题解释错了。我认为这是因为 DB API 规范:python.org/dev/peps/pep-0249/#cursor-objects"""这些对象代表一个数据库游标,用于管理获取操作的上下文。从同一连接创建的游标不是孤立的,即所做的任何更改游标到数据库的其他游标立即可见。从不同连接创建的游标可以或不能隔离,具体取决于实现事务支持的方式(另请参见连接的 .rollback() 和 .commit() 方法) .""" 【参考方案1】:

更简短的回答是,“MySQL 不支持那种类型的游标”,Python-MySQL 也不支持,所以首选连接命令的原因是因为 MySQL 就是这样工作的。这是一种重言式。

但是,更长的答案是:

    根据您的定义,“游标”是访问 RDMS 中的表和索引的某种类型的对象,能够维护其状态。 根据您的定义,“连接”将接受命令,并分配或重用游标来执行命令的操作,并将其结果返回给连接。 根据您的定义,“连接”将/可以管理多个游标。 您认为这将是访问数据库的首选/高性能方式,因为“连接”成本高昂,而“游标”成本低。

但是:

    MySQL(和其他 RDMS)中的cursor 不是用于执行操作的用户可访问机制。 MySQL(和其他的)以“set”的形式执行操作,或者更确切地说,它们将您的 SQL 命令编译成一个内部命令列表,并根据您的 SQL 命令的性质和您的表结构执行大量复杂的位。 cursor 是一种特定机制,在存储过程中使用(并且仅在存储过程中使用),为开发人员提供了一种以过程方式处理数据的方法。 MySQL 中的“连接”就是您所认为的“光标”。 MySQL 不会将它的内部结构作为迭代器或指针公开给您,它只是在表上移动。它将其内部暴露为“连接”,接受 SQL 和其他命令,将这些命令转换为内部操作,执行该操作,并将结果返回给您。 这是“集合”和“程序”执行风格之间的区别(这实际上与您(用户)可以访问的控制粒度有关,或者至少是 RDMS 抽象方式中固有的粒度当它通过 API 公开其内部时)。

【讨论】:

【参考方案2】:

每个数据库一个游标不一定是可取的,这只是默认行为。

理由是不同的数据库通常位于不同的服务器上,使用不同的引擎,和/或需要不同的初始化选项。 (否则,你为什么要首先使用不同的“数据库”?)

在您的情况下,如果您的两个数据库只是表的名称空间(在 SQL 术语中应该称为“模式”)但驻留在同一个 MySQL 实例上,那么一定要使用单个连接。 (如何配置 Django 这样做实际上是一个完全不同的问题。)

如果您只有一个线程并且实际上并不同时需要两个数据库工作者,那么单个连接优于两个连接也是对的。

【讨论】:

【参考方案3】:

正如您所说,MySQL 连接很便宜,因此对于您的情况,我不确定在代码组织和流程之外,无论哪种方式都有技术优势。管理两个游标可能比通过煞费苦心地跟踪 SQL 'USE' 语句来跟踪单个游标当前正在与哪个数据库通信更容易。使用其他数据库的里程可能会有所不同——请记住,Django 力求与数据库无关。

另外,考虑两个不同的数据库,即使在同一台服务器上,也需要不同的访问凭据的情况。在这种情况下,将需要两个连接,以便每个连接都能成功进行身份验证。

【讨论】:

以上是关于为啥 django 和 python MySQLdb 每个数据库有一个游标?的主要内容,如果未能解决你的问题,请参考以下文章

Python django 错误

django视图和url配置为啥没有view.pyc

为啥无法收到电子邮件(python、gmail、django)?

django,python为啥本地化后时间戳会发生变化

为啥我在 Django 的 Python shell 中出现编程错误?

为啥 nginx 不会用 django 和 gunicorn 显示静态内容?