diff --git a/backend/migrations/2026_01_29_141059_convert_order_items_to_hypertable.php b/backend/migrations/2026_01_29_141059_convert_order_items_to_hypertable.php new file mode 100644 index 0000000..ea86fac --- /dev/null +++ b/backend/migrations/2026_01_29_141059_convert_order_items_to_hypertable.php @@ -0,0 +1,96 @@ +statement('ALTER TABLE order_items DROP CONSTRAINT order_items_pkey'); + + // 2. 删除原有的唯一约束 + Schema::getConnection()->statement('ALTER TABLE order_items DROP CONSTRAINT order_items_order_sub_order_unique'); + Schema::getConnection()->statement('ALTER TABLE order_items DROP CONSTRAINT order_items_store_platform_sub_unique'); + + // 3. 创建新的复合主键(包含分区键) + Schema::getConnection()->statement('ALTER TABLE order_items ADD PRIMARY KEY (id, created_date)'); + + // 4. 转换为 hypertable(按年分区,与 orders 保持一致) + Schema::getConnection()->statement(" + SELECT create_hypertable('order_items', 'created_date', + chunk_time_interval => INTERVAL '1 year', + migrate_data => true + ) + "); + + // 5. 创建新的唯一约束(包含分区键) + Schema::getConnection()->statement(' + ALTER TABLE order_items ADD CONSTRAINT order_items_order_sub_order_unique + UNIQUE (order_id, sub_order_id, created_date) + '); + + Schema::getConnection()->statement(' + ALTER TABLE order_items ADD CONSTRAINT order_items_store_platform_sub_unique + UNIQUE (store_id, platform_order_id, sub_order_id, created_date) + '); + + // 6. 创建复合索引(支持按公司+时间查询) + Schema::getConnection()->statement(' + CREATE INDEX idx_order_items_company_created + ON order_items (company_id, created_date DESC) + '); + } + + /** + * Reverse the migrations. + * + * 警告:回滚 hypertable 会丢失分区结构,数据会保留但需要手动处理 + */ + public function down(): void + { + // 1. 创建临时表 + Schema::getConnection()->statement(' + CREATE TABLE order_items_temp AS SELECT * FROM order_items + '); + + // 2. 删除 hypertable + Schema::getConnection()->statement('DROP TABLE order_items'); + + // 3. 重命名临时表 + Schema::getConnection()->statement('ALTER TABLE order_items_temp RENAME TO order_items'); + + // 4. 重建原有约束 + Schema::getConnection()->statement('ALTER TABLE order_items ADD PRIMARY KEY (id)'); + Schema::getConnection()->statement(' + ALTER TABLE order_items ADD CONSTRAINT order_items_order_sub_order_unique + UNIQUE (order_id, sub_order_id) + '); + Schema::getConnection()->statement(' + ALTER TABLE order_items ADD CONSTRAINT order_items_store_platform_sub_unique + UNIQUE (store_id, platform_order_id, sub_order_id) + '); + + // 5. 重建序列(如果需要) + Schema::getConnection()->statement(" + SELECT setval('order_items_id_seq', (SELECT MAX(id) FROM order_items)) + "); + + // 6. 删除 created_date 索引(字段保留,可在下一个回滚中删除) + Schema::getConnection()->statement('DROP INDEX IF EXISTS idx_order_items_company_created'); + } +};