-- 2026-09-23 近期字段与表结构统一增量(MySQL 8.0+) -- -- 范围:2026-09-21 至 2026-09-22 合入的结构变化。 -- 特性:显式切换到所属 schema;字段和索引均通过 information_schema 判断;可重复执行。 -- 边界:不创建数据库、不删除业务字段/表、不包含权限种子或业务数据修正。 -- 注意:DDL 在 MySQL 中会隐式提交;任一步失败后应停止执行并核对目标实例。 SET NAMES utf8mb4; -- ============================================================================ -- IAM:国内头程 PDA 操作员绑定作业仓 -- ============================================================================ USE baiyue_iam; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'iam_membership' ) AND NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_membership' AND column_name = 'domestic_warehouse_id' ), 'ALTER TABLE iam_membership ADD COLUMN domestic_warehouse_id BIGINT NULL COMMENT ''国内头程PDA操作员绑定的唯一国内作业仓ID'' AFTER overseas_warehouse_id', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @domestic_warehouse_index_columns = ( SELECT GROUP_CONCAT(column_name ORDER BY seq_in_index SEPARATOR ',') FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'iam_membership' AND index_name = 'idx_membership_domestic_warehouse' ); SET @domestic_warehouse_index_non_unique = ( SELECT MIN(non_unique) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'iam_membership' AND index_name = 'idx_membership_domestic_warehouse' ); SET @ddl = CASE WHEN NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_membership' AND column_name = 'domestic_warehouse_id' ) THEN 'SELECT 1' WHEN @domestic_warehouse_index_columns IS NULL THEN 'ALTER TABLE iam_membership ADD KEY idx_membership_domestic_warehouse (tenant_id, domestic_warehouse_id, status)' WHEN @domestic_warehouse_index_columns <> 'tenant_id,domestic_warehouse_id,status' OR @domestic_warehouse_index_non_unique <> 1 THEN 'ALTER TABLE iam_membership DROP INDEX idx_membership_domestic_warehouse, ADD KEY idx_membership_domestic_warehouse (tenant_id, domestic_warehouse_id, status)' ELSE 'SELECT 1' END; PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; -- ============================================================================ -- Firstleg:人工 FBA 报价允许缺少船司价格快照 -- ============================================================================ USE baiyue_firstleg; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_inbound_fee' AND column_name = 'carrier_rate_id' AND is_nullable = 'NO' ), 'ALTER TABLE fl_inbound_fee MODIFY COLUMN carrier_rate_id BIGINT UNSIGNED NULL COMMENT ''船司FBA价格ID;人工报价为空''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_inbound_fee' AND column_name = 'carrier_rate_version' AND is_nullable = 'NO' ), 'ALTER TABLE fl_inbound_fee MODIFY COLUMN carrier_rate_version INT UNSIGNED NULL COMMENT ''船司价格版本快照;人工报价为空''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_inbound_fee' AND column_name = 'rate_effective_from' AND is_nullable = 'NO' ), 'ALTER TABLE fl_inbound_fee MODIFY COLUMN rate_effective_from DATETIME(3) NULL COMMENT ''价格生效开始快照;人工报价为空''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; -- ============================================================================ -- Firstleg:墨家测量收件箱扩展为箱唛/SKU 双分流 -- ============================================================================ SET @ddl = IF( NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'measurement_kind' ), 'ALTER TABLE fl_mojia_measurement_receipt ADD COLUMN measurement_kind VARCHAR(16) NOT NULL DEFAULT ''BOX_LABEL'' COMMENT ''测量分流:BOX_LABEL箱唛;SKU一件代发SKU'' AFTER box_code', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'weight_kg' ), 'ALTER TABLE fl_mojia_measurement_receipt ADD COLUMN weight_kg DECIMAL(18,3) NOT NULL DEFAULT 0 COMMENT ''设备实测重量kg'' AFTER height_cm', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'weight_kg' AND (column_type <> 'decimal(18,3)' OR is_nullable <> 'NO' OR column_default IS NOT NULL OR column_comment <> '设备实测重量kg') ), 'ALTER TABLE fl_mojia_measurement_receipt MODIFY COLUMN weight_kg DECIMAL(18,3) NOT NULL COMMENT ''设备实测重量kg''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'sync_status' ), 'ALTER TABLE fl_mojia_measurement_receipt ADD COLUMN sync_status VARCHAR(24) NULL COMMENT ''SKU同步状态:PENDING/SYNCING/SUCCESS/FAILED'' AFTER status', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'sync_failure_code' ), 'ALTER TABLE fl_mojia_measurement_receipt ADD COLUMN sync_failure_code VARCHAR(64) NULL COMMENT ''SKU同步失败业务码'' AFTER sync_status', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'sync_failure_reason' ), 'ALTER TABLE fl_mojia_measurement_receipt ADD COLUMN sync_failure_reason VARCHAR(500) NULL COMMENT ''脱敏后的SKU同步失败原因'' AFTER sync_failure_code', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'lingxing_sku_id' ), 'ALTER TABLE fl_mojia_measurement_receipt ADD COLUMN lingxing_sku_id VARCHAR(128) NULL COMMENT ''领星SKU内部标识'' AFTER sync_failure_reason', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'revision' ), 'ALTER TABLE fl_mojia_measurement_receipt ADD COLUMN revision INT NOT NULL DEFAULT 1 COMMENT ''当前测量版本号'' AFTER lingxing_sku_id', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'match_failure_code' AND is_nullable = 'NO' ), 'ALTER TABLE fl_mojia_measurement_receipt MODIFY COLUMN match_failure_code VARCHAR(16) NULL COMMENT ''正式箱唛业务匹配失败码''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'match_failure_reason' AND is_nullable = 'NO' ), 'ALTER TABLE fl_mojia_measurement_receipt MODIFY COLUMN match_failure_reason VARCHAR(500) NULL COMMENT ''脱敏后的箱唛匹配失败原因''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'box_code' AND column_comment <> '设备扫描的原始箱码或不带#的SKU' ), 'ALTER TABLE fl_mojia_measurement_receipt MODIFY COLUMN box_code VARCHAR(128) NOT NULL COMMENT ''设备扫描的原始箱码或不带#的SKU''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'fl_mojia_measurement_receipt' AND column_name = 'status' AND column_comment <> '原始收件状态;SKU记录使用SKU_PENDING_SYNC' ), 'ALTER TABLE fl_mojia_measurement_receipt MODIFY COLUMN status VARCHAR(24) NOT NULL DEFAULT ''UNMATCHED'' COMMENT ''原始收件状态;SKU记录使用SKU_PENDING_SYNC''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; -- ============================================================================ -- Lastleg:同一尾程单允许多次换标申请,订单关联由唯一索引改为普通索引 -- ============================================================================ USE baiyue_lastleg; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'll_relabel_application' AND index_name = 'uk_ll_relabel_application_order' ), 'ALTER TABLE ll_relabel_application DROP INDEX uk_ll_relabel_application_order', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @relabel_order_index_columns = ( SELECT GROUP_CONCAT(column_name ORDER BY seq_in_index SEPARATOR ',') FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'll_relabel_application' AND index_name = 'idx_ll_relabel_application_order' ); SET @relabel_order_index_non_unique = ( SELECT MIN(non_unique) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'll_relabel_application' AND index_name = 'idx_ll_relabel_application_order' ); SET @ddl = CASE WHEN @relabel_order_index_columns IS NULL THEN 'ALTER TABLE ll_relabel_application ADD KEY idx_ll_relabel_application_order (lastleg_order_id)' WHEN @relabel_order_index_columns <> 'lastleg_order_id' OR @relabel_order_index_non_unique <> 1 THEN 'ALTER TABLE ll_relabel_application DROP INDEX idx_ll_relabel_application_order, ADD KEY idx_ll_relabel_application_order (lastleg_order_id)' ELSE 'SELECT 1' END; PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; -- ============================================================================ -- Overseas Warehouse:A0 系统共享溢出库位标记 -- 注意:正式 schema 名沿用项目现有拼写 baiyue_lastlag_warehouse。 -- ============================================================================ USE baiyue_lastlag_warehouse; SET @ddl = IF( NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'wh_location' AND column_name = 'shared_overflow' ), 'ALTER TABLE wh_location ADD COLUMN shared_overflow TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否系统共享溢出库位(A0)'' AFTER location_type', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; SET @ddl = IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'wh_location' AND column_name = 'shared_overflow' AND (column_type <> 'tinyint(1)' OR is_nullable <> 'NO' OR COALESCE(column_default, '') <> '0' OR column_comment <> '是否系统共享溢出库位(A0)') ), 'ALTER TABLE wh_location MODIFY COLUMN shared_overflow TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否系统共享溢出库位(A0)''', 'SELECT 1' ); PREPARE recent_schema_stmt FROM @ddl; EXECUTE recent_schema_stmt; DEALLOCATE PREPARE recent_schema_stmt; -- 最终只读核对;四行均应返回 READY。 SELECT 'baiyue_iam' AS target_schema, IF( EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'baiyue_iam' AND table_name = 'iam_membership' AND column_name = 'domestic_warehouse_id') AND (SELECT GROUP_CONCAT(column_name ORDER BY seq_in_index SEPARATOR ',') FROM information_schema.statistics WHERE table_schema = 'baiyue_iam' AND table_name = 'iam_membership' AND index_name = 'idx_membership_domestic_warehouse') = 'tenant_id,domestic_warehouse_id,status', 'READY', 'CHECK_REQUIRED' ) AS schema_status UNION ALL SELECT 'baiyue_firstleg', IF( (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_mojia_measurement_receipt' AND column_name IN ('measurement_kind','weight_kg','sync_status','sync_failure_code','sync_failure_reason','lingxing_sku_id','revision')) = 7 AND (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_inbound_fee' AND column_name IN ('carrier_rate_id','carrier_rate_version','rate_effective_from') AND is_nullable = 'YES') = 3, 'READY', 'CHECK_REQUIRED' ) UNION ALL SELECT 'baiyue_lastleg', IF( NOT EXISTS (SELECT 1 FROM information_schema.statistics WHERE table_schema = 'baiyue_lastleg' AND table_name = 'll_relabel_application' AND index_name = 'uk_ll_relabel_application_order') AND (SELECT GROUP_CONCAT(column_name ORDER BY seq_in_index SEPARATOR ',') FROM information_schema.statistics WHERE table_schema = 'baiyue_lastleg' AND table_name = 'll_relabel_application' AND index_name = 'idx_ll_relabel_application_order') = 'lastleg_order_id' AND (SELECT MIN(non_unique) FROM information_schema.statistics WHERE table_schema = 'baiyue_lastleg' AND table_name = 'll_relabel_application' AND index_name = 'idx_ll_relabel_application_order') = 1, 'READY', 'CHECK_REQUIRED' ) UNION ALL SELECT 'baiyue_lastlag_warehouse', IF( EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'baiyue_lastlag_warehouse' AND table_name = 'wh_location' AND column_name = 'shared_overflow' AND column_type = 'tinyint(1)' AND is_nullable = 'NO' AND COALESCE(column_default, '') = '0' ), 'READY', 'CHECK_REQUIRED' );