-- CNC机床数据采集分析系统数据库脚本
-- 创建时间: 2024-01-01
-- 数据库: cnc_log (日志库)

-- 1. 原始采集数据表
-- 原始采集数据表
CREATE TABLE `raw_collection_data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `device_id` int(11) NOT NULL COMMENT '设备ID',
  `collection_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '采集时间',
  `raw_json` json NOT NULL COMMENT '原始JSON数据',
  `is_success` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否成功',
  `error_message` text DEFAULT NULL COMMENT '错误信息',
  `retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '重试次数',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_device_id` (`device_id`),
  KEY `idx_collection_time` (`collection_time`),
  KEY `idx_is_success` (`is_success`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='原始采集数据表';

-- 2. 系统日志表
-- 系统日志表
CREATE TABLE `system_logs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `log_level` varchar(20) NOT NULL COMMENT '日志级别',
  `log_category` varchar(50) NOT NULL COMMENT '日志类别',
  `log_message` text NOT NULL COMMENT '日志消息',
  `log_data` json DEFAULT NULL COMMENT '日志数据',
  `source_method` varchar(255) DEFAULT NULL COMMENT '来源方法',
  `source_file` varchar(255) DEFAULT NULL COMMENT '来源文件',
  `log_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '日志时间',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_log_level` (`log_level`),
  KEY `idx_log_category` (`log_category`),
  KEY `idx_log_time` (`log_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统日志表';

-- 3. 采集历史表
-- 采集历史表
CREATE TABLE `collection_history` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `device_id` int(11) NOT NULL COMMENT '设备ID',
  `collection_status` varchar(20) NOT NULL COMMENT '采集状态',
  `response_time` int(11) DEFAULT NULL COMMENT '响应时间（毫秒）',
  `data_size` int(11) DEFAULT NULL COMMENT '数据大小（字节）',
  `error_message` text DEFAULT NULL COMMENT '错误信息',
  `collection_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '采集时间',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_device_id` (`device_id`),
  KEY `idx_collection_time` (`collection_time`),
  KEY `idx_collection_status` (`collection_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='采集历史表';

-- 4. 性能监控表
-- 性能监控表
CREATE TABLE `performance_metrics` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `metric_name` varchar(50) NOT NULL COMMENT '指标名称',
  `metric_value` decimal(10,2) NOT NULL COMMENT '指标值',
  `metric_unit` varchar(20) DEFAULT NULL COMMENT '指标单位',
  `collection_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '采集时间',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_metric_name` (`metric_name`),
  KEY `idx_collection_time` (`collection_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='性能监控表';

-- 5. 告警历史表
-- 告警历史表
CREATE TABLE `alarm_history` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `alarm_type` varchar(50) NOT NULL COMMENT '告警类型',
  `alarm_level` varchar(20) NOT NULL COMMENT '告警级别',
  `alarm_content` text NOT NULL COMMENT '告警内容',
  `device_id` int(11) DEFAULT NULL COMMENT '关联设备ID',
  `device_name` varchar(100) DEFAULT NULL COMMENT '设备名称',
  `is_resolved` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已解决',
  `occurrence_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发生时间',
  `resolution_time` datetime DEFAULT NULL COMMENT '解决时间',
  `resolution_note` text DEFAULT NULL COMMENT '解决备注',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_alarm_type` (`alarm_type`),
  KEY `idx_alarm_level` (`alarm_level`),
  KEY `idx_device_id` (`device_id`),
  KEY `idx_occurrence_time` (`occurrence_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='告警历史表';

-- 6. 操作日志表
-- 操作日志表
CREATE TABLE `operation_logs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL COMMENT '用户ID',
  `username` varchar(50) DEFAULT NULL COMMENT '用户名',
  `operation_type` varchar(50) NOT NULL COMMENT '操作类型',
  `operation_target` varchar(100) DEFAULT NULL COMMENT '操作目标',
  `operation_details` text DEFAULT NULL COMMENT '操作详情',
  `ip_address` varchar(45) DEFAULT NULL COMMENT 'IP地址',
  `user_agent` text DEFAULT NULL COMMENT '用户代理',
  `operation_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_username` (`username`),
  KEY `idx_operation_type` (`operation_type`),
  KEY `idx_operation_time` (`operation_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表';

-- 7. 数据归档表
-- 数据归档表
CREATE TABLE `data_archive` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `archive_type` varchar(50) NOT NULL COMMENT '归档类型',
  `table_name` varchar(100) NOT NULL COMMENT '表名',
  `record_id` int(11) NOT NULL COMMENT '记录ID',
  `archive_data` json NOT NULL COMMENT '归档数据',
  `archive_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '归档时间',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_archive_type` (`archive_type`),
  KEY `idx_table_name` (`table_name`),
  KEY `idx_archive_time` (`archive_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据归档表';

-- 8. 索引优化表
-- 数据库性能统计表
CREATE TABLE `db_performance_stats` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `query_type` varchar(50) NOT NULL COMMENT '查询类型',
  `query_count` int(11) NOT NULL DEFAULT '0' COMMENT '查询次数',
  `avg_execution_time` decimal(10,3) DEFAULT '0.000' COMMENT '平均执行时间',
  `total_execution_time` decimal(10,3) DEFAULT '0.000' COMMENT '总执行时间',
  `slow_query_count` int(11) NOT NULL DEFAULT '0' COMMENT '慢查询次数',
  `stats_date` date NOT NULL COMMENT '统计日期',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_query_type_date` (`query_type`,`stats_date`),
  KEY `idx_stats_date` (`stats_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据库性能统计表';

-- 9. 创建触发器用于自动归档
-- 自动归档旧数据的触发器
DELIMITER //
CREATE TRIGGER before_system_logs_insert
BEFORE INSERT ON system_logs
FOR EACH ROW
BEGIN
    -- 检查是否需要归档旧日志
    DECLARE archive_threshold DATE;
    SET archive_threshold = DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY);
    
    -- 归档30天前的日志
    INSERT INTO data_archive (archive_type, table_name, record_id, archive_data, archive_time)
    SELECT 'system_logs', 'system_logs', id, 
           JSON_OBJECT('id', id, 'log_level', log_level, 'log_category', log_category, 
                       'log_message', log_message, 'log_data', log_data, 
                       'source_method', source_method, 'source_file', source_file, 
                       'log_time', log_time, 'created_at', created_at),
           NOW()
    FROM system_logs 
    WHERE log_time < archive_threshold
    LIMIT 1000;
    
    -- 删除已归档的日志
    DELETE FROM system_logs 
    WHERE log_time < archive_threshold
    LIMIT 1000;
END//
DELIMITER ;

-- 10. 创建存储过程用于数据清理
-- 清理过期数据的存储过程
DELIMITER //
CREATE PROCEDURE CleanExpiredData(IN days_to_keep INT)
BEGIN
    -- 设置保留天数
    DECLARE archive_date DATE;
    SET archive_date = DATE_SUB(CURRENT_DATE, INTERVAL days_to_keep DAY);
    
    -- 归档原始采集数据
    INSERT INTO data_archive (archive_type, table_name, record_id, archive_data, archive_time)
    SELECT 'raw_collection_data', 'raw_collection_data', id, 
           JSON_OBJECT('id', id, 'device_id', device_id, 'collection_time', collection_time, 
                       'raw_json', raw_json, 'is_success', is_success, 
                       'error_message', error_message, 'retry_count', retry_count, 
                       'created_at', created_at),
           NOW()
    FROM raw_collection_data 
    WHERE collection_time < archive_date
    LIMIT 1000;
    
    -- 删除已归档的数据
    DELETE FROM raw_collection_data 
    WHERE collection_time < archive_date
    LIMIT 1000;
    
    -- 归档采集历史
    INSERT INTO data_archive (archive_type, table_name, record_id, archive_data, archive_time)
    SELECT 'collection_history', 'collection_history', id, 
           JSON_OBJECT('id', id, 'device_id', device_id, 'collection_status', collection_status, 
                       'response_time', response_time, 'data_size', data_size, 
                       'error_message', error_message, 'collection_time', collection_time, 
                       'created_at', created_at),
           NOW()
    FROM collection_history 
    WHERE collection_time < archive_date
    LIMIT 1000;
    
    -- 删除已归档的历史
    DELETE FROM collection_history 
    WHERE collection_time < archive_date
    LIMIT 1000;
    
    -- 归档性能数据
    INSERT INTO data_archive (archive_type, table_name, record_id, archive_data, archive_time)
    SELECT 'performance_metrics', 'performance_metrics', id, 
           JSON_OBJECT('id', id, 'metric_name', metric_name, 'metric_value', metric_value, 
                       'metric_unit', metric_unit, 'collection_time', collection_time, 
                       'created_at', created_at),
           NOW()
    FROM performance_metrics 
    WHERE collection_time < archive_date
    LIMIT 1000;
    
    -- 删除已归档的性能数据
    DELETE FROM performance_metrics 
    WHERE collection_time < archive_date
    LIMIT 1000;
    
    -- 记录清理日志
    INSERT INTO system_logs (log_level, log_category, log_message, log_data)
    VALUES ('INFO', 'DATA_CLEANUP', 
           CONCAT('Cleaned data older than ', days_to_keep, ' days'),
           JSON_OBJECT('days_to_keep', days_to_keep, 'archive_date', archive_date));
END//
DELIMITER ;

-- 11. 创建事件定期执行数据清理
-- 创建每天凌晨2点执行的数据清理事件
CREATE EVENT IF NOT EXISTS daily_data_cleanup
ON SCHEDULE EVERY 1 DAY
STARTS TIMESTAMP(CURRENT_DATE + INTERVAL 1 DAY, '02:00:00')
DO
    CALL CleanExpiredData(30);

-- 创建每月执行的性能统计事件
CREATE EVENT IF NOT EXISTS monthly_performance_stats
ON SCHEDULE EVERY 1 MONTH
STARTS TIMESTAMP(CURRENT_DATE + INTERVAL 1 MONTH, '03:00:00')
DO
    -- 统计上月性能数据
    INSERT INTO db_performance_stats (query_type, query_count, avg_execution_time, total_execution_time, slow_query_count, stats_date)
    SELECT 
        'SELECT',
        COUNT(*),
        AVG(TIME_TO_SEC(query_time) / 1000),
        SUM(TIME_TO_SEC(query_time) / 1000),
        SUM(CASE WHEN TIME_TO_SEC(query_time) / 1000 > 1 THEN 1 ELSE 0 END),
        LAST_DAY(DATE_SUB(CURRENT_DATE, INTERVAL 1 MONTH)) AS last_day
    FROM system_logs 
    WHERE log_time >= LAST_DAY(DATE_SUB(CURRENT_DATE, INTERVAL 1 MONTH)) 
      AND log_time < LAST_DAY(CURRENT_DATE)
      AND log_category = 'DATABASE_QUERY';

-- 12. 创建视图用于查询
-- 创建设备状态汇总视图
CREATE VIEW v_device_status_summary AS
SELECT 
    d.id,
    d.device_code,
    d.device_name,
    d.ip_address,
    d.is_online,
    d.is_available,
    d.last_collection_time,
    MAX(ds.record_time) as last_status_time,
    COUNT(ds.id) as status_count,
    MAX(CASE WHEN ds.is_running = 1 THEN 1 ELSE 0 END) as is_any_running
FROM devices d
LEFT JOIN device_status ds ON d.id = ds.device_id
GROUP BY d.id, d.device_code, d.device_name, d.ip_address, 
         d.is_online, d.is_available, d.last_collection_time;

-- 创建今日产量统计视图
CREATE VIEW v_today_production_summary AS
SELECT 
    pr.device_id,
    d.device_code,
    d.device_name,
    pr.nc_program,
    pr.production_date,
    SUM(pr.quantity) as total_quantity,
    AVG(pr.quality_rate) as avg_quality_rate,
    COUNT(*) as record_count
FROM production_records pr
JOIN devices d ON pr.device_id = d.id
WHERE pr.production_date = CURDATE()
GROUP BY pr.device_id, d.device_code, d.device_name, pr.nc_program, pr.production_date;

-- 创建未解决告警视图
CREATE VIEW v_active_alarms AS
SELECT 
    a.id,
    a.alarm_type,
    a.alarm_level,
    a.alarm_content,
    a.device_id,
    d.device_name,
    a.occurrence_time,
    a.created_at
FROM alarms a
LEFT JOIN devices d ON a.device_id = d.id
WHERE a.is_resolved = 0
ORDER BY a.occurrence_time DESC;