115 lines
3.9 KiB
PL/PgSQL
115 lines
3.9 KiB
PL/PgSQL
-- 红绿灯IP地址增强功能数据库迁移脚本
|
||
-- 创建时间: 2025-01-06
|
||
-- 描述: 为traffic_lights表添加IP地址和端口字段,并修改device_id为可选字段
|
||
-- 版本: V1.1
|
||
|
||
-- 开始事务
|
||
BEGIN;
|
||
|
||
-- 1. 添加IP地址字段(必填,默认值为'0.0.0.0')
|
||
ALTER TABLE traffic_lights
|
||
ADD COLUMN IF NOT EXISTS ip_address VARCHAR(45) NOT NULL DEFAULT '0.0.0.0';
|
||
|
||
-- 2. 添加端口字段(可选)
|
||
ALTER TABLE traffic_lights
|
||
ADD COLUMN IF NOT EXISTS port INTEGER;
|
||
|
||
-- 3. 修改device_id字段为可选(移除NOT NULL约束)
|
||
-- 注意:PostgreSQL需要先检查是否存在NOT NULL约束
|
||
DO $$
|
||
BEGIN
|
||
-- 检查device_id字段是否有NOT NULL约束,如果有则移除
|
||
IF EXISTS (
|
||
SELECT 1
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'traffic_lights'
|
||
AND column_name = 'device_id'
|
||
AND is_nullable = 'NO'
|
||
) THEN
|
||
ALTER TABLE traffic_lights ALTER COLUMN device_id DROP NOT NULL;
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 4. 为现有记录设置默认值
|
||
-- 为现有记录设置默认IP地址和端口(如果字段为空)
|
||
-- 为了避免唯一约束冲突,为每个记录生成唯一的IP地址和端口组合
|
||
UPDATE traffic_lights
|
||
SET ip_address = '0.0.0.0'
|
||
WHERE ip_address IS NULL OR ip_address = '';
|
||
|
||
-- 为现有记录生成唯一的端口号,避免重复
|
||
-- 使用记录ID + 8082作为基础端口,确保每个记录都有唯一的端口
|
||
UPDATE traffic_lights
|
||
SET port = 8082 + (id % 1000) -- 使用ID的模运算确保端口在合理范围内
|
||
WHERE port IS NULL;
|
||
|
||
-- 5. 创建唯一约束:IP地址和端口组合必须唯一
|
||
-- 先检查是否已存在该索引
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1
|
||
FROM pg_indexes
|
||
WHERE tablename = 'traffic_lights'
|
||
AND indexname = 'idx_traffic_light_ip_port_unique'
|
||
) THEN
|
||
CREATE UNIQUE INDEX idx_traffic_light_ip_port_unique
|
||
ON traffic_lights(ip_address, port);
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 6. 创建IP地址索引(用于快速查询)
|
||
CREATE INDEX IF NOT EXISTS idx_traffic_light_ip_address
|
||
ON traffic_lights(ip_address);
|
||
|
||
-- 7. 添加字段注释
|
||
COMMENT ON COLUMN traffic_lights.ip_address IS '红绿灯设备IP地址';
|
||
COMMENT ON COLUMN traffic_lights.port IS '红绿灯设备端口号';
|
||
|
||
-- 8. 验证数据完整性
|
||
-- 检查是否有重复的IP地址和端口组合
|
||
DO $$
|
||
DECLARE
|
||
duplicate_count INTEGER;
|
||
BEGIN
|
||
SELECT COUNT(*) INTO duplicate_count
|
||
FROM (
|
||
SELECT ip_address, port, COUNT(*) as cnt
|
||
FROM traffic_lights
|
||
WHERE ip_address IS NOT NULL AND port IS NOT NULL
|
||
GROUP BY ip_address, port
|
||
HAVING COUNT(*) > 1
|
||
) duplicates;
|
||
|
||
IF duplicate_count > 0 THEN
|
||
RAISE WARNING '发现 % 个重复的IP地址和端口组合,请检查数据', duplicate_count;
|
||
ELSE
|
||
RAISE NOTICE '数据完整性检查通过,没有发现重复的IP地址和端口组合';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 9. 显示迁移结果
|
||
DO $$
|
||
DECLARE
|
||
total_records INTEGER;
|
||
records_with_ip INTEGER;
|
||
records_with_port INTEGER;
|
||
records_without_device_id INTEGER;
|
||
BEGIN
|
||
SELECT COUNT(*) INTO total_records FROM traffic_lights;
|
||
SELECT COUNT(*) INTO records_with_ip FROM traffic_lights WHERE ip_address IS NOT NULL AND ip_address != '';
|
||
SELECT COUNT(*) INTO records_with_port FROM traffic_lights WHERE port IS NOT NULL;
|
||
SELECT COUNT(*) INTO records_without_device_id FROM traffic_lights WHERE device_id IS NULL OR device_id = '';
|
||
|
||
RAISE NOTICE '=== 数据库迁移完成 ===';
|
||
RAISE NOTICE '总记录数: %', total_records;
|
||
RAISE NOTICE '有IP地址的记录数: %', records_with_ip;
|
||
RAISE NOTICE '有端口号的记录数: %', records_with_port;
|
||
RAISE NOTICE '没有设备ID的记录数: %', records_without_device_id;
|
||
END $$;
|
||
|
||
-- 提交事务
|
||
COMMIT;
|
||
|
||
-- 迁移完成提示
|
||
SELECT 'traffic_lights表IP地址增强迁移完成' AS migration_status; |