130 lines
8.3 KiB
Markdown
130 lines
8.3 KiB
Markdown
---
|
||
name: database-connect
|
||
description: 连接 MySQL 数据库并完成安全的查询、数据写入、更新、删除、表结构探查、事务处理和数据库诊断。用户要求 Codex 连接 MySQL、查看或修改数据库数据、分析表结构、执行 SQL、排查数据库连接或查询问题时使用。
|
||
---
|
||
|
||
# MySQL 数据库连接
|
||
|
||
## 目标
|
||
|
||
按照“发现配置、验证连接、了解结构、最小化操作、核对结果”的流程连接项目 MySQL,并完成用户授权范围内的数据库操作。优先复用项目已有的驱动、配置和命令,不擅自安装依赖或改变数据库环境。
|
||
|
||
## 安全边界
|
||
|
||
- 将数据库凭据视为机密。读取 `.env`、`.env.example`配置,只提取连接所需值,绝不在回复、日志、补丁或命令输出中打印密码、完整连接串或令牌。
|
||
- 禁止把密码直接写在命令行参数、SQL、源码或新建文件中。优先使用项目现有的安全配置、环境变量、凭据助手或 MySQL 客户端配置文件。
|
||
- 默认使用只读方式探查:`SELECT`、`SHOW`、`DESCRIBE`、`EXPLAIN` 和 `information_schema` 查询可以先执行;不要把探查语句改成写入语句。
|
||
- 执行 `INSERT`、`UPDATE`、`DELETE`、`REPLACE`、`TRUNCATE`、`DROP`、`ALTER`、`CREATE`、批量导入、权限变更或存储过程时,先说明目标、范围、预计影响和事务策略。
|
||
- 对删除、清空、改表、批量更新等不可逆或高影响操作,先展示将执行的精确 SQL(敏感值脱敏)并请求用户确认;用户已在当前请求中明确给出精确语句和范围时,可视为已确认,但仍先做影响评估。
|
||
- 不执行未限定范围的 `UPDATE` 或 `DELETE`,不执行生产库上的 `DROP DATABASE`、`TRUNCATE` 或全表更新,除非用户明确确认精确目标和范围。
|
||
- 不为了“修复连接”而修改防火墙、开放公网端口、重置密码、创建高权限账号或暴露数据库服务;这些需要单独授权。
|
||
|
||
## 标准工作流
|
||
|
||
### 1. 发现连接方式
|
||
|
||
按以下顺序检查,找到一种可用方式后停止扩散搜索:
|
||
|
||
1. 查看项目的 `README`、数据库迁移配置和应用配置,识别 host、port、database、user 的来源。密码只在本地使用,不回显。
|
||
2. 检查当前环境变量,如 `MYSQL_HOST`、`MYSQL_PORT`、`MYSQL_DATABASE`、`MYSQL_USER`、`MYSQL_PASSWORD` 或项目自定义变量。优先确认变量是否存在,不输出其值。
|
||
3. 检查项目依赖和现有数据库访问代码。Java 项目优先复用 JDBC/迁移工具,Node.js 项目优先复用现有 MySQL 驱动,Python 项目优先复用已安装的驱动。
|
||
4. 检查 `mysql` 客户端是否可用及版本。客户端不可用时,先报告缺少的工具,并优先使用项目已有驱动;不要未经授权下载或安装软件。
|
||
|
||
连接参数不完整时,只询问缺少的参数。接受用户提供的 `host`、`port`、数据库名和用户名,但不要要求用户把密码粘贴到聊天中;建议通过环境变量或本地凭据配置提供密码。
|
||
|
||
### 2. 验证连接
|
||
|
||
建立连接后先执行轻量验证,不直接操作业务数据:
|
||
|
||
```sql
|
||
SELECT DATABASE() AS current_database,
|
||
USER() AS connected_user,
|
||
VERSION() AS mysql_version;
|
||
```
|
||
|
||
验证以下事项:
|
||
|
||
- 实际连接的主机、端口、数据库和账号是否符合目标;不要仅凭配置文件推断已经连对。
|
||
- 当前账号是否有完成任务所需的最小权限。
|
||
- 是否存在只读副本、开发库和生产库混淆的风险。发现环境不明确时暂停写操作并询问。
|
||
- 字符集和时区是否可能影响结果,必要时读取 `SELECT @@character_set_connection, @@time_zone`。
|
||
|
||
连接失败时按错误码和现象诊断:先区分 DNS/网络不可达、端口拒绝、认证失败、数据库不存在、权限不足、TLS 配置错误和客户端/驱动缺失;不要用反复重试掩盖根因。记录可公开的错误类型和下一步,不回显凭据。
|
||
|
||
### 3. 探查结构和数据
|
||
|
||
在写操作前确认表、列、键和约束。按需执行:
|
||
|
||
```sql
|
||
SHOW TABLES;
|
||
SHOW CREATE TABLE `table_name`;
|
||
SELECT TABLE_NAME, TABLE_ROWS
|
||
FROM information_schema.TABLES
|
||
WHERE TABLE_SCHEMA = DATABASE();
|
||
|
||
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'table_name'
|
||
ORDER BY ORDINAL_POSITION;
|
||
```
|
||
|
||
- 从实际结构确认表名、列名、主键、唯一键、外键、默认值和软删除字段;不要根据名称猜测 schema。
|
||
- 样本数据只取必要列并加 `LIMIT`,避免 `SELECT *` 扫描大表。需要总量时优先 `COUNT(*)`,需要性能判断时使用 `EXPLAIN`。
|
||
- 识别敏感列(密码、身份证、手机号、令牌、支付信息等),查询结果脱敏或只返回聚合结果。
|
||
- 表名和列名不能用普通 SQL 参数绑定。对动态标识符只允许来自已探查且白名单校验通过的名称,并使用 MySQL 反引号转义。
|
||
|
||
### 4. 执行查询或修改
|
||
|
||
- 复杂任务拆成可验证的小步骤,每一步说明目的和结果。
|
||
- 所有用户输入值使用驱动的参数绑定(如 `?`、`:name`),不要拼接值生成 SQL。只在无法参数化的标识符上使用白名单。
|
||
- 先用等价的 `SELECT` 验证筛选条件,再执行 `UPDATE`/`DELETE`。修改前记录主键集合或预估影响行数。
|
||
- 查询大表时必须有合理的过滤条件、索引或分页;避免在未了解数据量时执行全表排序、笛卡尔积和无条件扫描。
|
||
- 对写操作优先使用事务:开始事务,执行变更,检查受影响行数和关键结果,确认无误后提交;异常时回滚。不要在无法确认事务状态时重复提交。
|
||
- 批量操作分批执行并记录每批结果。遇到锁等待、死锁、超时或影响行数异常时停止后续批次,回滚当前事务并报告。
|
||
- DDL 可能隐式提交,执行前明确告知这一点;涉及表结构变更时先备份/导出或确认已有恢复方案。
|
||
|
||
通用写操作模板:
|
||
|
||
```sql
|
||
START TRANSACTION;
|
||
|
||
-- 先用同一 WHERE 条件确认目标和数量
|
||
SELECT `primary_key`
|
||
FROM `table_name`
|
||
WHERE ...
|
||
LIMIT 1000;
|
||
|
||
-- 使用参数绑定执行精确变更
|
||
UPDATE `table_name`
|
||
SET `column_name` = ?
|
||
WHERE `primary_key` IN (...);
|
||
|
||
-- 核对受影响行数和结果后再提交
|
||
COMMIT;
|
||
-- 任一步失败时执行 ROLLBACK;
|
||
```
|
||
|
||
### 5. 核对并汇报
|
||
|
||
操作完成后重新查询关键结果,核对实际影响行数、唯一性、关联完整性和业务约束。向用户报告:使用的连接环境(不含密码)、执行的操作、结果摘要、是否提交事务、异常或未验证事项;不要粘贴大批量原始数据。
|
||
|
||
## 工具选择
|
||
|
||
- 已有应用或迁移工具能安全提供连接时,优先使用它,避免引入第二套连接配置。
|
||
- 使用 `mysql` CLI 时,把密码交给安全凭据机制或交互式输入,不使用 `--password=明文`。长 SQL 用受控的临时文件或标准输入传递,并在使用后清理临时文件。
|
||
- 使用脚本时复用项目锁定的依赖和配置,设置连接超时、查询超时(若驱动支持)和结果上限;脚本结束时关闭连接。
|
||
- 不把结果写入仓库,不提交临时凭据,不把生产数据导出到工作区。确需导出时先确认文件位置、字段范围和保留期限。
|
||
|
||
## 常见问题处理
|
||
|
||
- `Access denied`: 核对实际用户名、认证插件、目标主机和账号来源;不要通过授予 `ALL PRIVILEGES` 规避权限问题。
|
||
- `Unknown database`: 确认数据库名和当前连接环境,先列出允许访问的数据库或检查 Compose/迁移配置。
|
||
- `Table doesn't exist`: 核对大小写、schema、迁移状态和连接库,不要直接创建同名表覆盖问题。
|
||
- `Lock wait timeout` 或死锁: 回滚当前事务,识别长事务和索引缺失,缩小批次;不要盲目重试写入。
|
||
- 字符集乱码: 检查连接、表和列的字符集与排序规则,先读取并评估已有数据,再决定是否迁移。
|
||
- 结果数量异常: 重新检查 JOIN 条件、NULL 语义、时区、软删除条件和分页边界,并保留可复现的只读查询。
|
||
|
||
## 完成标准
|
||
|
||
只有在连接目标已验证、操作范围已确认、SQL 使用参数绑定、写操作结果已核对且事务状态明确时,才报告数据库任务完成。任何凭据、环境或影响范围无法确认时,保持只读并明确阻塞原因。
|