kcg-monitoring/database/migration/007_fleet_registry.sql
htlee bb99387168 feat: 선단 등록 DB + 어망/어구 정체성 추적 시스템
- DB 007: fleet_companies, fleet_vessels, gear_identity_log, fleet_tracking_snapshot
- 906척 선단 구성 데이터 적재 (497개 회사, 279쌍 PT)
- FleetTracker: 등록 선단 ↔ AIS 매칭(NAME_EXACT) + 어구 정체성 추적
- track_similarity.py: DTW 기반 궤적 유사도 (TRACK_SIMILAR 플래그)
- scheduler: fleet_tracker 통합 (기존 assign_fleet_roles 대체)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 18:07:15 +09:00

75 lines
2.6 KiB
SQL

-- 선단 등록 + 어망/어구 정체성 추적 시스템
-- 1. 소유자/회사
CREATE TABLE IF NOT EXISTS kcg.fleet_companies (
id SERIAL PRIMARY KEY,
name_cn TEXT NOT NULL,
name_en TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 2. 등록 선박 (906척 참고자료 기반)
CREATE TABLE IF NOT EXISTS kcg.fleet_vessels (
id SERIAL PRIMARY KEY,
company_id INT REFERENCES kcg.fleet_companies(id),
permit_no VARCHAR(20) NOT NULL,
name_cn TEXT NOT NULL,
name_en TEXT,
tonnage INT,
gear_code VARCHAR(10),
fleet_role VARCHAR(20),
pair_vessel_id INT REFERENCES kcg.fleet_vessels(id),
mmsi VARCHAR(15),
match_confidence REAL DEFAULT 0,
match_method VARCHAR(20),
last_seen_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_fleet_vessels_mmsi ON kcg.fleet_vessels(mmsi);
CREATE INDEX IF NOT EXISTS idx_fleet_vessels_name_en ON kcg.fleet_vessels(name_en);
CREATE INDEX IF NOT EXISTS idx_fleet_vessels_name_cn ON kcg.fleet_vessels(name_cn);
CREATE INDEX IF NOT EXISTS idx_fleet_vessels_company ON kcg.fleet_vessels(company_id);
-- 3. 어망/어구 정체성 이력
CREATE TABLE IF NOT EXISTS kcg.gear_identity_log (
id BIGSERIAL PRIMARY KEY,
mmsi VARCHAR(15) NOT NULL,
name TEXT NOT NULL,
parent_name TEXT,
parent_mmsi VARCHAR(15),
parent_vessel_id INT REFERENCES kcg.fleet_vessels(id),
gear_index_1 INT,
gear_index_2 INT,
lat DOUBLE PRECISION,
lon DOUBLE PRECISION,
match_method VARCHAR(30),
match_confidence REAL DEFAULT 0,
first_seen_at TIMESTAMPTZ NOT NULL,
last_seen_at TIMESTAMPTZ NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_gear_identity_mmsi ON kcg.gear_identity_log(mmsi);
CREATE INDEX IF NOT EXISTS idx_gear_identity_parent ON kcg.gear_identity_log(parent_mmsi);
CREATE INDEX IF NOT EXISTS idx_gear_identity_active ON kcg.gear_identity_log(is_active) WHERE is_active = TRUE;
-- 4. 선단 추적 스냅샷 (5분 주기)
CREATE TABLE IF NOT EXISTS kcg.fleet_tracking_snapshot (
id BIGSERIAL PRIMARY KEY,
company_id INT REFERENCES kcg.fleet_companies(id),
snapshot_time TIMESTAMPTZ NOT NULL,
total_vessels INT,
active_vessels INT,
in_zone_vessels INT,
operating_vessels INT,
gear_count INT,
fleet_status VARCHAR(20),
center_lat DOUBLE PRECISION,
center_lon DOUBLE PRECISION,
details JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_fleet_snapshot_time ON kcg.fleet_tracking_snapshot(snapshot_time DESC);
CREATE INDEX IF NOT EXISTS idx_fleet_snapshot_company ON kcg.fleet_tracking_snapshot(company_id);