add orders hypertable convert
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
use Hyperf\Database\Schema\Schema;
|
||||
use Hyperf\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* 将 orders 表转换为 TimescaleDB hypertable
|
||||
*
|
||||
* 注意事项:
|
||||
* 1. Hypertable 要求主键和唯一约束必须包含分区键 (created_date)
|
||||
* 2. Hypertable 不支持被外键引用,需先删除 order_items 的外键
|
||||
* 3. 转换后数据完整性需在应用层保证
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// 1. 删除 order_items 表对 orders 的外键约束
|
||||
Schema::table('order_items', function ($table) {
|
||||
$table->dropForeign(['order_id']);
|
||||
});
|
||||
|
||||
// 2. 删除原有的主键约束
|
||||
Schema::getConnection()->statement('ALTER TABLE orders DROP CONSTRAINT orders_pkey');
|
||||
|
||||
// 3. 删除原有的唯一约束
|
||||
Schema::getConnection()->statement('ALTER TABLE orders DROP CONSTRAINT orders_store_platform_order_unique');
|
||||
|
||||
// 4. 创建新的复合主键(包含分区键)
|
||||
Schema::getConnection()->statement('ALTER TABLE orders ADD PRIMARY KEY (id, created_date)');
|
||||
|
||||
// 5. 转换为 hypertable(按年分区)
|
||||
Schema::getConnection()->statement("
|
||||
SELECT create_hypertable('orders', 'created_date',
|
||||
chunk_time_interval => INTERVAL '1 year',
|
||||
migrate_data => true
|
||||
)
|
||||
");
|
||||
|
||||
// 6. 创建新的唯一约束(包含分区键)
|
||||
Schema::getConnection()->statement('
|
||||
ALTER TABLE orders ADD CONSTRAINT orders_store_platform_order_unique
|
||||
UNIQUE (store_id, platform_order_id, created_date)
|
||||
');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* 警告:回滚 hypertable 会丢失分区结构,数据会保留但需要手动处理
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// 注意:TimescaleDB 不支持直接将 hypertable 转回普通表
|
||||
// 需要创建新表、迁移数据、删除 hypertable、重命名新表
|
||||
|
||||
// 1. 创建临时表
|
||||
Schema::getConnection()->statement('
|
||||
CREATE TABLE orders_temp AS SELECT * FROM orders
|
||||
');
|
||||
|
||||
// 2. 删除 hypertable
|
||||
Schema::getConnection()->statement('DROP TABLE orders');
|
||||
|
||||
// 3. 重命名临时表
|
||||
Schema::getConnection()->statement('ALTER TABLE orders_temp RENAME TO orders');
|
||||
|
||||
// 4. 重建原有约束
|
||||
Schema::getConnection()->statement('ALTER TABLE orders ADD PRIMARY KEY (id)');
|
||||
Schema::getConnection()->statement('
|
||||
ALTER TABLE orders ADD CONSTRAINT orders_store_platform_order_unique
|
||||
UNIQUE (store_id, platform_order_id)
|
||||
');
|
||||
|
||||
// 5. 重建外键
|
||||
Schema::table('order_items', function ($table) {
|
||||
$table->foreign('order_id')
|
||||
->references('id')
|
||||
->on('orders')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
|
||||
// 6. 重建序列(如果需要)
|
||||
Schema::getConnection()->statement("
|
||||
SELECT setval('orders_id_seq', (SELECT MAX(id) FROM orders))
|
||||
");
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user