MySQL 连接器/Python 开发人员指南  /  第 2 章 Python 开发人员指南

第 2 章 Python 开发人员指南

以下指南涵盖了开发 MySQL 应用程序的各个方面,这些方面对于具有 Python 背景的开发人员来说可能不是很明显:

  • 为了安全起见,不要在主脚本中对连接和登录数据库所需的值进行硬编码。Python 有一个config.py模块的约定,您可以在其中将这些值与代码的其余部分分开。

  • Python 脚本经常在内存中建立和拆除大型数据结构,直至达到可用 RAM 的限制。由于 MySQL 经常处理比可用内存大很多倍的数据集,因此优化存储空间和磁盘 I/O 的技术尤为重要。例如,在 MySQL 表中,您通常使用数字 ID 而不是基于字符串的字典键,因此键值紧凑且具有可预测的长度。这对于构成表主键的列尤其重要InnoDB,因为这些列值在每个 二级索引中都是重复的。

  • 任何接受输入的应用程序都必须期望处理坏数据。

    错误数据可能是偶然的,例如超出范围的值或格式错误的字符串。应用程序可以使用服务器端检查,例如唯一约束NOT NULL 约束,以防止错误数据到达数据库。在客户端,使用异常处理程序等技术来报告任何问题并采取纠正措施。

    坏数据也可能是故意的,代表 SQL 注入攻击。例如,输入值可能包含引号、分号%_SQL 语句中的通配符和其他重要字符。验证输入值以确保它们只有预期的字符。转义任何在替换为 SQL 语句时可能会改变预期行为的特殊字符。切勿在未先进行验证和转义的情况下将用户输入值连接到 SQL 语句中。即使在接受其他程序生成的输入时,也应预料到其他程序也可能受到威胁并向您发送不正确或恶意的数据。

  • 由于 SQL 查询的结果集可能非常大,因此在循环遍历结果集时使用适当的方法从结果集中检索项目。 当您知道结果集包含一行时, fetchone() 会检索单个项目。fetchall() 检索所有项目,当您知道结果集包含可以轻松放入内存的有限行数时。 fetchmany() 是无法预测结果集大小时的通用方法:您不断调用它并循环返回的项目,直到没有更多结果要处理为止。

  • 由于 Python 已经有方便的模块,例如 picklecPickle在磁盘上读取和写入数据结构,因此您选择存储在 MySQL 中的数据可能具有特殊特征:

    • 太大而不能一次全部放入内存。您使用 SELECT语句仅查询您需要的精确项目,并 使用聚合函数对多个项目执行计算。您可以在 MySQL 服务器中配置该 innodb_buffer_pool_size 选项,以专用于缓存表和索引数据的一定数量的 RAM。

    • 太复杂,无法用单一数据结构表示。您在不同的 SQL 表之间划分数据。您可以使用连接查询重新组合来自多个表的数据 您可以通过设置外键关系 确保相关数据在不同表之间保持同步

    • 经常更新,可能由多个用户同时更新。更新可能只影响一小部分数据,每次都写入整个结构是一种浪费。您使用 SQL INSERTUPDATEDELETE语句同时更新不同的项目,只将更改的值写入磁盘。您使用InnoDB 表和 事务来防止写入操作相互冲突,并返回一致的查询结果,即使基础数据正在更新。

  • 使用 MySQL 性能最佳实践可以帮助您的应用程序进行扩展,而无需进行重大重写和架构更改。有关MySQL 性能的最佳实践,请参阅优化。它提供了有关 SQL 调优、数据库设计和服务器配置的指南和技巧。

  • 您可以通过学习常见操作的 MySQL SQL 语句来避免重新发明轮子:查询中使用的运算符、批量加载数据的技术等。一些语句和子句是对 SQL 标准定义的基本语句和子句的扩展。有关主要语句类别,请参阅 数据操作语句数据定义语句SELECT语句。

  • 从 Python 发出 SQL 语句通常涉及声明非常长的、可能是多行的字符串文字。由于 SQL 语句中的字符串文字可以用单引号、双引号括起来,或者包含这些字符中的任何一个,为简单起见,您可以使用 Python 的三重引号机制将整个语句括起来。例如:

    '''It doesn't matter if this string contains 'single'
    or "double" quotes, as long as there aren't 3 in a
    row.'''

    您可以使用'"字符中的任何一个来进行三重引号多行字符串文字。

  • 快速、可扩展的 MySQL 应用程序的许多秘诀都涉及在设置过程的最开始,即在CREATE TABLE 语句中使用正确的语法。例如,Oracle ENGINE=INNODB为大多数表推荐该子句,并InnoDB在 MySQL 5.5 及更高版本中成为默认存储引擎。使用InnoDB表可以实现有助于读写工作负载的可扩展性并提供自动 崩溃恢复的事务行为。另一个建议是为每个表声明一个数字 主键,它提供了最快的查找值的方法,并且可以充当指向其他表中关联值的指针( 外键). 同样在CREATE TABLE 语句中,使用满足您的应用程序要求的最紧凑的列数据类型有助于提高性能和可伸缩性,因为这使数据库服务器能够在内存和磁盘之间来回移动更少的数据。