Files
banban/talkingq-url/mysql/mysql.md
2026-03-24 15:04:36 +08:00

879 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TalkingQ MySQL 查询手册
## 数据库概览
TalkingQ 使用 MySQL 8.0 作为数据库后端,存储设备配置、角色信息和会话数据。本文档提供了数据库结构和常用查询操作的参考。
## 连接信息
```
数据库名称: talkingq
用户名: talkingq
密码: 在 .env 或 .env.prod 文件中配置的 MYSQL_PASSWORD
主机: localhost (本地开发) 或 mysql (Docker环境)
端口: 3306
```
## 连接数据库
```bash
# 本地开发环境
mysql -u talkingq -p talkingq
# Docker环境中
sudo docker compose exec -it mysql mysql -u talkingq -p talkingq
```
## 表结构
### device_configs - 设备配置表
存储设备的角色选择和语言偏好等配置。
| 字段名 | 类型 | 描述 |
|-------------------|---------------|---------------------------|
| id | INT | 主键,自增 |
| device_id | VARCHAR(64) | 设备ID唯一索引 |
| selected_role_key | VARCHAR(64) | 选中的角色键 |
| preferred_language| VARCHAR(10) | 首选语言代码 |
| last_update_time | FLOAT | 最后更新时间戳 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
### conversation_histories - 对话历史表
存储设备的对话历史记录和角色信息。
| 字段名 | 类型 | 描述 |
|--------------------|---------------|---------------------------|
| id | INT | 主键,自增 |
| device_id | VARCHAR(64) | 设备ID索引 |
| role_key | VARCHAR(64) | 角色键,索引 |
| last_interaction_time | FLOAT | 最后交互时间戳 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
### conversation_messages - 对话消息表
存储对话的具体消息内容。
| 字段名 | 类型 | 描述 |
|--------------------|---------------|---------------------------|
| id | INT | 主键,自增 |
| conversation_id | INT | 关联的对话历史ID外键 |
| is_user | BOOLEAN | 是否为用户消息 |
| content | TEXT | 消息内容 |
| timestamp | FLOAT | 消息时间戳 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
### roles - 角色表
存储系统中可用的角色定义。
| 字段名 | 类型 | 描述 |
|--------------------|---------------|---------------------------|
| id | INT | 主键,自增 |
| role_key | VARCHAR(64) | 角色键名,唯一索引 |
| name | VARCHAR(128) | 角色名称 |
| description | TEXT | 角色描述 |
| content | TEXT | 系统提示内容 |
| default_language | VARCHAR(10) | 默认语言代码 |
| asr_provider | VARCHAR(64) | ASR服务提供商 |
| llm_provider | VARCHAR(64) | LLM服务提供商 |
| tts_provider | VARCHAR(64) | TTS服务提供商 |
| competitive_llm_mode | BOOLEAN | 是否启用竞争模式 |
| volcano_model_id | VARCHAR(64) | Volcano模型ID |
| volcano_voice_type | VARCHAR(64) | Volcano音色类型 |
| tencent_voice_type | VARCHAR(64) | 腾讯音色类型 |
| aliyun_voice_name | VARCHAR(64) | 阿里云音色名称 |
| url | VARCHAR(255) | 资源URL路径 |
| homophones | JSON | 同音词列表 |
| enabled | BOOLEAN | 是否启用 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
### role_languages - 角色语言表
存储角色的多语言配置。
| 字段名 | 类型 | 描述 |
|--------------------|---------------|---------------------------|
| id | INT | 主键,自增 |
| role_id | INT | 关联的角色ID外键 |
| language_code | VARCHAR(10) | 语言代码 |
| name | VARCHAR(128) | 该语言下的角色名称 |
| content | TEXT | 该语言下的系统提示内容 |
| asr_provider | VARCHAR(64) | 该语言的ASR服务提供商 |
| llm_provider | VARCHAR(64) | 该语言的LLM服务提供商 |
| tts_provider | VARCHAR(64) | 该语言的TTS服务提供商 |
| volcano_voice_type | VARCHAR(64) | 该语言的Volcano音色类型 |
| tencent_voice_type | VARCHAR(64) | 该语言的腾讯音色类型 |
| aliyun_voice_name | VARCHAR(64) | 该语言的阿里云音色名称 |
| url | VARCHAR(255) | 该语言的资源URL路径 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
### device_auth - 设备认证表
存储设备认证信息,用于验证设备身份。
| 字段名 | 类型 | 描述 |
|--------------------|---------------|---------------------------|
| id | INT | 主键,自增 |
| device_id | VARCHAR(64) | 设备ID唯一索引 |
| serial_number | VARCHAR(64) | 设备序列号 |
| is_active | BOOLEAN | 是否活跃 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
## 常用查询示例
### 设备配置查询
#### 查询所有设备配置
```sql
SELECT * FROM device_configs;
```
#### 查询特定设备的配置
```sql
SELECT * FROM device_configs WHERE device_id = '设备ID';
```
#### 查询使用特定角色的设备
```sql
SELECT * FROM device_configs WHERE selected_role_key = '角色键名';
```
#### 查询使用特定语言的设备
```sql
SELECT * FROM device_configs WHERE preferred_language = '语言代码';
```
#### 查询最近更新的设备配置
```sql
SELECT * FROM device_configs
ORDER BY last_update_time DESC
LIMIT 10;
```
### 对话历史查询
#### 查询特定设备的所有对话历史
```sql
SELECT * FROM conversation_histories WHERE device_id = '设备ID';
```
#### 查询特定设备和角色的对话历史
```sql
SELECT * FROM conversation_histories
WHERE device_id = '设备ID' AND role_key = '角色键名';
```
#### 查询最近交互的对话历史
```sql
SELECT * FROM conversation_histories
ORDER BY last_interaction_time DESC
LIMIT 10;
```
#### 查询一段时间内的对话历史
```sql
SELECT * FROM conversation_histories
WHERE last_interaction_time BETWEEN UNIX_TIMESTAMP('2023-01-01') AND UNIX_TIMESTAMP('2023-12-31')
ORDER BY last_interaction_time DESC;
```
### 对话消息查询
#### 查询特定对话的所有消息
```sql
SELECT * FROM conversation_messages
WHERE conversation_id = 对话ID
ORDER BY timestamp ASC;
```
#### 查询特定对话的用户消息
```sql
SELECT * FROM conversation_messages
WHERE conversation_id = 对话ID AND is_user = TRUE
ORDER BY timestamp ASC;
```
#### 查询特定对话的助手回复
```sql
SELECT * FROM conversation_messages
WHERE conversation_id = 对话ID AND is_user = FALSE
ORDER BY timestamp ASC;
```
#### 查询包含特定关键词的消息
```sql
SELECT * FROM conversation_messages
WHERE content LIKE '%关键词%'
ORDER BY timestamp DESC;
```
#### 查询最近的消息记录
```sql
SELECT cm.*, ch.device_id, ch.role_key
FROM conversation_messages cm
JOIN conversation_histories ch ON cm.conversation_id = ch.id
ORDER BY cm.timestamp DESC
LIMIT 20;
```
### 角色表查询
#### 查询所有启用的角色
```sql
SELECT * FROM roles WHERE enabled = TRUE;
```
#### 查询特定角色的详细信息
```sql
SELECT * FROM roles WHERE role_key = '角色键名';
```
#### 查询使用特定服务提供商的角色
```sql
SELECT * FROM roles WHERE llm_provider = 'Volcano';
-- 或
SELECT * FROM roles WHERE tts_provider = 'Tencent';
-- 或
SELECT * FROM roles WHERE asr_provider = 'Aliyun';
```
#### 查询角色的同音词列表
```sql
SELECT role_key, homophones FROM roles WHERE homophones IS NOT NULL;
```
#### 查询启用竞争模式的角色
```sql
SELECT * FROM roles WHERE competitive_llm_mode = TRUE;
```
### 角色语言表查询
#### 查询特定角色的所有语言配置
```sql
SELECT rl.* FROM role_languages rl
JOIN roles r ON rl.role_id = r.id
WHERE r.role_key = '角色键名';
```
#### 查询特定语言的所有角色配置
```sql
SELECT r.role_key, r.name, rl.* FROM role_languages rl
JOIN roles r ON rl.role_id = r.id
WHERE rl.language_code = '语言代码';
```
#### 查询特定角色特定语言的配置
```sql
SELECT rl.* FROM role_languages rl
JOIN roles r ON rl.role_id = r.id
WHERE r.role_key = '角色键名' AND rl.language_code = '语言代码';
```
#### 查询支持多语言的角色列表
```sql
SELECT r.role_key, r.name, COUNT(rl.id) as language_count
FROM roles r
JOIN role_languages rl ON r.id = rl.role_id
GROUP BY r.id
HAVING language_count > 1
ORDER BY language_count DESC;
```
### 设备认证查询
#### 查询所有已认证设备
```sql
SELECT * FROM device_auth WHERE is_active = TRUE;
```
#### 查询特定设备的认证信息
```sql
SELECT * FROM device_auth WHERE device_id = '设备ID';
```
#### 查询最近添加的设备认证
```sql
SELECT * FROM device_auth
ORDER BY created_at DESC
LIMIT 10;
```
### 多表联合查询
#### 查询特定设备的所有消息及对应的角色
```sql
SELECT cm.*, ch.role_key
FROM conversation_messages cm
JOIN conversation_histories ch ON cm.conversation_id = ch.id
WHERE ch.device_id = '设备ID'
ORDER BY cm.timestamp ASC;
```
#### 查询特定设备使用特定角色的所有对话内容
```sql
SELECT cm.*, ch.role_key, ch.last_interaction_time
FROM conversation_messages cm
JOIN conversation_histories ch ON cm.conversation_id = ch.id
WHERE ch.device_id = '设备ID' AND ch.role_key = '角色键名'
ORDER BY cm.timestamp ASC;
```
#### 查询所有设备的最新一条消息
```sql
SELECT ch.device_id, ch.role_key, cm.content, cm.timestamp
FROM conversation_histories ch
JOIN conversation_messages cm ON ch.id = cm.conversation_id
WHERE cm.id = (
SELECT MAX(cm2.id)
FROM conversation_messages cm2
WHERE cm2.conversation_id = ch.id
);
```
#### 查询设备当前使用的角色详细信息
```sql
SELECT dc.device_id, r.*
FROM device_configs dc
JOIN roles r ON dc.selected_role_key = r.role_key
WHERE dc.device_id = '设备ID';
```
#### 查询设备对话中使用的所有角色
```sql
SELECT DISTINCT ch.device_id, ch.role_key, r.name, r.description
FROM conversation_histories ch
JOIN roles r ON ch.role_key = r.role_key
WHERE ch.device_id = '设备ID';
```
#### 查询设备认证状态与当前配置信息
```sql
SELECT da.device_id, da.serial_number, da.is_active,
dc.selected_role_key, dc.preferred_language, dc.last_update_time
FROM device_auth da
LEFT JOIN device_configs dc ON da.device_id = dc.device_id
ORDER BY da.created_at DESC;
```
### 高级统计查询
#### 统计每个角色的使用情况
```sql
SELECT selected_role_key, COUNT(*) as device_count
FROM device_configs
GROUP BY selected_role_key
ORDER BY device_count DESC;
```
#### 统计每种语言的使用情况
```sql
SELECT preferred_language, COUNT(*) as language_count
FROM device_configs
WHERE preferred_language IS NOT NULL
GROUP BY preferred_language
ORDER BY language_count DESC;
```
#### 统计每个设备的对话数量
```sql
SELECT device_id, COUNT(*) as conversation_count
FROM conversation_histories
GROUP BY device_id
ORDER BY conversation_count DESC;
```
#### 统计每个角色的对话数量
```sql
SELECT role_key, COUNT(*) as conversation_count
FROM conversation_histories
GROUP BY role_key
ORDER BY conversation_count DESC;
```
#### 统计消息量最多的对话
```sql
SELECT ch.id, ch.device_id, ch.role_key, COUNT(cm.id) as message_count
FROM conversation_histories ch
JOIN conversation_messages cm ON ch.id = cm.conversation_id
GROUP BY ch.id, ch.device_id, ch.role_key
ORDER BY message_count DESC
LIMIT 10;
```
#### 统计最活跃的设备
```sql
SELECT device_id, COUNT(DISTINCT role_key) as roles_used,
COUNT(*) as total_conversations,
MAX(last_interaction_time) as last_active
FROM conversation_histories
GROUP BY device_id
ORDER BY total_conversations DESC
LIMIT 10;
```
#### 统计各语言下的角色数量
```sql
SELECT rl.language_code, COUNT(DISTINCT r.id) as role_count
FROM role_languages rl
JOIN roles r ON rl.role_id = r.id
GROUP BY rl.language_code
ORDER BY role_count DESC;
```
#### 统计近期设备活跃度
```sql
SELECT
DATE(FROM_UNIXTIME(last_interaction_time)) as date,
COUNT(DISTINCT device_id) as active_devices
FROM conversation_histories
WHERE last_interaction_time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY))
GROUP BY date
ORDER BY date DESC;
```
#### 统计各TTS提供商的使用情况
```sql
SELECT
CASE
WHEN volcano_voice_type IS NOT NULL THEN 'Volcano'
WHEN tencent_voice_type IS NOT NULL THEN 'Tencent'
WHEN aliyun_voice_name IS NOT NULL THEN 'Aliyun'
ELSE 'Unknown'
END as tts_provider,
COUNT(*) as role_count
FROM roles
GROUP BY tts_provider
ORDER BY role_count DESC;
```
#### 统计设备认证与使用情况
```sql
SELECT
COUNT(da.id) as total_devices,
SUM(CASE WHEN da.is_active = TRUE THEN 1 ELSE 0 END) as active_devices,
SUM(CASE WHEN dc.id IS NOT NULL THEN 1 ELSE 0 END) as configured_devices,
SUM(CASE WHEN ch.device_id IS NOT NULL THEN 1 ELSE 0 END) as devices_with_conversations
FROM device_auth da
LEFT JOIN device_configs dc ON da.device_id = dc.device_id
LEFT JOIN (SELECT DISTINCT device_id FROM conversation_histories) ch ON da.device_id = ch.device_id;
```
## 数据分析查询
### 对话内容分析
#### 查询用户问题平均长度
```sql
SELECT ch.role_key, AVG(LENGTH(cm.content)) as avg_length
FROM conversation_messages cm
JOIN conversation_histories ch ON cm.conversation_id = ch.id
WHERE cm.is_user = TRUE
GROUP BY ch.role_key;
```
#### 查询助手回答平均长度
```sql
SELECT ch.role_key, AVG(LENGTH(cm.content)) as avg_length
FROM conversation_messages cm
JOIN conversation_histories ch ON cm.conversation_id = ch.id
WHERE cm.is_user = FALSE
GROUP BY ch.role_key;
```
#### 查询用户消息长度分布
```sql
SELECT
CASE
WHEN LENGTH(content) < 50 THEN '极短 (<50)'
WHEN LENGTH(content) BETWEEN 50 AND 100 THEN '短 (50-100)'
WHEN LENGTH(content) BETWEEN 101 AND 200 THEN '中 (101-200)'
WHEN LENGTH(content) BETWEEN 201 AND 500 THEN '长 (201-500)'
ELSE '极长 (>500)'
END as message_length_category,
COUNT(*) as message_count
FROM conversation_messages
WHERE is_user = TRUE
GROUP BY message_length_category
ORDER BY
CASE message_length_category
WHEN '极短 (<50)' THEN 1
WHEN '短 (50-100)' THEN 2
WHEN '中 (101-200)' THEN 3
WHEN '长 (201-500)' THEN 4
ELSE 5
END;
```
#### 查询不同角色对话完成时间统计
```sql
SELECT ch.role_key,
COUNT(*) as conversation_count,
AVG(MAX(cm.timestamp) - MIN(cm.timestamp)) as avg_duration
FROM conversation_histories ch
JOIN conversation_messages cm ON ch.id = cm.conversation_id
GROUP BY ch.role_key
HAVING conversation_count > 5
ORDER BY avg_duration DESC;
```
#### 查询不同语言的平均对话长度
```sql
SELECT dc.preferred_language,
COUNT(DISTINCT ch.id) as conversation_count,
AVG(cm_count.msg_count) as avg_messages_per_conversation
FROM device_configs dc
JOIN conversation_histories ch ON dc.device_id = ch.device_id
JOIN (
SELECT conversation_id, COUNT(*) as msg_count
FROM conversation_messages
GROUP BY conversation_id
) cm_count ON ch.id = cm_count.conversation_id
WHERE dc.preferred_language IS NOT NULL
GROUP BY dc.preferred_language
HAVING conversation_count > 3
ORDER BY avg_messages_per_conversation DESC;
```
#### 查询包含特定关键词的对话
```sql
SELECT ch.id, ch.device_id, ch.role_key,
MAX(ch.last_interaction_time) as conversation_time,
GROUP_CONCAT(DISTINCT CASE WHEN cm.is_user = TRUE THEN cm.content ELSE NULL END SEPARATOR '\n') as user_messages,
GROUP_CONCAT(DISTINCT CASE WHEN cm.is_user = FALSE THEN cm.content ELSE NULL END SEPARATOR '\n') as assistant_messages
FROM conversation_histories ch
JOIN conversation_messages cm ON ch.id = cm.conversation_id
WHERE cm.content LIKE '%关键词%'
GROUP BY ch.id, ch.device_id, ch.role_key
ORDER BY conversation_time DESC;
```
### 用户行为分析
#### 查询用户平均会话时长趋势
```sql
SELECT
DATE(FROM_UNIXTIME(ch.last_interaction_time)) as date,
AVG(
MAX(cm.timestamp) - MIN(cm.timestamp)
) as avg_session_duration
FROM conversation_histories ch
JOIN conversation_messages cm ON ch.id = cm.conversation_id
WHERE ch.last_interaction_time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY))
GROUP BY date
ORDER BY date;
```
#### 查询每日活跃用户数和对话量
```sql
SELECT
DATE(FROM_UNIXTIME(last_interaction_time)) as date,
COUNT(DISTINCT device_id) as active_users,
COUNT(*) as conversations
FROM conversation_histories
WHERE last_interaction_time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY))
GROUP BY date
ORDER BY date DESC;
```
#### 查询设备的首次使用时间和最后使用时间
```sql
SELECT
device_id,
MIN(created_at) as first_use,
FROM_UNIXTIME(MAX(last_interaction_time)) as last_use,
DATEDIFF(FROM_UNIXTIME(MAX(last_interaction_time)), MIN(created_at)) as days_between
FROM conversation_histories
GROUP BY device_id
ORDER BY days_between DESC;
```
#### 查询用户连续活跃天数
```sql
WITH daily_activity AS (
SELECT
device_id,
DATE(FROM_UNIXTIME(last_interaction_time)) as activity_date
FROM conversation_histories
GROUP BY device_id, activity_date
)
SELECT
device_id,
COUNT(*) as active_days,
MIN(activity_date) as first_active_day,
MAX(activity_date) as last_active_day,
DATEDIFF(MAX(activity_date), MIN(activity_date)) + 1 as day_span,
COUNT(*) / (DATEDIFF(MAX(activity_date), MIN(activity_date)) + 1) as activity_ratio
FROM daily_activity
GROUP BY device_id
HAVING day_span > 7
ORDER BY active_days DESC, activity_ratio DESC;
```
## 管理操作
### 备份数据库
```bash
# 在Docker环境外执行
docker exec -it talkingq-mysql-1 mysqldump -u root -p talkingq > talkingq_backup.sql
# 或使用本地MySQL客户端
mysqldump -h localhost -u talkingq -p talkingq > talkingq_backup.sql
```
### 恢复数据库
```bash
# 在Docker环境外执行
cat talkingq_backup.sql | docker exec -i talkingq-mysql-1 mysql -u root -p talkingq
# 或使用本地MySQL客户端
mysql -h localhost -u talkingq -p talkingq < talkingq_backup.sql
```
### 备份特定表
```bash
# 仅备份设备配置表
docker exec -it talkingq-mysql-1 mysqldump -u root -p talkingq device_configs > device_configs_backup.sql
# 仅备份角色表和角色语言表
docker exec -it talkingq-mysql-1 mysqldump -u root -p talkingq roles role_languages > roles_backup.sql
# 仅备份对话历史和消息表
docker exec -it talkingq-mysql-1 mysqldump -u root -p talkingq conversation_histories conversation_messages > conversations_backup.sql
# 备份设备认证表
docker exec -it talkingq-mysql-1 mysqldump -u root -p talkingq device_auth > device_auth_backup.sql
```
### 删除过期记录
```sql
-- 删除长期未使用的设备配置
DELETE FROM device_configs
WHERE last_update_time < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 90 DAY));
-- 删除3个月前的对话历史
DELETE ch, cm
FROM conversation_histories ch
LEFT JOIN conversation_messages cm ON ch.id = cm.conversation_id
WHERE ch.last_interaction_time < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 3 MONTH));
-- 将90天内未被任何设备使用的角色标记为禁用
UPDATE roles r
SET enabled = FALSE
WHERE r.role_key NOT IN (
SELECT DISTINCT selected_role_key
FROM device_configs
WHERE last_update_time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 90 DAY))
) AND r.role_key NOT IN (
SELECT DISTINCT role_key
FROM conversation_histories
WHERE last_interaction_time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 90 DAY))
);
-- 清理已停用设备的认证记录
UPDATE device_auth
SET is_active = FALSE
WHERE device_id NOT IN (
SELECT DISTINCT device_id
FROM conversation_histories
WHERE last_interaction_time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 180 DAY))
);
```
### 角色管理
```sql
-- 添加新角色(基本信息)
INSERT INTO roles (role_key, name, description, content, default_language, enabled)
VALUES ('new_role', '新角色', '新角色的描述', '系统提示内容', 'zh', TRUE);
-- 为角色添加语言配置
INSERT INTO role_languages (role_id, language_code, name, content)
VALUES (
(SELECT id FROM roles WHERE role_key = 'new_role'),
'en',
'New Role',
'System prompt content in English'
);
-- 复制角色
INSERT INTO roles (
role_key, name, description, content, default_language,
asr_provider, llm_provider, tts_provider, competitive_llm_mode,
volcano_model_id, volcano_voice_type, tencent_voice_type, aliyun_voice_name,
url, homophones, enabled
)
SELECT
CONCAT(role_key, '_copy'), CONCAT(name, ' (复制)'), description, content, default_language,
asr_provider, llm_provider, tts_provider, competitive_llm_mode,
volcano_model_id, volcano_voice_type, tencent_voice_type, aliyun_voice_name,
url, homophones, enabled
FROM roles
WHERE role_key = '要复制的角色键名';
```
## 数据库优化
### 优化表
```sql
OPTIMIZE TABLE device_configs;
OPTIMIZE TABLE conversation_histories;
OPTIMIZE TABLE conversation_messages;
OPTIMIZE TABLE roles;
OPTIMIZE TABLE role_languages;
OPTIMIZE TABLE device_auth;
```
### 分析表
```sql
ANALYZE TABLE device_configs;
ANALYZE TABLE conversation_histories;
ANALYZE TABLE conversation_messages;
ANALYZE TABLE roles;
ANALYZE TABLE role_languages;
ANALYZE TABLE device_auth;
```
### 检查表
```sql
CHECK TABLE device_configs;
CHECK TABLE conversation_histories;
CHECK TABLE conversation_messages;
CHECK TABLE roles;
CHECK TABLE role_languages;
CHECK TABLE device_auth;
```
### 添加索引
```sql
-- 为对话历史表添加联合索引
CREATE INDEX idx_device_role ON conversation_histories(device_id, role_key);
-- 为角色语言表添加联合索引
CREATE INDEX idx_role_language ON role_languages(role_id, language_code);
-- 为消息表添加时间戳索引,优化时间范围查询
CREATE INDEX idx_message_timestamp ON conversation_messages(timestamp);
-- 为设备认证表添加索引
CREATE INDEX idx_device_auth_active ON device_auth(is_active);
```
### 监控查询性能
```sql
-- 查看慢查询日志状态
SHOW VARIABLES LIKE 'slow_query%';
-- 查看当前运行的查询
SHOW PROCESSLIST;
-- 终止执行时间过长的查询
KILL QUERY 线程ID;
```
## 数据库维护脚本示例
以下是一个可以添加到cron任务的脚本示例用于定期清理过期数据和优化表
```bash
#!/bin/bash
# 文件名: /home/ubuntu/TalkingQ_URL/scripts/db_maintenance.sh
# 数据库连接参数
DB_USER="talkingq"
DB_PASS="您的密码"
DB_NAME="talkingq"
DB_HOST="mysql"
# 日志文件
LOG_FILE="/home/ubuntu/TalkingQ_URL/logs/db_maintenance.log"
echo "===== $(date) 开始数据库维护 =====" >> $LOG_FILE
# 删除3个月前的对话历史
echo "清理旧对话历史..." >> $LOG_FILE
docker exec -i talkingq-mysql-1 mysql -u$DB_USER -p$DB_PASS $DB_NAME << EOF
DELETE ch, cm
FROM conversation_histories ch
LEFT JOIN conversation_messages cm ON ch.id = cm.conversation_id
WHERE ch.last_interaction_time < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 3 MONTH));
EOF
# 优化表
echo "优化数据库表..." >> $LOG_FILE
docker exec -i talkingq-mysql-1 mysql -u$DB_USER -p$DB_PASS $DB_NAME << EOF
OPTIMIZE TABLE conversation_histories, conversation_messages, device_configs;
EOF
echo "===== $(date) 数据库维护完成 =====" >> $LOG_FILE
```