스타트업에 현재 기존 개발자가 나간 상태, 1인 개발자 나 혼자 남은 상태에서 DB를 봤을 때 상태가 전혀 괜찮지 않았다. FK가 없으면 그것대신 트리거라도 있어야 하는데, 그야말로 그냥 테이블만 띡! 있는 관계형 데이터베이스의 의미가 존재하지 않는 상태인 것이다. 그래서 데이터베이스 리팩토링을 대표님에게 제안했고, 최소 6개월 최대 1년을 받아냈다. 기획과 설계에 약 6개월 이상을 잡고, 실제 설계를 3개월로 잡았으니 기간은 제법 넉넉하다. 현재 서비스가 초기 상태이기에 사용하는 테이블이 9개, 스키마가 100개 이내인 것을 생각해볼 때 지금이 바로잡기에 제일 좋은 시기임은 확실하니까 반드시 지금 해야한다는 생각이 가득했다. 또, 내 최종 목표인 DBA가 되기 위해서 엄청난 기회라고 생각한 것도 있다!(3년차에 혼자 재구축이라니 너무 재밌잖아!)
첫 단추에서 제일 문제가 된 건, 기존 테이블의 명세서가 하나도... 하나도 존재하지 않는다는 것이다.
오늘은 우선, 기존 테이블과 스키마를 전부 긁어와서 정리하는 것을 목표로 삼았다. DB는 굉장히 중요한 요소기에 조금 느리더라도 집중하고 천천히 하는 것이 옳다고 생각하는 바, 하루를 그것에 쏟는 것은 낭비가 아닐 것이다.
🐥 1. DB에서 쿼리를 통해 스키마와 테이블 조회하기
SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('information_schema', 'pg_catalog');
다음과 같은 쿼리를 실행하게 되면, 스키마와 스키마 내의 테이블을 조회하게 된다.
이것을 통해 나는 무슨 스키마에 어떤 테이블이 있는지 확인하고, 여기에서 테이블 네임을 가져오면 된다.
🐣 2. 테이블을 조회해서 그 안에 있는 컬럼 값을 가져오기
SELECT table_schema, table_name, column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema NOT IN ('information_schema', 'pg_catalog') and table_schema = 'test'
ORDER BY table_schema, table_name, ordinal_position;
위에서 가져온 테이블 네임을 쿼리 안의 'test' 부분에 넣으면, 해당하는 테이블 안에 있는 컬럼들의 목록이 나열된다. 나는 이것을 문서화할 것이기 때문에, csv 타입으로 데이터 추출만 하면 끝!
문서화의 경우는 개인의 취향에 따라 형식이 다르고, 회사의 내부 정보가 존재하기 때문에 정리하는 것을 보여줄 수는 없지만 다음 과정을 통해 추출된 데이터들을 가지고 하면 된다는 형식은 동일하다.
+ 나는 새로 데이터를 만드는 게 아니라, 기존에 있는 것을 리팩토링하는 것이기 때문에 트리거와 사용자 정의 함수도 정리를 해야 한다.
-- 트리거 목록 조회
SELECT trigger_name, event_manipulation, event_object_table, action_statement
FROM information_schema.triggers;
-- 사용자 정의 함수 조회
SELECT n.nspname AS schema_name,
p.proname AS function_name,
pg_catalog.pg_get_function_result(p.oid) AS return_type,
pg_catalog.pg_get_function_arguments(p.oid) AS arguments,
CASE
WHEN p.prokind = 'a' THEN 'agg'
WHEN p.prokind = 'w' THEN 'window'
WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger'
ELSE 'normal'
END AS type
FROM pg_catalog.pg_proc p
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND pg_catalog.pg_function_is_visible(p.oid)
ORDER BY 1, 2;
※ 테이블을 조회해서 컬럼 값을 가져올 때, view와 레퍼런스등의 하위테이블도 전부 가져온다. 이 점을 참고해서 작업하고, 트리거와 함수 또한 천천히 보면서 어느 테이블에 연결되어 있는지 점검할 필요가 있다. 우선은 테이블을 정리하는 것을 시작으로, 다음 편에는 트리거와 함수를 토대로 이어주는 작업을 하자