DB가 바뀌면 분석은 낡는다, 바뀐 테이블만 찾아 다시 분석한다

스키마 분석(「컬럼의 뜻은 DDL에 없다, 질문 전에 값을 읽어 둔다」)이 끝난 뒤 주문 테이블에 반품 여부 컬럼 RETURN_YN이 추가됐다고 해 봅시다. 테이블 카드에는 이 컬럼이 없으니, 모델은 「지난달 매출」을 물으면 반품을 빼지 않은 합계를 냅니다. SQL은 오류 없이 실행되고 숫자만 틀립니다. 반대로 DBA가 연결 계정에서 급여 테이블의 조회 권한을 회수했다면 SQL은 실패합니다. 이때 카드를 다시 확인하지 않으면 분석 때 저장한 샘플 행과 자주 나오는 값이 카드에 남아 모델이 읽게 됩니다.
분석 결과는 분석한 시점의 DB를 담고 있고, DB는 그 뒤에도 바뀝니다. 이 글은 바뀐 테이블을 찾아내는 두 가지 확인을 다룹니다. 테이블이 아직 있는지는 연결 계정이 지금 보는 테이블 목록과 대조하고, 사라진 테이블은 모델이 쓰는 도구에서 뺍니다. 컬럼과 코드 값이 바뀌었는지는 테이블마다 만든 스키마 지문(fingerprint)을 비교하고, 바뀐 테이블만 다시 분석합니다. 목록을 확인할 수 없을 때는 아무것도 바꾸지 않습니다.
낡은 카드는 실행되는 SQL로 틀린 답을 만든다
분석 뒤의 변화는 모델에게 세 가지로 나타납니다.
| 변화 | 모델이 하는 일 | 결과 |
|---|---|---|
| 컬럼이 추가되거나 타입이 바뀜 | 카드에 있는 컬럼만으로 SQL을 쓴다 | 실행은 되고 숫자가 틀린다. 카드에만 남은 컬럼을 쓰면 DB 오류가 난다 |
| 코드 테이블에 새 값이 들어옴 | 분석 때 만든 코드 풀이에 없는 값을 만난다 | 새 코드가 이름 없이 남거나 다른 이름을 얻는다 |
| 테이블이 지워지거나 권한이 회수됨 | 남은 카드를 보고 그 테이블로 SQL을 쓴다 | SQL은 실패하지만, 카드의 샘플 행과 값 분포는 답에 실릴 수 있다 |
이 가운데 코드 값은 분석 결과를 고치지 않아도 피해를 줄일 수 있습니다. 채팅은 코드 풀이를 힌트로만 쓰고 실제 값은 늘 코드 테이블을 조인해 읽습니다(「컬럼의 뜻은 DDL에 없다, 질문 전에 값을 읽어 둔다」). 테이블 검색 결과와 카드에는 마지막 분석 시각도 함께 실려서, 모델은 카드가 오래됐다는 것을 압니다. 하지만 모델은 카드에 없는 컬럼이 무엇인지 알 수 없고, 사라진 테이블의 카드를 읽지 말아야 한다는 것도 스스로 판단하지 못합니다. 이 두 경우는 바뀐 테이블을 찾아내야 합니다.
질문마다 카탈로그를 읽거나 주기적으로 전부 다시 분석하는 방법
가장 단순한 방법은 질문이 들어올 때마다 원천 DB의 카탈로그를 읽어 카드와 맞춰 보는 것입니다. 테이블과 컬럼 목록은 늘 최신이 됩니다. 그런데 카탈로그가 알려 주는 것은 이름과 타입뿐이고, 새 컬럼이 무슨 뜻인지는 분석을 다시 해야 압니다. 원천 DB는 질문마다 카탈로그 조회를 받습니다.
다른 방법은 정해진 주기로 테이블 전체를 다시 분석하는 것입니다. 뜻까지 최신이 되지만 분석 비용은 테이블 수에 비례하고(「컬럼의 뜻은 DDL에 없다, 질문 전에 값을 읽어 둔다」), 대부분의 테이블은 그사이 바뀌지 않았습니다. 테이블이 수천 개인 DB에서는 바뀌지 않은 테이블에 모델 비용을 쓰는 셈입니다.
그래서 바뀐 테이블을 찾는 일과 다시 분석하는 일을 나눴습니다. 찾는 일은 싼 조회로 자주 하고, 다시 분석하는 일은 찾아낸 테이블에만 합니다. 테이블이 사라진 경우와 모양이 바뀐 경우는 확인하는 방법도 달라서 따로 봅니다.
테이블이 있는지는 연결 계정이 보는 목록 하나로 판정한다
기준은 연결 계정이 지금 보는 테이블 목록입니다. 이 목록이 OwlAI가 지금 쓸 수 있는 테이블의 전부입니다. 원천에서 DROP 됐든 계정 권한에서 빠졌든, 목록에서 빠진 테이블은 똑같이 쓸 수 없는 테이블로 봅니다.
목록 대조는 다음 시점에 돕니다.
- 연결을 등록하거나 수정하거나 다시 켤 때
- 분석을 시작할 때
- 관리자가 데이터베이스 화면에 들어올 때
- 뒤에서 설명할 주기 점검이 돌 때
분석을 마친 테이블이 목록에서 사라지면 분석 결과를 지우지 않고 조회 불가로 표시합니다. 표시하는 즉시 그 테이블은 모델이 쓰는 세 도구, 곧 테이블 이름 목록·테이블 검색·테이블 카드 조회에서 모두 빠집니다. DB 요약도 조회 불가 테이블의 분석 결과를 재료로 쓰지 않습니다.
사라졌는지 판정하는 곳은 하나이고, 세 도구가 그 결과를 함께 씁니다. 도구마다 조건을 따로 두면 각 도구를 고치기는 편합니다. 하지만 한 도구가 조건을 빠뜨리면 그 도구로만 사라진 테이블의 카드가 나가고, 이런 누락은 오류도 로그도 없이 답에 섞입니다. 테이블 카드 조회는 테이블 이름을 직접 받으므로, 모델이 앞선 대화에서 본 이름을 그대로 넣어도 조회 불가 테이블이면 카드를 내주지 않습니다.
테이블이 다시 보이면 표시를 지웁니다. 분석 결과가 그대로 남아 있어서 다시 분석하지 않아도 바로 답에 쓰입니다. 계정 권한을 잠깐 바꿨다가 되돌린 경우에 분석을 처음부터 다시 하지 않아도 되는 것은 이 때문입니다. 분석 결과를 영구히 지우는 것은 관리자가 데이터베이스 화면에서 조회 불가 정리를 누를 때뿐이고, 이때 그 테이블의 테이블 메모도 함께 지워집니다. 급여 테이블처럼 다시 열 계획이 없는 테이블의 샘플 행은 이 버튼으로 지웁니다.
아직 분석하지 않은 테이블은 목록에서 사라지면 그냥 빠집니다. 지울 분석 결과가 없기 때문입니다. 새로 생긴 테이블은 다음 대조 때 미분석으로 나타나고, 분석하기 전까지 채팅은 그 테이블을 쓰지 않습니다.
목록을 확인하지 못하면 아무것도 바꾸지 않는다
이 판정에서 가장 조심한 경우는 목록을 확인하지 못했을 때입니다. 목록 조회가 실패하거나 빈 목록이 돌아오면 어떤 테이블도 조회 불가로 바꾸지 않고, 다음 대조를 기다립니다.
빈 목록을 「테이블이 전부 사라졌다」로 읽으면 그 DB의 모든 테이블이 한꺼번에 채팅에서 빠집니다. 원천 DB가 재시작되는 동안이나 네트워크가 잠깐 끊긴 사이에 대조가 돌면 이런 응답을 받을 수 있습니다. 분석된 테이블이 수백 개인데 목록이 0행이라면, DB 전체가 DROP 됐을 가능성보다 계정이나 스키마 설정이 어긋났을 가능성이 훨씬 큽니다. 일부 테이블만 사라진 목록은 정상 응답으로 보고 대조합니다.
이 규칙의 대가는 DB가 정말 통째로 사라졌을 때 표시가 늦어진다는 것입니다. 그동안 모델이 그 DB로 SQL을 쓰면 DB가 오류로 바로 알려 주므로, 틀린 숫자가 답으로 나가지는 않습니다.
컬럼과 코드 값이 바뀐 테이블은 스키마 지문으로 찾는다
테이블은 그대로인데 컬럼이 늘거나, 타입이 바뀌거나, 코드 테이블에 새 값이 들어온 경우는 목록 대조로 잡히지 않습니다. 이런 변화는 스키마 지문으로 찾습니다. 지문은 테이블마다 다음 재료를 정해진 순서로 정규화해 만든 해시입니다.
| 재료 | 얻는 방법 |
|---|---|
| 컬럼 이름과 순서 | 카탈로그 조회 |
| 컬럼 타입(길이·정밀도 포함) | 같은 카탈로그 조회 |
| 분석이 코드 컬럼으로 판정한 컬럼의 고유값 수와 자주 나오는 값 | 코드 컬럼에만 보내는 집계 쿼리 |
컬럼 이름과 타입은 카탈로그 조회 한 번으로 얻습니다. 값 분포는 코드 컬럼에만 집계 쿼리를 보냅니다. 모든 컬럼의 분포를 매번 다시 세면 더 많은 변화를 잡겠지만, 원천 DB가 받는 부하가 분석과 다르지 않게 됩니다. 해시와 함께 재료도 남겨서, 무엇이 바뀌었는지 설명할 수 있게 합니다.
테이블 분석이 끝나면 그 시점의 지문을 기준값으로 저장합니다. 워커는 DB 연결마다 관리자가 정한 주기로 현재 지문을 만들어 기준값과 비교합니다. 해시가 같으면 아무것도 하지 않습니다. 다르면 재료를 맞대어 「컬럼 1개 추가(RETURN_YN)」, 「STATUS_CODE 값 1개 추가」 같은 변경 요약을 만들고, 그 테이블을 스키마 변경으로 표시합니다. 변경 요약은 테이블 검색 결과와 카드에도 실립니다. 그래서 다시 분석하기 전이라도 모델은 카드에 없는 컬럼과 코드 풀이에 없는 값이 있다는 것을 압니다.
주기 점검은 목록 대조도 함께 합니다. 사라진 것이 확인된 테이블은 그 자리에서 조회 불가가 되어 도구에서 빠집니다. 카탈로그 조회가 실패하거나 빈 목록이 오면 지문도 비교하지 않고 상태도 바꾸지 않습니다.
다시 분석하는 것은 관리자가 고른 테이블뿐이다
스키마 변경 테이블은 데이터베이스 화면의 조치가 필요한 테이블 카드에 미분석·실패 테이블과 함께 잡힙니다. 관리자는 여기서 테이블을 골라 다시 분석합니다. 다시 분석하는 것은 지문이 바뀐 테이블뿐이라, 비용은 DB 크기가 아니라 바뀐 테이블 수를 따릅니다. 재분석이 끝나면 새 지문이 기준값이 되고 스키마 변경 표시가 풀립니다.
분석을 멈추려면 진행 패널의 분석 취소를 누릅니다. 아직 시작하지 않은 테이블은 이전 상태로 돌아가고, 이미 분석 중인 테이블은 끝까지 분석합니다. 분석 중인 테이블은 모델 호출을 이미 시작해서, 끊으면 그때까지 쓴 비용이 카드로 남지 않기 때문입니다. 그래서 취소를 누른 뒤에도 진행 중인 테이블을 마칠 때까지 분석 취소 중이 보입니다.
DB 요약은 따로 다시 만듭니다. 요약을 만든 뒤 테이블 분석이 새로 끝났거나, 초기화나 조회 불가 정리로 요약의 재료가 된 테이블 수가 바뀌면 요약에 DB 요약 낡음이 표시됩니다. 요약에도 모델 비용이 들기 때문에, 언제 다시 만들지는 이 표시를 보고 관리자가 정합니다.
설계에서 고른 것
다시 분석하는 일은 자동으로 돌리는 대신 관리자에게 맡겼습니다. 분석은 모델 비용이 들고 조직마다 한 번에 한 요청만 도는 작업입니다. 주기 점검이 바뀐 테이블을 알아서 분석 큐에 넣으면, 관리자가 지금 돌리려는 분석이 그 뒤로 밀립니다. 무엇이 바뀌었는지는 변경 요약이 이미 알려 주므로, 언제 얼마나 다시 분석할지는 요약을 본 관리자가 정합니다. 그사이 모델은 변경 요약이 붙은 예전 카드를 씁니다.
지문의 범위는 좁게 잡았습니다. 컬럼 이름·타입과 코드 컬럼의 값 분포만 봅니다. 그래서 타입은 그대로인데 쓰임이 바뀐 컬럼, 예를 들어 AMT에 어느 날부터 부가세를 포함한 금액이 들어가는 변화는 잡지 못합니다. 이런 변화는 업무 쪽에서 먼저 알게 되므로, 관리자가 그 테이블을 골라 다시 분석합니다.
점검 주기는 반영 속도와 원천 DB 부하를 맞바꾸는 값이라 관리자가 DB 연결마다 정합니다. 주기가 짧으면 변화가 빨리 표시되고, 길면 원천 DB에 나가는 카탈로그·집계 조회가 줄어듭니다. 점검 사이에 사라진 테이블로 SQL을 쓰면 DB가 오류로 알려 줍니다.
사라진 테이블의 분석 결과를 남겨 두는 대가로, 조회 불가 정리를 누르기 전까지 샘플 행과 테이블 메모가 OwlAI에 저장된 채로 남습니다. 모델이 그 내용을 읽을 수는 없지만, 권한을 회수한 이유가 데이터를 남기지 않는 것이라면 관리자가 정리까지 해야 합니다. 분석 뒤에도 스키마가 자주 바뀌는 업무 DB라면, 점검 주기를 배포 주기에 맞추고 배포 직후 조치가 필요한 테이블 카드를 확인하면 됩니다.
어떤 문제를 해결하나요?
정형 데이터와 NL2SQL의 다른 글

엔지니어링 노트 · 정형 데이터와 NL2SQL
테이블을 잘못 고른 SQL도 실행된다, 검색이 후보부터 좁힌다
테이블이 수천 개인 업무 DB에는 주문 테이블 옆에 ORDMSTBAK, ORDMST202312 같은 백업·작업용 사본이 흔히 함께 남아 있습니다.

엔지니어링 노트 · 정형 데이터와 NL2SQL
컬럼의 뜻은 DDL에 없다, 질문 전에 값을 읽어 둔다
주문 테이블의 STATUSCODE CHAR(1)에는 S, D, C가 들어 있습니다. 모델이 C를 완료(complete)로 짐작하면 「지난달 완료 주문 매출」에 취소 주문이 섞여 나옵니다.

엔지니어링 노트 · 정형 데이터와 NL2SQL
부서마다 다른 매출 계산식, 승인된 용어집 정의만 질문 앞에 싣는다
「지난달 매출」을 물으면 영업팀은 수주 금액을, 재무팀은 반품을 뺀 세금계산서 발행 금액을 떠올립니다.
