MySQL Connector/Python 开发人员指南  /  Python 开发人员指南

第 2 章 Python 开发人员指南

以下指南涵盖了开发 MySQL 应用程序的某些方面,这些方面对于来自 Python 背景的开发人员来说可能并不立即显而易见

  • 出于安全考虑,不要在主脚本中硬编码连接和登录数据库所需的 value。Python 有一种将这些 value 与其余代码分开保存的约定,即 config.py 模块。

  • Python 脚本通常在内存中构建和拆解大型数据结构,直到可用 RAM 的限制。由于 MySQL 通常处理的数据集远远大于可用内存,因此优化存储空间和磁盘 I/O 的技术尤其重要。例如,在 MySQL 表中,通常使用数字 ID 而不是基于字符串的字典键,这样键 value 紧凑且长度可预测。对于构成 InnoDB主键 的列来说,这一点尤其重要,因为这些列 value 会在每个 辅助索引 中被复制。

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

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

    不良数据也可能是故意的,代表 SQL 注入 攻击。例如,输入 value 可能包含引号、分号、%_ 通配符以及 SQL 语句中重要的其他字符。验证输入 value 以确保它们仅包含预期字符。转义任何可能在替换到 SQL 语句中时改变预期行为的特殊字符。在对用户输入 value 进行验证和转义之前,永远不要将其连接到 SQL 语句中。即使接受由其他程序生成的输入,也要预期其他程序也可能已被破坏,并向您发送不正确或恶意数据。

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

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

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

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

    • 频繁更新,可能由多个用户同时更新。 更新可能只影响数据的一小部分,因此每次写入整个结构都是浪费的。您使用 SQL INSERTUPDATEDELETE 语句来并发更新不同的项目,只将更改的 value 写入磁盘。您使用 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 子句,并在 MySQL 5.5 及更高版本中将 InnoDB 设为默认存储引擎。使用 InnoDB 表可以实现事务行为,这有助于读写工作负载的可扩展性,并提供自动 崩溃恢复。另一个建议是为每个表声明一个数字 主键,这提供了查找 value 的最快方法,并且可以充当指向其他表中关联 value 的指针(外键)。同样,在 CREATE TABLE 语句中,使用满足应用程序需求的最紧凑的列数据类型,有助于提高性能和可扩展性,因为这样可以使数据库服务器在内存和磁盘之间移动更少的数据。