综合对比与选择建议
维度 PHP Java Python Ruby Perl
学习门槛 低(适合新手) 高(语法复杂) 低(语法简洁) 中(需理解 Rails 理念) 中(特殊语法)
性能 中(依赖 OPcache) 高(编译型语言) 低(解释型语言) 低(解释型语言) 中(文本处理快)
Web 开发效率 高(原生支持) 中(需配置框架) 中(需选框架) 高(Rails 加速) 低(无主流框架)
数据处理 中(需依赖扩展) 中(需手写代码) 高(pandas 等库) 中(ActiveRecord) 高(文本处理强)
适用规模 中小项目 大型企业级项目 数据科学、自动化 敏捷开发、创业项目 系统脚本、遗留系统
最终建议
选 PHP:如果是 Web 前端为主的项目,追求快速上线,且团队熟悉 PHP。
选 Java:如果是 大型企业级应用,需要高并发、分布式、强类型语言。
选 Python:如果项目 侧重数据处理、AI,或需要快速原型验证。
选 Ruby:如果是 敏捷开发、初创团队,希望用优雅的代码快速迭代。
选 Perl:仅用于 维护遗留系统 或 高性能文本处理脚本。
无论选择哪种语言,与 MySQL 交互时都要注意:
安全:防止 SQL 注入,过滤用户输入。
性能:合理设计表结构,添加索引,避免全表扫描。
扩展性:考虑未来数据量增长,提前规划分库分表或读写分离。
第2章:编写基于mysql的程序
2.0 引言
2.1 连接、选择数据库及断开连接
Python 与 MySQL 数据库连接是现代开发中最常用的组合之一,其应用覆盖从Web开发到数据分析等多个领域。以下是具体用途和技术细节:
🔥 核心应用场景
- Web开发后端
Django/Flask框架:原生支持MySQL,构建动态网站
Python
https://blog.csdn.net/xiaohuoche175/article/details/81261795
Django模型示例
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
REST API开发:FastAPI/Sanic + MySQL构建高性能接口
C:\Users\lenovo>pip install DBUtils
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting DBUtils
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/30/cd/e69e39ed66cb405ddaadc85f7429bd03f273600e83f804eb4a5c33d0f956/DBUtils-3.1.0-py3-none-any.whl (32 kB)
Installing collected packages: DBUtils
Successfully installed DBUtils-3.1.0
[notice] A new release of pip is available: 24.2 -> 25.1.1
[notice] To update, run: python.exe -m pip install --upgrade pip
C:\Users\lenovo>pip show DBUtils
Name: DBUtils
Version: 3.1.0
Summary: Database connections for multi-threaded environments.
Home-page: https://webwareforpython.github.io/DBUtils/
Author:
Author-email: Christoph Zwerschke cito@online.de
License: MIT License
Location: D:\dev\python\python3.12\Lib\site-packages
Requires:
Required-by:
https://blog.csdn.net/Linshaodan520/article/details/138734234
conda 安装
这是由于ustc镜像停止服务了,只要删除所有镜像链接,恢复到默认设置即可。
执行下面这行代码 conda config --remove-key channels
conda config --show channels 显示default。后再重新安装即可
https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html
- jupyter notebook操作oracle数据库
步骤一:安装cx_Oracle模块
cmd面板上输入命令: conda install cx_Oracle
步骤二:安装Oracle Instant Client (安装与服务器端Oracle版本相近的版本)
下载地址,解压之后,配置系统环境,如:D:\python\instantclient_19_6;
在解压路径中添加tnsnames.ora文件,文件配置如下:
复制代码
orcl =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = IP地址)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = 服务名)))
复制代码
如果没有安装oracle客户端,则会报"Cannot locate a 64-bit Oracle Client library: "The specified module could not be found…"错误。
https://blog.csdn.net/dugushangliang/article/details/85455270
数据库连接池(dbutils)_from dbutils.pooleddb import pooleddb-CSDN博客
- 创建或检查配置文件
确保 config.ini 文件存在,且内容如下:
ini
[database]
host = localhost
user = root
password = root
database = cookbook
max_connections = 5
- 添加配置文件存在检查
在代码中增加文件存在检查,避免无声失败:
python
运行
import os# 读取配置
config = configparser.ConfigParser()
config_path = 'config.ini'if not os.path.exists(config_path):logging.error(f"配置文件不存在: {config_path}")raise FileNotFoundError(f"配置文件不存在: {config_path}")config.read(config_path)# 验证配置文件包含必要的节
if 'database' not in config:logging.error("配置文件缺少 [database] 部分")
raise KeyError("配置文件缺少 [database] 部分")
使用绝对路径
避免相对路径带来的问题:
```python
python
运行
import os# 获取当前脚本所在目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(BASE_DIR, 'config.ini')
import pymysql
import matplotlib.pyplot as plt
from dbutils.pooled_db import PooledDB # 修正导入路径
import os
import configparser
import logging# 配置日志
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',filename='app.log'
)# 设置中文字体
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC", "Arial Unicode MS"]# 获取配置文件路径(兼容交互式环境)
try:# 脚本环境BASE_DIR = os.path.dirname(os.path.abspath(__file__))
except NameError:# 交互式环境BASE_DIR = os.getcwd()logging.warning(f"在交互式环境中运行,使用当前工作目录: {BASE_DIR}")config_path = os.path.join(BASE_DIR, 'D:\\sql\\Mysql_learning\\config.ini')# 检查配置文件是否存在
if not os.path.exists(config_path):logging.error(f"配置文件不存在: {config_path}")raise FileNotFoundError(f"配置文件不存在: {config_path}")# 读取配置
config = configparser.ConfigParser()
config.read(config_path)# 验证配置文件包含必要的节
if 'database' not in config:logging.error("配置文件缺少 [database] 部分")raise KeyError("配置文件缺少 [database] 部分")# 连接池初始化
pool = PooledDB(creator=pymysql,host=config['database']['host'],user=config['database']['user'],password=config['database']['password'],database=config['database']['database'],charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor,maxconnections=int(config['database']['max_connections'])
)def safe_query_table(table_name):"""安全查询表数据,带错误处理"""# 验证表名只包含合法字符if not re.match(r'^[a-zA-Z0-9_]+$', table_name):raise ValueError(f"非法表名: {table_name}")allowed_tables = ['limbs', 'customers']if table_name not in allowed_tables:logging.warning(f"尝试访问未授权表: {table_name}")raise ValueError(f"禁止访问表: {table_name}")try:with pool.connection() as conn:with conn.cursor() as cursor:# 使用反引号包裹表名,防止与关键字冲突sql = f"SELECT * FROM `{table_name}` LIMIT 5"cursor.execute(sql)return cursor.fetchall()except pymysql.Error as e:logging.error(f"数据库查询错误 ({table_name}): {e}")raiseexcept Exception as e:logging.error(f"未知错误: {e}")raisedef plot_limb_data(data, title="生物肢体数量对比", filename="limbs_comparison.png", show=True):"""绘制生物肢体数据图,支持自定义参数"""if not data:logging.warning("无数据可绘制")returnthings = [row['thing'] for row in data]legs = [row['legs'] for row in data]arms = [row['arms'] for row in data]plt.figure(figsize=(12, 6))x = range(len(things))# 绘制柱状图bars1 = plt.bar(x, legs, width=0.4, label='Legs', color='#2ecc71')bars2 = plt.bar([i+0.4 for i in x], arms, width=0.4, label='Arms', color='#3498db')# 添加数据标签for bars in [bars1, bars2]:for bar in bars:height = bar.get_height()plt.text(bar.get_x() + bar.get_width()/2., height,f'{height}', ha='center', va='bottom', fontweight='bold')# 图表装饰plt.title(title, fontsize=14, fontweight='bold')plt.xlabel('生物名称', fontsize=12)plt.ylabel('数量', fontsize=12)plt.xticks([i+0.2 for i in x], things, rotation=45, fontsize=10)plt.legend(fontsize=12)plt.grid(axis='y', linestyle='--', alpha=0.7)plt.tight_layout()# 保存图表if filename:plt.savefig(filename, dpi=300, bbox_inches='tight')logging.info(f"图表已保存至 {filename}")# 显示图表(可选)if show:plt.show()# 使用示例
if __name__ == "__main__":try:data = safe_query_table("limbs")if data:plot_limb_data(data, "生物肢体数量对比分析", "limbs_analysis.png")except Exception as e:print(f"程序执行出错: {e}")logging.exception("程序执行异常")

📌 替代方案(如果不想用 DBUtils)
1. 使用普通连接(不推荐生产环境)```python
python
import pymysqldef get_connection():return pymysql.connect(host='localhost',user='root',password='root',database='cookbook',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)
- 使用 SQLAlchemy 的连接池
python
from sqlalchemy import create_engine
创建带连接池的引擎
engine = create_engine("mysql+pymysql://root:root@localhost/cookbook?charset=utf8mb4",pool_size=5,max_overflow=10
)```python
获取连接
with engine.connect() as conn:
result = conn.execute(“SELECT * FROM limbs LIMIT 5”)
print(result.fetchall())
💡 为什么需要连接池?
场景 无连接池 使用连接池
高频短查询 频繁创建/断开连接开销大 复用连接,性能提升50%+
并发请求 容易耗尽数据库连接数 可控的最大连接数
长连接稳定性 可能因超时断开 自动检测并重置失效连接