You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
haoliang-net/docs/01-数据库设计.md

779 lines
34 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# CNC机床数据采集系统 - 数据库设计文档
> 最后更新2026-04-28
> 状态:定稿(界面设计已全部确认,数据库结构已落地)
---
## 一、数据库架构
- **业务库**cnc_business
- **日志库**cnc_log
- **引擎**InnoDB字符集 utf8mb4排序 utf8mb4_unicode_ci
- **分区策略**:高写入表按月分区,定期创建新分区+删除过期分区
---
## 二、业务库 cnc_business17张表
### 2.1 车间表 cnc_workshop
``sql
CREATE TABLE cnc_workshop (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL UNIQUE,
sort_order INT NOT NULL DEFAULT 0,
is_enabled TINYINT(1) NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='车间表';
``
无额外索引。3个车间数据量极小主键足够。
---
### 2.2 品牌模板表 cnc_brand
``sql
CREATE TABLE cnc_brand (
id INT AUTO_INCREMENT PRIMARY KEY,
brand_name VARCHAR(50) NOT NULL UNIQUE,
device_field VARCHAR(50) NOT NULL DEFAULT 'device',
tags_path VARCHAR(100) NOT NULL DEFAULT 'tags',
is_enabled TINYINT(1) NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='CNC品牌模板表';
``
所有品牌顶层结构统一device_field和tags_path默认值覆盖绝大多数品牌。品牌数量少无额外索引。
---
### 2.3 品牌字段映射表 cnc_brand_field_mapping
``sql
CREATE TABLE cnc_brand_field_mapping (
id INT AUTO_INCREMENT PRIMARY KEY,
brand_id INT NOT NULL,
standard_field VARCHAR(50) NOT NULL,
field_name VARCHAR(50) NOT NULL,
match_by VARCHAR(20) NOT NULL DEFAULT 'id',
data_type VARCHAR(20) NOT NULL DEFAULT 'string',
is_required TINYINT(1) NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (brand_id) REFERENCES cnc_brand(id) ON DELETE CASCADE,
UNIQUE KEY uk_brand_standard (brand_id, standard_field)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='品牌字段映射表';
``
**标准字段约定**(代码层面,不建表):
| standard_field | 含义 | data_type |
|----------------|------|-----------|
| program_name | NC程序名 | string |
| part_count | 当前加工零件数 | number |
| device_status | 设备状态 | number |
| run_status | 运行状态 | number |
| operate_mode | 操作模式 | number |
| spindle_speed_set | 主轴设定速度 | number |
| feed_speed_set | 进给设定速度 | number |
| spindle_speed_actual | 主轴实际速度 | number |
| feed_speed_actual | 进给实际转速 | number |
| spindle_load | 主轴负载 | number |
| spindle_override | 主轴倍率 | number |
| power_on_time | 开机时间 | number |
| run_time | 运行时间 | number |
| cutting_time | 切削时间 | number |
| cycle_time | 循环时间 | number |
| machining_status | 加工状态 | string |
索引uk_brand_standard唯一约束同时作为索引保证同一品牌下标准字段不重复采集时按brand_id查询所有映射规则。
---
### 2.4 采集地址表 cnc_collect_address
``sql
CREATE TABLE cnc_collect_address (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
url VARCHAR(500) NOT NULL,
brand_id INT NOT NULL,
collect_interval INT NOT NULL DEFAULT 30,
is_enabled TINYINT(1) NOT NULL DEFAULT 1,
last_collect_time DATETIME NULL,
last_collect_status VARCHAR(20) NULL,
fail_count INT NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (brand_id) REFERENCES cnc_brand(id),
INDEX idx_brand (brand_id),
INDEX idx_enabled (is_enabled)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采集地址表';
``
索引idx_brand用于采集服务按品牌加载地址列表idx_enabled用于只查启用的地址。last_collect_time/status/fail_count由采集服务实时更新大屏和管理后台直接查此表显示采集状态。
---
### 2.5 机床表 cnc_machine
``sql
CREATE TABLE cnc_machine (
id INT AUTO_INCREMENT PRIMARY KEY,
device_code VARCHAR(100) NOT NULL,
name VARCHAR(100) NOT NULL,
workshop_id INT NOT NULL,
collect_address_id INT NOT NULL,
ip_address VARCHAR(50) NOT NULL,
brand_id INT NOT NULL,
is_enabled TINYINT(1) NOT NULL DEFAULT 1,
is_online TINYINT(1) NOT NULL DEFAULT 0,
last_ping_time DATETIME NULL,
last_collect_time DATETIME NULL,
last_device_status VARCHAR(20) NULL,
last_run_status VARCHAR(20) NULL,
last_program_name VARCHAR(200) NULL,
last_part_count DECIMAL(15,5) NULL,
last_operate_mode VARCHAR(20) NULL,
last_machining_status VARCHAR(20) NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (workshop_id) REFERENCES cnc_workshop(id),
FOREIGN KEY (collect_address_id) REFERENCES cnc_collect_address(id),
FOREIGN KEY (brand_id) REFERENCES cnc_brand(id),
UNIQUE KEY uk_device_code (device_code),
INDEX idx_workshop (workshop_id),
INDEX idx_collect_address (collect_address_id),
INDEX idx_enabled_online (is_enabled, is_online),
INDEX idx_enabled_address (is_enabled, collect_address_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='CNC机床表';
``
索引设计:
- uk_device_code采集时用device值匹配机床唯一约束防重复
- idx_workshop按车间筛选机床
- idx_enabled_online大屏查在线+可用机床列表,高频查询
- idx_enabled_address采集服务按地址查启用的机床列表
实时状态字段故意冗余到机床表大屏和首页查询只读此表不JOIN采集记录表避免高频查询大表。
---
### 2.6 工人表 cnc_worker
``sql
CREATE TABLE cnc_worker (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
code VARCHAR(50) NOT NULL UNIQUE,
is_enabled TINYINT(1) NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工人表';
``
工人不归属车间。uk_code覆盖工号查询。
---
### 2.7 工人-机床绑定表 cnc_worker_machine
``sql
CREATE TABLE cnc_worker_machine (
id INT AUTO_INCREMENT PRIMARY KEY,
worker_id INT NOT NULL,
machine_id INT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (worker_id) REFERENCES cnc_worker(id) ON DELETE CASCADE,
FOREIGN KEY (machine_id) REFERENCES cnc_machine(id) ON DELETE CASCADE,
UNIQUE KEY uk_machine (machine_id),
INDEX idx_worker (worker_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工人-机床绑定表';
``
索引uk_machine保证一对一绑定同时作为按机床查工人的索引idx_worker用于按工人查机床列表。
---
### 2.8 采集结构化记录表 cnc_collect_record按月分区高频写入
``sql
CREATE TABLE cnc_collect_record (
id BIGINT AUTO_INCREMENT,
machine_id INT NOT NULL,
collect_time DATETIME NOT NULL,
device_time DATETIME NULL,
program_name VARCHAR(200) NULL,
part_count DECIMAL(15,5) NULL,
device_status VARCHAR(20) NULL,
run_status VARCHAR(20) NULL,
operate_mode VARCHAR(20) NULL,
spindle_speed_set DECIMAL(15,5) NULL,
feed_speed_set DECIMAL(15,5) NULL,
spindle_speed_actual DECIMAL(15,5) NULL,
feed_speed_actual DECIMAL(15,5) NULL,
spindle_load DECIMAL(15,5) NULL,
spindle_override DECIMAL(5,2) NULL,
power_on_time DECIMAL(15,2) NULL,
run_time DECIMAL(15,2) NULL,
cutting_time DECIMAL(15,2) NULL,
cycle_time DECIMAL(15,2) NULL,
machining_status VARCHAR(20) NULL,
extra_data JSON NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id, collect_time),
INDEX idx_machine_time (machine_id, collect_time),
INDEX idx_collect_time (collect_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='采集结构化记录表按月分区90天自动清理'
PARTITION BY RANGE (TO_DAYS(collect_time)) (
PARTITION p202604 VALUES LESS THAN (TO_DAYS('2026-05-01')),
PARTITION p202605 VALUES LESS THAN (TO_DAYS('2026-06-01')),
PARTITION p202606 VALUES LESS THAN (TO_DAYS('2026-07-01')),
PARTITION p_future VALUES LESS THAN MAXVALUE
);
``
索引设计:
- idx_machine_time最核心索引覆盖查某台机床某时间段采集数据报表、趋势图、日汇总计算
- idx_collect_time覆盖查某个时间点所有机床数据全局状态快照
分区策略按月分区删除过期数据只需DROP PARTITION避免DELETE大量行导致锁表和碎片。
数据量估算160台 x 每天约2000条 = 32万/天90天约2900万行。分区后单分区约300万行。
---
### 2.9 产量分段记录表 cnc_production_segment
``sql
CREATE TABLE cnc_production_segment (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
machine_id INT NOT NULL,
program_name VARCHAR(200) NOT NULL,
production_date DATE NOT NULL,
start_time DATETIME NOT NULL,
end_time DATETIME NULL,
start_part_count DECIMAL(15,5) NOT NULL,
end_part_count DECIMAL(15,5) NULL,
quantity DECIMAL(15,5) NULL,
is_settled TINYINT(1) NOT NULL DEFAULT 0,
close_reason VARCHAR(30) NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (machine_id) REFERENCES cnc_machine(id),
INDEX idx_machine_date (machine_id, production_date),
INDEX idx_machine_date_program (machine_id, production_date, program_name),
INDEX idx_active (machine_id, is_settled, end_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='产量分段记录表';
``
核心逻辑:每次采集检测到以下情况时结账当前段并开新段:
1. NC程序名变化 -> close_reason = 'program_change'
2. 同程序下part_count下降 -> close_reason = 'manual_reset'
3. 日终汇总时仍在运行 -> close_reason = 'end_of_day'
4. 采集服务停止时 -> close_reason = 'service_stop'
A-B-C-A-B场景程序A第二次出现时创建新的段记录日汇总按(machine_id, production_date, program_name)合并。
索引设计:
- idx_machine_date日汇总计算时查某台机床某天的所有段
- idx_machine_date_program查某台机床某天某个程序的所有段合并计算
- idx_active采集服务运行时快速查找当前活跃段is_settled=0, end_time IS NULL
---
### 2.10 机床日状态表 cnc_machine_daily_status
``sql
CREATE TABLE cnc_machine_daily_status (
id INT AUTO_INCREMENT PRIMARY KEY,
machine_id INT NOT NULL,
production_date DATE NOT NULL,
data_status VARCHAR(20) NOT NULL DEFAULT 'normal',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (machine_id) REFERENCES cnc_machine(id),
UNIQUE KEY uk_machine_date (machine_id, production_date),
INDEX idx_date_status (production_date, data_status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='机床日状态表';
``
data_status规则
- normal当天至少成功采集过一次
- offline当天从未Ping通产量=0
- data_missingPing通但采集始终失败前端显示-而非0
索引uk_machine_date保证每台机床每天只有一条状态记录idx_date_status支持按天查特定状态机床。
---
### 2.11 日汇总表 cnc_daily_production按机床+程序)
``sql
CREATE TABLE cnc_daily_production (
id INT AUTO_INCREMENT PRIMARY KEY,
machine_id INT NOT NULL,
production_date DATE NOT NULL,
program_name VARCHAR(200) NOT NULL,
total_quantity DECIMAL(15,5) NOT NULL DEFAULT 0,
segment_count INT NOT NULL DEFAULT 1,
total_run_time DECIMAL(15,2) NULL,
total_cutting_time DECIMAL(15,2) NULL,
total_cycle_time DECIMAL(15,2) NULL,
is_adjusted TINYINT(1) NOT NULL DEFAULT 0,
adjusted_quantity DECIMAL(15,5) NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (machine_id) REFERENCES cnc_machine(id),
UNIQUE KEY uk_machine_date_program (machine_id, production_date, program_name),
INDEX idx_date (production_date),
INDEX idx_date_program (production_date, program_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='日汇总表(按机床+程序)';
``
索引设计:
- uk_machine_date_program唯一约束+最核心查询索引
- idx_date按日期查所有汇总
- idx_date_program按日期+程序名查汇总
---
### 2.12 工人日汇总表 cnc_worker_daily_summary
``sql
CREATE TABLE cnc_worker_daily_summary (
id INT AUTO_INCREMENT PRIMARY KEY,
worker_id INT NOT NULL,
production_date DATE NOT NULL,
total_quantity DECIMAL(15,5) NOT NULL DEFAULT 0,
machine_count INT NOT NULL DEFAULT 0,
program_count INT NOT NULL DEFAULT 0,
is_adjusted TINYINT(1) NOT NULL DEFAULT 0,
adjusted_quantity DECIMAL(15,5) NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (worker_id) REFERENCES cnc_worker(id) ON DELETE CASCADE,
UNIQUE KEY uk_worker_date (worker_id, production_date),
INDEX idx_date (production_date),
INDEX idx_date_quantity (production_date, total_quantity)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工人日汇总表';
``
索引设计:
- uk_worker_date唯一约束+核心查询
- idx_date按日期查所有工人汇总
- idx_date_quantity排行榜核心索引按日期查产量排名覆盖大屏排行榜高频查询
---
### 2.13 产量修正审计表 cnc_production_adjustment
``sql
CREATE TABLE cnc_production_adjustment (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
target_table VARCHAR(30) NOT NULL,
target_id INT NOT NULL,
field_name VARCHAR(50) NOT NULL,
old_value DECIMAL(15,5) NULL,
new_value DECIMAL(15,5) NOT NULL,
reason VARCHAR(500) NOT NULL,
operator_ip VARCHAR(50) NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_target (target_table, target_id),
INDEX idx_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='产量修正审计表';
``
索引idx_target用于查某条记录的修正历史idx_created用于按时间查审计日志。
---
### 2.14 告警表 cnc_alert
``sql
CREATE TABLE cnc_alert (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
alert_type VARCHAR(30) NOT NULL,
machine_id INT NULL,
collect_address_id INT NULL,
title VARCHAR(200) NOT NULL,
detail TEXT NULL,
is_resolved TINYINT(1) NOT NULL DEFAULT 0,
resolved_at DATETIME NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (machine_id) REFERENCES cnc_machine(id) ON DELETE SET NULL,
FOREIGN KEY (collect_address_id) REFERENCES cnc_collect_address(id) ON DELETE SET NULL,
INDEX idx_type_resolved (alert_type, is_resolved),
INDEX idx_machine_time (machine_id, created_at),
INDEX idx_created (created_at),
INDEX idx_unresolved (is_resolved, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='告警表';
``
告警类型collect_fail / device_offline / production_anomaly / unknown_device / service_error
索引设计:
- idx_type_resolved按类型查未处理告警
- idx_machine_time查某台机床的告警历史
- idx_unresolved管理后台最常用查询查所有未处理告警按时间排序
---
### 2.15 系统配置表 cnc_sys_config
``sql
CREATE TABLE cnc_sys_config (
id INT AUTO_INCREMENT PRIMARY KEY,
config_key VARCHAR(100) NOT NULL UNIQUE,
config_value TEXT NOT NULL,
value_type VARCHAR(20) NOT NULL DEFAULT 'string',
description VARCHAR(200) NULL,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统配置表';
``
预置配置项:
| config_key | 默认值 | 说明 |
|------------|--------|------|
| ping_interval | 60 | Ping检测间隔(秒) |
| collect_retry_count | 3 | 采集失败重试次数 |
| collect_retry_interval | 30 | 采集重试间隔(秒) |
| collect_fail_alert_threshold | 5 | 连续失败N次触发告警 |
| heartbeat_interval | 10 | 心跳写入间隔(秒) |
| daily_summary_time | 01:00 | 日终汇总执行时间 |
| config_poll_interval | 30 | 采集服务轮询配置间隔(秒) |
| log_retention_days | 90 | 原始采集日志保留天数 |
| system_log_retention_days | 30 | 系统日志保留天数 |
| alert_log_retention_days | 180 | 异常日志保留天数 |
| heartbeat_retention_days | 7 | 心跳记录保留天数 |
| bigscreen_refresh_interval | 10 | 大屏刷新间隔(秒) |
| api_token | (自动生成) | 前端API Token |
| collector_api_port | 5800 | 采集服务管理API端口 |
| collector_api_key | (自动生成) | 采集服务间通信API Key |
| error_retry_base_interval | 60 | 任务错误重试基础间隔(秒) |
| admin_username | admin | 管理员用户名(不可修改) |
| admin_password_hash | (bcrypt hash of admin123) | 管理员密码哈希 |
---
### 2.16 大屏配置表 cnc_screen_config
``sql
CREATE TABLE cnc_screen_config (
id INT AUTO_INCREMENT PRIMARY KEY,
card_key VARCHAR(50) NOT NULL UNIQUE,
card_type VARCHAR(30) NOT NULL,
title VARCHAR(100) NOT NULL,
metric VARCHAR(50) NOT NULL,
dimension VARCHAR(30) NULL,
sort_order INT NOT NULL DEFAULT 0,
is_enabled TINYINT(1) NOT NULL DEFAULT 1,
chart_config JSON NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='大屏卡片配置表';
``
card_type类型stat_number / bar_chart / line_chart / pie_chart / status_grid / rank_list
预置卡片:
| card_key | card_type | title | metric | dimension |
|----------|-----------|-------|--------|-----------|
| total_online | stat_number | 在线机床数 | online_count | - |
| total_production_today | stat_number | 今日总产量 | part_count | - |
| workshop_production | bar_chart | 各车间产量 | part_count | workshop |
| worker_rank | rank_list | 工人产量排行 | part_count | worker |
| machine_rank | rank_list | 机床产量排行 | part_count | machine |
| machine_status | status_grid | 机床状态总览 | - | - |
| collector_status | stat_number | 采集服务状态 | - | - |
| production_trend | line_chart | 产量趋势(7天) | part_count | - |
---
### 2.17 大屏筛选配置表 cnc_screen_filter
``sql
CREATE TABLE cnc_screen_filter (
id INT AUTO_INCREMENT PRIMARY KEY,
screen_key VARCHAR(50) NOT NULL,
filter_type VARCHAR(30) NOT NULL,
filter_value VARCHAR(100) NOT NULL,
is_default TINYINT(1) NOT NULL DEFAULT 0,
sort_order INT NOT NULL DEFAULT 0,
UNIQUE KEY uk_screen_filter (screen_key, filter_type, filter_value)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='大屏筛选配置表';
``
---
## 三、日志库 cnc_log5张表
### 3.1 原始采集JSON表 log_collect_raw按月分区
``sql
CREATE TABLE log_collect_raw (
id BIGINT AUTO_INCREMENT,
collect_address_id INT NOT NULL,
request_time DATETIME NOT NULL,
response_time DATETIME NOT NULL,
response_duration INT NULL,
is_success TINYINT(1) NOT NULL DEFAULT 1,
status_code INT NULL,
raw_json MEDIUMTEXT NOT NULL,
error_message VARCHAR(500) NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id, request_time),
INDEX idx_address_time (collect_address_id, request_time),
INDEX idx_request_time (request_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='原始采集JSON表按月分区90天自动清理'
PARTITION BY RANGE (TO_DAYS(request_time)) (
PARTITION p202604 VALUES LESS THAN (TO_DAYS('2026-05-01')),
PARTITION p202605 VALUES LESS THAN (TO_DAYS('2026-06-01')),
PARTITION p202606 VALUES LESS THAN (TO_DAYS('2026-07-01')),
PARTITION p_future VALUES LESS THAN MAXVALUE
);
``
数据量估算每30秒一次采集 x 5-10个地址 x 86400秒/天 = 1.4-2.9万条/天每条约20KB = 280-580MB/天。90天约25-52GB。
---
### 3.2 系统日志表 log_system按月分区
``sql
CREATE TABLE log_system (
id BIGINT AUTO_INCREMENT,
log_level VARCHAR(10) NOT NULL,
source VARCHAR(50) NOT NULL,
message TEXT NOT NULL,
stack_trace TEXT NULL,
extra_data JSON NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id, created_at),
INDEX idx_level_time (log_level, created_at),
INDEX idx_source_time (source, created_at),
INDEX idx_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='系统日志表按月分区30天自动清理'
PARTITION BY RANGE (TO_DAYS(created_at)) (
PARTITION p202604 VALUES LESS THAN (TO_DAYS('2026-05-01')),
PARTITION p202605 VALUES LESS THAN (TO_DAYS('2026-06-01')),
PARTITION p202606 VALUES LESS THAN (TO_DAYS('2026-07-01')),
PARTITION p_future VALUES LESS THAN MAXVALUE
);
``
---
### 3.3 采集服务心跳表 log_collector_heartbeat
``sql
CREATE TABLE log_collector_heartbeat (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
service_id VARCHAR(50) NOT NULL DEFAULT 'CncCollector',
status VARCHAR(20) NOT NULL,
collect_address_id INT NULL,
last_collect_time DATETIME NULL,
success_count INT NOT NULL DEFAULT 0,
fail_count INT NOT NULL DEFAULT 0,
uptime_seconds BIGINT NULL,
detail JSON NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_service_time (service_id, created_at),
INDEX idx_address_time (collect_address_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采集服务心跳表7天自动清理';
``
心跳检测逻辑Web API查WHERE service_id='CncCollector' AND created_at > NOW() - INTERVAL 30 SECOND有记录=运行中,无记录=已停止。
---
### 3.4 采集分析日志表 log_collect_analysis按月分区
记录每次采集后对每台机床的数据变化分析。每次采集周期中,每台机床产生一条分析记录,包含与上一次采集数据的对比结果。
``sql
CREATE TABLE log_collect_analysis (
id BIGINT AUTO_INCREMENT,
analysis_time DATETIME NOT NULL COMMENT '分析时间(分区键)',
raw_log_id BIGINT NOT NULL COMMENT '关联原始日志IDlog_collect_raw.id',
collect_address_id INT NOT NULL COMMENT '采集地址ID关联cnc_collect_address',
machine_id INT NOT NULL COMMENT '机床ID关联cnc_machine',
analysis_type VARCHAR(30) NOT NULL COMMENT '分析类型枚举',
previous_program VARCHAR(200) NULL COMMENT '上一次NC程序名',
current_program VARCHAR(200) NULL COMMENT '本次NC程序名',
previous_part_count DECIMAL(15,5) NULL COMMENT '上一次零件计数',
current_part_count DECIMAL(15,5) NULL COMMENT '本次零件计数',
part_count_delta DECIMAL(15,5) NULL COMMENT '零件计数变化量(正=增加,负=减少)',
previous_status VARCHAR(20) NULL COMMENT '上一次设备状态',
current_status VARCHAR(20) NULL COMMENT '本次设备状态',
analysis_summary VARCHAR(500) NOT NULL COMMENT '人类可读的分析摘要',
analysis_detail JSON NULL COMMENT '完整的字段级对比数据JSON',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id, analysis_time),
INDEX idx_address_time (collect_address_id, analysis_time),
INDEX idx_machine_time (machine_id, analysis_time),
INDEX idx_type_time (analysis_type, analysis_time),
INDEX idx_raw_log (raw_log_id),
INDEX idx_program_time (current_program, analysis_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='采集分析日志表(按月分区,记录每次采集对每台机床的数据变化分析)'
PARTITION BY RANGE (TO_DAYS(analysis_time)) (
PARTITION p202605 VALUES LESS THAN (TO_DAYS('2026-06-01')),
PARTITION p202606 VALUES LESS THAN (TO_DAYS('2026-07-01')),
PARTITION p202607 VALUES LESS THAN (TO_DAYS('2026-08-01')),
PARTITION p_future VALUES LESS THAN MAXVALUE
);
``
**analysis_type 分析类型枚举:**
| 值 | 含义 | 说明 |
|----|------|------|
| NORMAL_UNCHANGED | 正常无变化 | 数据与上次一致,正常加工中 |
| PART_COUNT_INCREASE | 零件数增加 | 零件计数增长,正常加工中 |
| PROGRAM_SWITCH | NC程序切换 | 程序名变更,触发上一段结账 |
| MANUAL_RESET | 手动清零 | 同程序下零件计数下降 |
| DEVICE_ONLINE | 设备上线 | 设备从离线恢复在线 |
| DEVICE_OFFLINE | 设备离线 | 设备变为离线状态 |
| NEW_DEVICE_FOUND | 发现新设备 | 采集到未注册的device |
| DATA_ANOMALY | 数据异常 | 字段缺失/格式错误/值异常 |
| COLLECTION_FAILED | 采集失败 | 本次采集请求失败 |
**数据量估算**每次采集周期×每台机床1条。假设每30秒1次采集×5-10个地址×每地址2-5台机床 = 600-2500条/分钟 = 约86-360万条/天。按月分区便于查询和清理。
---
### 3.5 采集周期汇总表 log_collect_cycle按月分区
记录每次采集周期一个地址的一次完整HTTP采集的汇总信息。一个周期对应 log_collect_raw 中的一条记录和 log_collect_analysis 中的多条记录。
``sql
CREATE TABLE log_collect_cycle (
id BIGINT AUTO_INCREMENT,
cycle_time DATETIME NOT NULL COMMENT '周期开始时间(分区键)',
collect_address_id INT NOT NULL COMMENT '采集地址ID关联cnc_collect_address',
raw_log_id BIGINT NOT NULL COMMENT '关联原始日志IDlog_collect_raw.id',
end_time DATETIME NULL COMMENT '周期结束时间',
duration_ms INT NULL COMMENT '本次采集总耗时(毫秒)',
total_machines INT NOT NULL DEFAULT 0 COMMENT '本周期采集的机床总数',
success_count INT NOT NULL DEFAULT 0 COMMENT '成功采集的机床数',
fail_count INT NOT NULL DEFAULT 0 COMMENT '失败采集的机床数',
change_distribution JSON NULL COMMENT '变化类型分布(如 {"PROGRAM_SWITCH":2,"PART_COUNT_INCREASE":5}',
has_anomaly TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否存在异常1=有异常)',
cycle_summary VARCHAR(500) NULL COMMENT '人类可读的周期汇总',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id, cycle_time),
INDEX idx_address_time (collect_address_id, cycle_time),
INDEX idx_time (cycle_time),
INDEX idx_anomaly_time (has_anomaly, cycle_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='采集周期汇总表(按月分区,每次采集周期的汇总信息)'
PARTITION BY RANGE (TO_DAYS(cycle_time)) (
PARTITION p202605 VALUES LESS THAN (TO_DAYS('2026-06-01')),
PARTITION p202606 VALUES LESS THAN (TO_DAYS('2026-07-01')),
PARTITION p202607 VALUES LESS THAN (TO_DAYS('2026-08-01')),
PARTITION p_future VALUES LESS THAN MAXVALUE
);
``
**数据量估算**每次采集1条。每30秒×5-10个地址 = 10-20条/分钟 = 约1.4-2.9万条/天。远小于分析表,查询负担轻。
---
## 四、ER关系总览
`
cnc_workshop 1-----N cnc_machine
cnc_brand 1-----N cnc_brand_field_mapping
cnc_brand 1-----N cnc_collect_address
cnc_collect_address 1--N cnc_machine
cnc_machine 1-----1 cnc_worker_machine (uk_machine)
cnc_worker 1-----N cnc_worker_machine
cnc_machine 1-----N cnc_collect_record
cnc_machine 1-----N cnc_production_segment
cnc_machine 1-----N cnc_daily_production
cnc_machine 1-----N cnc_machine_daily_status
cnc_worker 1-----N cnc_worker_daily_summary
cnc_daily_production 1--N cnc_production_adjustment
cnc_worker_daily_summary 1--N cnc_production_adjustment
cnc_machine 1-----N cnc_alert
--- 日志库 ---
cnc_collect_address 1--N log_collect_raw (弱关联,跨库)
log_collect_raw 1--N log_collect_analysis (原始日志→分析记录)
log_collect_raw 1---1 log_collect_cycle (原始日志→周期汇总)
cnc_machine 1--N log_collect_analysis (弱关联,跨库)
cnc_collect_address 1--N log_collect_cycle (弱关联,跨库)
log_collector_heartbeat (独立弱关联collect_address_id)
log_system (独立)
`
---
## 五、分区维护策略
| 任务 | 频率 | 操作 |
|------|------|------|
| 创建新分区 | 每月1日 | 为cnc_collect_record、log_collect_raw、log_system、log_collect_analysis、log_collect_cycle预创建下下月分区 |
| 删除过期分区 | 每月1日 | DROP超过保留期的分区保留天数=0时不删除 |
| 清理心跳表 | 每天 | DELETE log_collector_heartbeat超过7天的记录保留天数=0时不删除 |
| 清理告警表 | 每天 | DELETE cnc_alert已处理且超过180天的记录 |
---
## 六、索引设计总览
| 表 | 索引名 | 类型 | 覆盖场景 |
|----|--------|------|---------|
| cnc_brand_field_mapping | uk_brand_standard | UNIQUE | 按品牌查映射规则 |
| cnc_collect_address | idx_brand | INDEX | 按品牌加载地址 |
| cnc_collect_address | idx_enabled | INDEX | 查启用的地址 |
| cnc_machine | uk_device_code | UNIQUE | 采集device匹配 |
| cnc_machine | idx_workshop | INDEX | 按车间筛选 |
| cnc_machine | idx_enabled_online | INDEX | 大屏在线机床查询 |
| cnc_machine | idx_enabled_address | INDEX | 采集服务按地址查机床 |
| cnc_worker_machine | uk_machine | UNIQUE | 一对一绑定+按机床查工人 |
| cnc_worker_machine | idx_worker | INDEX | 按工人查机床列表 |
| cnc_collect_record | idx_machine_time | INDEX | 报表/趋势图/汇总计算 |
| cnc_collect_record | idx_collect_time | INDEX | 全局状态快照 |
| cnc_production_segment | idx_machine_date | INDEX | 日汇总计算 |
| cnc_production_segment | idx_machine_date_program | INDEX | 按程序合并计算 |
| cnc_production_segment | idx_active | INDEX | 查找活跃段 |
| cnc_machine_daily_status | uk_machine_date | UNIQUE | 每天一条状态 |
| cnc_machine_daily_status | idx_date_status | INDEX | 按天查状态 |
| cnc_daily_production | uk_machine_date_program | UNIQUE | 机床+日+程序唯一 |
| cnc_daily_production | idx_date | INDEX | 按日期查汇总 |
| cnc_daily_production | idx_date_program | INDEX | 按日期+程序查 |
| cnc_worker_daily_summary | uk_worker_date | UNIQUE | 工人+日唯一 |
| cnc_worker_daily_summary | idx_date | INDEX | 按日期查工人汇总 |
| cnc_worker_daily_summary | idx_date_quantity | INDEX | 排行榜查询 |
| cnc_production_adjustment | idx_target | INDEX | 修正历史查询 |
| cnc_production_adjustment | idx_created | INDEX | 审计日志时间查询 |
| cnc_alert | idx_type_resolved | INDEX | 按类型查未处理 |
| cnc_alert | idx_machine_time | INDEX | 机床告警历史 |
| cnc_alert | idx_unresolved | INDEX | 未处理告警列表 |
| log_collect_raw | idx_address_time | INDEX | 按地址查原始数据 |
| log_collect_raw | idx_request_time | INDEX | 时间范围清理 |
| log_system | idx_level_time | INDEX | 按级别查错误日志 |
| log_system | idx_source_time | INDEX | 按来源查日志 |
| log_collect_raw | idx_success_time | INDEX | 按成功/失败筛选 |
| log_collect_analysis | idx_address_time | INDEX | 按采集地址+时间查分析 |
| log_collect_analysis | idx_machine_time | INDEX | 按机床+时间查分析 |
| log_collect_analysis | idx_type_time | INDEX | 按分析类型+时间查 |
| log_collect_analysis | idx_raw_log | INDEX | 按原始日志ID关联查 |
| log_collect_analysis | idx_program_time | INDEX | 按NC程序名+时间查 |
| log_collect_cycle | idx_address_time | INDEX | 按采集地址+时间查周期 |
| log_collect_cycle | idx_time | INDEX | 时间范围查询 |
| log_collect_cycle | idx_anomaly_time | INDEX | 查异常周期 |
| log_collector_heartbeat | idx_service_time | INDEX | 服务最新状态 |
| log_collector_heartbeat | idx_address_time | INDEX | 地址心跳历史 |
共计22张表43个索引含唯一索引