wing-ops/database/schema/04_accident_tables.sql
htlee 13d6ca69e2 refactor(db): DDL 스크립트 현행화 + wing_auth→auth 스키마 문서 전면 수정
- database/schema/ 14개 DDL 파일 신규 생성 (운영 DB pg_dump 기반)
- database/seed/ 14개 초기 데이터 파일 분리
- database/_deprecated/로 구 init.sql, auth_init.sql 이동
- database/README.md 신규 작성 (DB 아키텍처, 설치 절차)
- docs/ 6개 가이드 문서 wing_auth→auth 스키마 구조로 수정
- README.md, CLAUDE.md wing 단일 DB 구조 반영

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:16:38 +09:00

203 lines
7.8 KiB
SQL

-- WING-OPS Database Schema: Accident Tables
-- wing 스키마 사고 관련 테이블
-- ============================================================
-- 1. acdnt — 사고
-- ============================================================
CREATE TABLE wing.acdnt (
acdnt_sn integer NOT NULL,
acdnt_cd character varying(20) NOT NULL,
acdnt_nm character varying(200) NOT NULL,
acdnt_tp_cd character varying(50) NOT NULL,
acdnt_stts_cd character varying(20) DEFAULT 'ACTIVE'::character varying NOT NULL,
lat numeric(9,6),
lng numeric(10,6),
loc_dc character varying(200),
occrn_dtm timestamp with time zone NOT NULL,
rpt_dtm timestamp with time zone,
region_nm character varying(20),
office_nm character varying(30),
svrt_cd character varying(10),
vessel_tp character varying(30),
phase_cd character varying(20) DEFAULT 'RESPONSE'::character varying,
analyst_nm character varying(50),
rgtr_id uuid,
use_yn character(1) DEFAULT 'Y'::bpchar,
reg_dtm timestamp with time zone DEFAULT now() NOT NULL,
mdfcn_dtm timestamp with time zone,
loc_geom public.geometry(Point,4326),
CONSTRAINT pk_acdnt PRIMARY KEY (acdnt_sn),
CONSTRAINT uk_acdnt_cd UNIQUE (acdnt_cd),
CONSTRAINT ck_acdnt_stts CHECK (((acdnt_stts_cd)::text = ANY (ARRAY[('ACTIVE'::character varying)::text, ('INVESTIGATING'::character varying)::text, ('CLOSED'::character varying)::text]))),
CONSTRAINT ck_acdnt_svrt CHECK (((svrt_cd IS NULL) OR ((svrt_cd)::text = ANY (ARRAY[('DANGER'::character varying)::text, ('ALERT'::character varying)::text, ('CAUTION'::character varying)::text, ('INTEREST'::character varying)::text])))),
CONSTRAINT ck_acdnt_phase CHECK (((phase_cd IS NULL) OR ((phase_cd)::text = ANY (ARRAY[('RESPONSE'::character varying)::text, ('STANDBY'::character varying)::text, ('CLOSED'::character varying)::text]))))
);
CREATE SEQUENCE wing.acdnt_acdnt_sn_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE wing.acdnt_acdnt_sn_seq OWNED BY wing.acdnt.acdnt_sn;
ALTER TABLE ONLY wing.acdnt ALTER COLUMN acdnt_sn SET DEFAULT nextval('wing.acdnt_acdnt_sn_seq'::regclass);
-- ============================================================
-- 2. spil_data — 유출정보
-- ============================================================
CREATE TABLE wing.spil_data (
spil_data_sn integer NOT NULL,
acdnt_sn integer NOT NULL,
oil_tp_cd character varying(50) NOT NULL,
spil_qty numeric(12,2),
spil_unit_cd character varying(10) DEFAULT 'KL'::character varying,
spil_tp_cd character varying(20),
fcst_hr integer,
reg_dtm timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT pk_spil_data PRIMARY KEY (spil_data_sn)
);
CREATE SEQUENCE wing.spil_data_spil_data_sn_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE wing.spil_data_spil_data_sn_seq OWNED BY wing.spil_data.spil_data_sn;
ALTER TABLE ONLY wing.spil_data ALTER COLUMN spil_data_sn SET DEFAULT nextval('wing.spil_data_spil_data_sn_seq'::regclass);
-- ============================================================
-- 3. pred_exec — 예측실행
-- ============================================================
CREATE TABLE wing.pred_exec (
pred_exec_sn integer NOT NULL,
acdnt_sn integer NOT NULL,
algo_cd character varying(20) NOT NULL,
exec_stts_cd character varying(20) DEFAULT 'PENDING'::character varying NOT NULL,
bgng_dtm timestamp with time zone,
cmpl_dtm timestamp with time zone,
reqd_sec integer,
rslt_data jsonb,
err_msg text,
CONSTRAINT pk_pred_exec PRIMARY KEY (pred_exec_sn),
CONSTRAINT ck_pred_stts CHECK (((exec_stts_cd)::text = ANY (ARRAY[('PENDING'::character varying)::text, ('RUNNING'::character varying)::text, ('COMPLETED'::character varying)::text, ('FAILED'::character varying)::text])))
);
CREATE SEQUENCE wing.pred_exec_pred_exec_sn_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE wing.pred_exec_pred_exec_sn_seq OWNED BY wing.pred_exec.pred_exec_sn;
ALTER TABLE ONLY wing.pred_exec ALTER COLUMN pred_exec_sn SET DEFAULT nextval('wing.pred_exec_pred_exec_sn_seq'::regclass);
-- ============================================================
-- 4. acdnt_weather — 사고기상정보
-- ============================================================
CREATE TABLE wing.acdnt_weather (
weather_sn integer NOT NULL,
acdnt_sn integer NOT NULL,
loc_nm character varying(100),
obs_dtm timestamp with time zone,
icon character varying(10),
temp character varying(20),
weather_dc character varying(50),
wind character varying(30),
wave character varying(20),
humid character varying(20),
vis character varying(20),
sst character varying(20),
tide character varying(30),
high_tide character varying(30),
low_tide character varying(30),
forecast jsonb,
impact_dc text,
reg_dtm timestamp with time zone DEFAULT now(),
CONSTRAINT acdnt_weather_pkey PRIMARY KEY (weather_sn)
);
CREATE SEQUENCE wing.acdnt_weather_weather_sn_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE wing.acdnt_weather_weather_sn_seq OWNED BY wing.acdnt_weather.weather_sn;
ALTER TABLE ONLY wing.acdnt_weather ALTER COLUMN weather_sn SET DEFAULT nextval('wing.acdnt_weather_weather_sn_seq'::regclass);
-- ============================================================
-- 5. acdnt_media — 사고미디어
-- ============================================================
CREATE TABLE wing.acdnt_media (
media_sn integer NOT NULL,
acdnt_sn integer NOT NULL,
photo_cnt smallint DEFAULT 0,
video_cnt smallint DEFAULT 0,
sat_cnt smallint DEFAULT 0,
cctv_cnt smallint DEFAULT 0,
photo_meta jsonb,
drone_meta jsonb,
sat_meta jsonb,
cctv_meta jsonb,
reg_dtm timestamp with time zone DEFAULT now(),
CONSTRAINT acdnt_media_pkey PRIMARY KEY (media_sn)
);
CREATE SEQUENCE wing.acdnt_media_media_sn_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE wing.acdnt_media_media_sn_seq OWNED BY wing.acdnt_media.media_sn;
ALTER TABLE ONLY wing.acdnt_media ALTER COLUMN media_sn SET DEFAULT nextval('wing.acdnt_media_media_sn_seq'::regclass);
-- ============================================================
-- FK 제약조건
-- ============================================================
ALTER TABLE ONLY wing.spil_data
ADD CONSTRAINT fk_spil_acdnt FOREIGN KEY (acdnt_sn) REFERENCES wing.acdnt(acdnt_sn) ON DELETE CASCADE;
ALTER TABLE ONLY wing.pred_exec
ADD CONSTRAINT fk_pred_acdnt FOREIGN KEY (acdnt_sn) REFERENCES wing.acdnt(acdnt_sn) ON DELETE CASCADE;
ALTER TABLE ONLY wing.acdnt_weather
ADD CONSTRAINT acdnt_weather_acdnt_sn_fkey FOREIGN KEY (acdnt_sn) REFERENCES wing.acdnt(acdnt_sn) ON DELETE CASCADE;
ALTER TABLE ONLY wing.acdnt_media
ADD CONSTRAINT acdnt_media_acdnt_sn_fkey FOREIGN KEY (acdnt_sn) REFERENCES wing.acdnt(acdnt_sn) ON DELETE CASCADE;
-- ============================================================
-- 인덱스
-- ============================================================
-- 공간 인덱스
CREATE INDEX idx_acdnt_loc_geom ON wing.acdnt USING gist (loc_geom);
-- 상태/분류 인덱스
CREATE INDEX idx_acdnt_stts ON wing.acdnt USING btree (acdnt_stts_cd);
CREATE INDEX idx_acdnt_occrn ON wing.acdnt USING btree (occrn_dtm DESC);
CREATE INDEX idx_acdnt_region ON wing.acdnt USING btree (region_nm);
-- 외래키 인덱스
CREATE INDEX idx_spil_acdnt ON wing.spil_data USING btree (acdnt_sn);
CREATE INDEX idx_pred_acdnt ON wing.pred_exec USING btree (acdnt_sn);
CREATE INDEX idx_weather_acdnt ON wing.acdnt_weather USING btree (acdnt_sn);
CREATE INDEX idx_media_acdnt ON wing.acdnt_media USING btree (acdnt_sn);