为什么Django和Python MySQLdb每个数据库有一个游标?
示例场景:
在一台服务器上运行MySQL -> 主机名
这台服务器上有两个MySQL数据库 -> USERS(用户),GAMES(游戏)。
任务 -> 从GAMES.my_games_table中获取10个最新的游戏,并从USERS.my_users_table中获取玩这些游戏的用户(假设不需要连接查询)。
在Django和Python的MySQLdb中,为什么每个数据库使用一个游标更好呢?
如果使用一个扩展的游标,它是每个MySQL服务器只有一个,可以切换数据库(比如通过查询“use USERS;”),然后在相应的数据库上工作,这样有什么缺点呢?
MySQL的连接成本很低,但如果没有复杂的事务需要两个游标,单个连接不是比多个连接更好吗?
3 个回答
每个数据库用一个游标并不是一定更好,这只是默认的做法。
这样做的原因是,不同的数据库通常在不同的服务器上,使用不同的引擎,或者需要不同的初始化选项。(否则,为什么要使用不同的“数据库”呢?)
在你的情况下,如果这两个数据库只是表的命名空间(在SQL术语中应该叫“模式”),而且它们在同一个MySQL实例上,那么完全可以使用一个连接。(如何配置Django来实现这一点其实是另一个问题。)
你说得对,如果你只有一个线程,并且不需要同时使用两个数据库工作,那么一个连接确实比两个要好。
正如你所说,MySQL的连接成本很低,所以在你的情况下,我不太确定无论哪种方式在技术上有什么优势,除了代码的组织和流程。管理两个游标可能比费劲地追踪一个游标当前连接哪个数据库(通过仔细记录SQL的'USE'语句)要简单一些。使用其他数据库的情况可能会有所不同——记住,Django的目标是能够支持多种数据库。
另外,想想如果两个不同的数据库,即使在同一个服务器上,也需要不同的访问凭证。在这种情况下,就需要两个连接,以便每个连接都能成功进行身份验证。
简单来说,就是“MySQL不支持那种类型的游标”,所以Python-MySQL也不支持。因此,使用一个连接命令是因为这就是MySQL的工作方式。这有点像自我重复。
不过,详细说一下:
- 你所说的“游标”,可以理解为一种对象,它用来访问数据库里的表和索引,并且能够保持自己的状态。
- 你所说的“连接”,就是接受命令的东西,它可以分配或重用一个游标来执行命令,并把结果返回给连接。
- 按照你的定义,一个“连接”可以管理多个游标。
- 你认为这样访问数据库是更好的方式,因为“连接”比较贵,而“游标”比较便宜。
但是:
- 在MySQL(和其他关系数据库管理系统)中,
游标
并不是用户用来执行操作的工具。MySQL等是以“集合”的方式来执行操作,换句话说,它会把你的SQL命令编译成内部的命令列表,然后根据你的SQL命令和表的结构做很多复杂的处理。 游标
是一种特定的机制,只在存储过程里使用,给开发者提供了一种以过程化方式处理数据的方法。- 在MySQL中,“连接”可以有点像你想象中的“游标”。MySQL并不会把内部机制暴露给你作为一个迭代器或指针,它只是简单地在表上移动。它把内部机制作为一个“连接”来暴露,接受SQL和其他命令,把这些命令翻译成内部操作,执行这个操作,然后把结果返回给你。
- 这就是“集合”执行方式和“过程”执行方式之间的区别(这实际上是关于用户可以获得的控制粒度,或者说是关系数据库管理系统在通过API暴露其内部时所固有的粒度)。