USE model_operations; CREATE TABLE IF NOT EXISTS ops_monitor_batches ( batch_id CHAR(26) NOT NULL, workspace_id CHAR(26) NOT NULL COMMENT '逻辑引用 model_platform.workspaces', source_system VARCHAR(64) NOT NULL DEFAULT 'model_platform', source_batch_no VARCHAR(128) NOT NULL COMMENT '来源方幂等批次号', monitor_month DATE NOT NULL COMMENT '固定存当月1日', revision_no INT NOT NULL DEFAULT 1, supersedes_batch_id CHAR(26) NULL COMMENT '逻辑引用上一修订批次', batch_status VARCHAR(24) NOT NULL DEFAULT 'writing' COMMENT 'writing/published/failed/superseded', expected_model_count INT NOT NULL DEFAULT 0, written_model_count INT NOT NULL DEFAULT 0, feature_row_count BIGINT NOT NULL DEFAULT 0, distribution_row_count BIGINT NOT NULL DEFAULT 0, checksum_sha256 CHAR(64) NULL, generated_at DATETIME(3) NULL, published_at DATETIME(3) NULL, published_by CHAR(26) NULL COMMENT '逻辑引用 model_platform.users', failed_reason VARCHAR(2000) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), is_deleted TINYINT(1) NOT NULL DEFAULT 0, deleted_at DATETIME(3) NULL, PRIMARY KEY (batch_id), UNIQUE KEY uk_ops_monitor_batches_source_no ( workspace_id, source_system, source_batch_no ), UNIQUE KEY uk_ops_monitor_batches_revision ( workspace_id, source_system, monitor_month, revision_no ), KEY fk_ops_monitor_batches_supersedes (supersedes_batch_id), KEY idx_ops_monitor_batches_publish ( workspace_id, batch_status, monitor_month, revision_no ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='月度监控写入批次与发布门闩;模型平台可受控直写'; CREATE TABLE IF NOT EXISTS ops_monitor_results ( monitor_result_id CHAR(26) NOT NULL, workspace_id CHAR(26) NOT NULL COMMENT '逻辑引用 model_platform.workspaces', batch_id CHAR(26) NOT NULL COMMENT '逻辑引用 ops_monitor_batches', model_instance_id CHAR(26) NOT NULL COMMENT '逻辑引用 ops_model_instances', model_version_id CHAR(26) NOT NULL COMMENT '逻辑引用 ops_model_versions', monitor_month DATE NOT NULL COMMENT '固定存当月1日', source_result_ref VARCHAR(128) NULL, ranking_result VARCHAR(24) NULL COMMENT 'matched/unmatched/not_applicable', ks_value DECIMAL(12,8) NULL COMMENT '0-1比率', psi_value DECIMAL(12,8) NULL COMMENT '0-1比率', sample_count BIGINT NULL, good_count BIGINT NULL, bad_count BIGINT NULL, source_result_json JSON NULL COMMENT '尚未结构化的可追溯源字段', source_calculated_at DATETIME(3) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), is_deleted TINYINT(1) NOT NULL DEFAULT 0, deleted_at DATETIME(3) NULL, PRIMARY KEY (monitor_result_id), UNIQUE KEY uk_ops_monitor_results_batch_model ( batch_id, model_instance_id ), KEY fk_ops_monitor_results_batch (batch_id), KEY fk_ops_monitor_results_model (model_instance_id), KEY fk_ops_monitor_results_version (model_version_id), KEY idx_ops_monitor_results_month ( workspace_id, monitor_month, model_instance_id ), CONSTRAINT chk_ops_monitor_results_ks CHECK (ks_value IS NULL OR (ks_value >= 0 AND ks_value <= 1)), CONSTRAINT chk_ops_monitor_results_psi CHECK (psi_value IS NULL OR psi_value >= 0) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='单模型单月原始监控结果;发布后不可更新'; CREATE TABLE IF NOT EXISTS ops_monitor_feature_metrics ( feature_metric_id CHAR(26) NOT NULL, monitor_result_id CHAR(26) NOT NULL COMMENT '逻辑引用 ops_monitor_results', feature_code VARCHAR(128) NOT NULL, feature_name VARCHAR(200) NOT NULL, iv_value DECIMAL(12,8) NULL, previous_iv_value DECIMAL(12,8) NULL, iv_drop_rate DECIMAL(12,8) NULL COMMENT '0-1比率', csi_value DECIMAL(12,8) NULL, previous_csi_value DECIMAL(12,8) NULL, csi_rise_rate DECIMAL(12,8) NULL COMMENT '0-1比率', ks_contribution_change DECIMAL(12,8) NULL, psi_contribution_change DECIMAL(12,8) NULL, source_metric_json JSON NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), is_deleted TINYINT(1) NOT NULL DEFAULT 0, deleted_at DATETIME(3) NULL, PRIMARY KEY (feature_metric_id), UNIQUE KEY uk_ops_feature_metrics_result_feature ( monitor_result_id, feature_code ), KEY fk_ops_feature_metrics_result (monitor_result_id), KEY idx_ops_feature_metrics_iv_drop (monitor_result_id, iv_drop_rate), KEY idx_ops_feature_metrics_csi_rise (monitor_result_id, csi_rise_rate) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='单月特征级 IV/CSI 与贡献变化;发布后不可更新'; CREATE TABLE IF NOT EXISTS ops_monitor_distributions ( distribution_id CHAR(26) NOT NULL, monitor_result_id CHAR(26) NOT NULL COMMENT '逻辑引用 ops_monitor_results', dimension_type VARCHAR(24) NOT NULL COMMENT 'score_band/feature_bin', feature_code VARCHAR(128) NOT NULL DEFAULT '' COMMENT '评分分箱时为空串', feature_name VARCHAR(200) NULL, bin_order INT NOT NULL, bin_code VARCHAR(128) NOT NULL, bin_label VARCHAR(255) NOT NULL, reference_period_label VARCHAR(64) NULL, reference_count BIGINT NULL, reference_share DECIMAL(12,8) NULL COMMENT '0-1比率', current_count BIGINT NULL, current_share DECIMAL(12,8) NULL COMMENT '0-1比率', good_count BIGINT NULL, bad_count BIGINT NULL, bad_rate DECIMAL(12,8) NULL COMMENT '0-1比率', psi_component DECIMAL(12,8) NULL, csi_component DECIMAL(12,8) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), is_deleted TINYINT(1) NOT NULL DEFAULT 0, deleted_at DATETIME(3) NULL, PRIMARY KEY (distribution_id), UNIQUE KEY uk_ops_distributions_bin ( monitor_result_id, dimension_type, feature_code, bin_order ), KEY fk_ops_distributions_result (monitor_result_id), KEY idx_ops_distributions_feature ( monitor_result_id, feature_code, bin_order ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='排序性评分分箱及特征分布;发布后不可更新'; CREATE OR REPLACE VIEW v_ops_current_monitor_results AS SELECT result_row.* FROM ops_monitor_results AS result_row JOIN ops_monitor_batches AS batch_row ON batch_row.batch_id = result_row.batch_id JOIN ( SELECT workspace_id, source_system, monitor_month, MAX(revision_no) AS revision_no FROM ops_monitor_batches WHERE batch_status = 'published' AND is_deleted = 0 GROUP BY workspace_id, source_system, monitor_month ) AS latest ON latest.workspace_id = batch_row.workspace_id AND latest.source_system = batch_row.source_system AND latest.monitor_month = batch_row.monitor_month AND latest.revision_no = batch_row.revision_no WHERE result_row.is_deleted = 0 AND batch_row.batch_status = 'published' AND batch_row.is_deleted = 0;