infra
Platform

모듈 맵

[Database] DBeaver, TablePlus, psql, mycli 실무 100% 활용법

0 / 37 완료

펼치기
0 / 37 완료0%

데이터베이스 설계 & 튜닝 · 11 / 37

[Database] DBeaver, TablePlus, psql, mycli 실무 100% 활용법

실무에서 데이터베이스에 접속하고 관리하는 주요 도구들을 익힙니다

🚨INCIDENT ALERT
HIGH

DB 문제를 해결할 때 GUI만 열어서는 원인을 끝까지 추적하기 어렵습니다. psql, mysql client, DBeaver, migration 도구가 각각 잘하는 일이 다릅니다. 도구의 역할을 구분하면 운영 상황에서도 당황하지 않고 필요한 정보를 바로 확인할 수 있습니다.

이번 챕터에서 배울 것

좋은 도구를 선택하고 능숙하게 사용하면 DB 작업 효율이 크게 높아집니다. GUI와 CLI 각각의 강점을 파악하고 상황에 맞게 선택하는 방법을 배웁니다.

  • 1DBeaver, TablePlus, DataGrip을 비교하고 상황에 맞는 GUI 클라이언트를 선택할 수 있다
  • 2연결 문자열의 구조를 이해하고 직접 작성할 수 있다
  • 3psql 핵심 메타 커맨드를 활용해 DB를 탐색할 수 있다
  • 4mycli와 pgcli 같은 CLI 도구를 사용해 효율적으로 작업할 수 있다

실무 DB 도구 — DBeaver, TablePlus, psql, mycli

데이터베이스를 배웠다면 이제 실제로 접속하고 쿼리를 실행해야 합니다. GUI 도구를 쓸지, CLI를 쓸지는 상황과 취향에 따라 다르지만, 실무에서는 두 가지 모두 사용할 줄 알아야 합니다. GUI는 스키마 탐색과 데이터 확인에 편리하고, CLI는 서버 직접 접속과 스크립트 자동화에 필수적입니다.


💡개념

GUI vs CLI 도구 선택 — 상황별 최적 도구

운영 서버에 SSH로 접속해서 DB 쿼리를 실행해야 합니다. GUI 도구는 로컬에서만 쓸 수 있고, CLI 도구는 명령어가 생소합니다. 반대로 개발할 때는 테이블 구조를 눈으로 보면서 쿼리를 짜는 게 훨씬 편합니다. 상황별로 어떤 도구를 쓰는지 알면 매번 검색하는 시간이 줄어듭니다.

GUI vs CLI 도구 선택 — 상황별 최적 도구확대

주요 도구 비교

GUI 도구는 스키마 탐색, ERD 확인, 대화형 쿼리 작성에 강합니다. CLI 도구는 서버 SSH 환경, 스크립트 자동화, 빠른 점검 루틴에 강합니다. 실무에서는 평소에는 GUI를 쓰고, 프로덕션 서버 긴급 대응 시에는 CLI를 씁니다.

항목DBeaverTablePlusDataGrippsql/pgcli
가격무료유료 (~$69)유료 (~$8.9/월)무료
OS 지원모든 OSmacOS/iOS모든 OS모든 OS
DB 지원 수100+20+20+PostgreSQL 전용
성능/속도보통빠름보통빠름
SQL 자동완성좋음좋음최고pgcli 사용 시 좋음
서버 환경 사용불가불가불가필수
추천 상황다양한 DB, 무료 필요macOS 네이티브JetBrains 생태계서버 직접 접속, 자동화

DBeaver — 최고의 무료 선택

DBeaver는 가장 많이 사용되는 무료 데이터베이스 GUI 클라이언트입니다. Java 기반으로 Windows, macOS, Linux 모두 동일한 경험을 제공하며 ERD 자동 생성, 데이터 내보내기/가져오기, SQL 편집기 자동완성을 지원합니다. 단점은 Java 기반이라 무겁고 시작이 느리며, macOS에서 네이티브 앱 대비 UI가 다소 어색하다는 점입니다.

TablePlus — macOS 최적화

네이티브 macOS 앱으로 빠른 시작과 반응성, 깔끔한 UI, 탭 방식의 다중 연결 관리를 제공합니다. macOS를 주력으로 사용하고 빠른 UI를 원할 때 선택합니다.

DataGrip — 개발자 최강 도구

JetBrains에서 만든 유료 DB 전용 IDE입니다. 가장 강력한 SQL 자동완성과 리팩터링, JetBrains IDE와의 완벽 통합, 스키마 비교와 데이터 마이그레이션을 지원합니다. IntelliJ 계열 IDE를 사용하며 DB 작업이 많을 때 선택합니다. 학생과 오픈소스 프로젝트는 무료입니다.

연결 문자열(Connection String) 이해

어떤 도구를 사용하든 DB 연결에는 동일한 정보가 필요합니다. 연결 문자열은 호스트, 포트, 데이터베이스 이름, 사용자명, 비밀번호, 선택적 파라미터(SSL 모드, 타임아웃 등)를 하나의 URL로 표현합니다.

postgresql://username:password@host:port/dbname
postgresql://postgres:secret123@localhost:5432/shop_db
postgresql://postgres:secret123@localhost:5432/shop_db?sslmode=require&connect_timeout=10

비밀번호는 절대 코드에 직접 쓰지 않습니다. .env 파일이나 환경변수로 관리하고 .gitignore에 반드시 추가해야 합니다.

항목설명예시
hostDB 서버 주소localhost, 192.168.1.1
port포트 번호PostgreSQL: 5432, MySQL: 3306
dbname데이터베이스 이름shop_db, production
usernameDB 사용자postgres, admin
password비밀번호(환경변수로 관리)
💡개념

psql 핵심 사용법 — CLI에서 DB 다루기

운영 서버에 접속해서 PostgreSQL을 확인해야 합니다. GUI 도구를 설치할 수 없는 환경입니다. psql만 있는데, \l, \dt, \d tablename이 무엇을 뜻하는지 모릅니다. psql 메타 명령어를 익혀두면 어떤 서버에서도 DB 상태를 즉시 확인할 수 있습니다.

psql 핵심 사용법 — CLI에서 DB 다루기확대

psql 시작하기

psql은 PostgreSQL 공식 CLI 클라이언트입니다. GUI 도구가 없는 서버 환경이나 스크립트 자동화에 필수적입니다. 환경변수(PGHOST, PGPORT, PGUSER, PGDATABASE)를 미리 설정해두면 매번 플래그를 입력하지 않아도 됩니다.

DB 클라이언트
psql -h localhost -p 5432 -U postgres -d mydb
psql "postgresql://postgres:password@localhost:5432/mydb"
OUTPUT
실행 완료 또는 조회 결과가 표시됩니다.
🔍실행 후 확인할 것
  • psql 접속 후 프롬프트 먼저 확인: 프롬프트가 mydb=#이면 슈퍼유저, mydb=>이면 일반 사용자입니다. 프롬프트에 표시된 DB 이름이 접속 의도한 DB와 일치하는지 반드시 확인하세요. prod_db인데 dev_db에 접속했다면 잘못된 환경에서 작업하는 것입니다.
  • \dt 결과가 비어 있으면: 현재 search_path 스키마에 테이블이 없는 것입니다. \dt *.*로 전체 스키마 테이블을 확인하거나, \dn으로 스키마 목록을 먼저 파악하세요. 마이그레이션이 다른 스키마에 적용됐을 가능성이 있습니다.
  • \d users 실행 후 확인: 컬럼 목록, 타입, NOT NULL 여부, DEFAULT 값, 인덱스 정보가 모두 표시됩니다. Indexes 섹션에서 idx_users_email이 없으면 이메일 검색이 Full Table Scan으로 실행됩니다. 100만 건 이상 테이블이라면 즉시 인덱스 생성을 검토하세요.
  • \timing 활성화 후 실행 시간 판단: SELECT 쿼리가 100ms 이하면 정상, 1,000ms(1초) 이상이면 인덱스 누락 또는 대용량 조인 문제입니다. 느린 쿼리는 EXPLAIN ANALYZE를 붙여 Seq Scan 여부를 확인하세요. Seq Scan + 수백만 rows는 인덱스 추가가 필요한 명확한 신호입니다.

필수 메타 커맨드 (백슬래시 명령어)

psql의 메타 커맨드는 \로 시작하며 SQL이 아닌 psql 자체 명령입니다. 세미콜론 없이 Enter만 치면 바로 실행됩니다.

\l              데이터베이스 목록 전체
\c mydb         mydb로 연결 전환
\dt             현재 DB의 테이블 목록
\dt public.*    public 스키마 전체 테이블
\d tablename    테이블 컬럼 구조와 인덱스 상세 보기
\di             인덱스 목록
\dv             뷰 목록
\df             함수 목록
\du             사용자(Role) 목록
\dn             스키마 목록
\timing         쿼리 실행 시간 측정 ON/OFF
\e              외부 에디터(vim/nano)에서 쿼리 편집
\i filename.sql SQL 파일 실행
\o output.txt   결과를 파일로 저장
\q              psql 종료
\?              전체 메타 커맨드 도움말
\h SELECT       SELECT 문법 도움말

\d tablename은 컬럼 타입, NOT NULL 여부, 기본값, 인덱스 정보를 한 번에 보여줍니다. 테이블 구조를 빠르게 확인할 때 가장 많이 쓰는 명령입니다.

COPY 명령으로 대용량 데이터 처리

\COPY는 클라이언트 파일시스템을 사용하므로 로컬 파일 작업에 항상 \COPY를 사용합니다. COPY(백슬래시 없음)는 DB 서버 파일시스템 경로를 사용해 로컬 환경에서 동작하지 않을 수 있습니다.

SQL
\COPY orders TO '/tmp/orders_backup.csv' WITH CSV HEADER;

\COPY products FROM '/tmp/products.csv' WITH CSV HEADER;

\COPY (SELECT id, email, created_at FROM users WHERE active = true)
TO '/tmp/active_users.csv' WITH CSV HEADER;

.psqlrc — psql 환경 설정

홈 디렉토리의 .psqlrc 파일로 psql 기본 설정을 커스터마이징할 수 있습니다. 아래 설정을 적용하면 psql을 열 때마다 실행 시간 측정이 켜지고 NULL 값이 [NULL]로 시각적으로 표시됩니다.

\set PROMPT1 '%[%033[1;32m%]%n@%/%[%033[0m%]# '
\timing on
\pset null '[NULL]'
\pset pager always

pgcli와 mycli — 자동완성 강화 CLI

표준 psql/mysql보다 편리한 대안 도구입니다. 테이블명, 컬럼명, SQL 키워드 자동완성, 문법 컬러 강조, Ctrl+R 히스토리 검색을 지원합니다. 서버에 GUI를 설치할 수 없는 환경에서 DB 작업이 잦다면 pgcli를 강력 추천합니다.

로컬 터미널
pip install pgcli
pgcli postgresql://postgres:password@localhost/mydb

pip install mycli
mycli -u root -h localhost mydb

psql에서 BEGIN으로 트랜잭션을 시작한 뒤 쿼리를 입력하다가 Ctrl+C를 누르면 psql이 현재 입력을 취소하는 것이 아니라 세션 자체를 인터럽트합니다. 이때 열려 있던 트랜잭션이 롤백됩니다. 의도한 변경 사항이 저장되지 않고 사라집니다.

psql을 종료하려면 반드시 \q를 사용합니다. 입력 중인 줄을 취소하려면 Ctrl+C 대신 \r(reset)을 입력하거나, 빈 줄에서 Ctrl+C를 누릅니다. 트랜잭션 내에서 실수한 경우에는 ROLLBACK을 명시적으로 입력해 안전하게 취소하고, 정상 종료 시에는 COMMIT\q를 순서대로 실행합니다.

💼
실무 맥락프로덕션 DB 서버에 읽기 전용 계정으로 접속해 슬로우 쿼리 원인을 파악해야 하는 상황
현업 패턴

프로덕션 서버에서 특정 API가 갑자기 느려졌을 때, DBA나 SRE는 먼저 psql로 읽기 전용 계정을 통해 프로덕션 DB에 직접 접속합니다. GUI 도구는 SSH 터널 설정이 복잡하지만 psql은 psql "postgresql://readonly:pass@prod-db:5432/mydb?sslmode=require" 한 줄로 바로 접속됩니다.

접속 후 \timing을 켜고 의심되는 쿼리를 직접 실행해 시간을 확인합니다. 느리면 EXPLAIN ANALYZE로 실행 계획을 확인해 Seq Scan 여부를 판단합니다. pg_stat_activity로 현재 실행 중인 쿼리와 대기 중인 쿼리를 조회해 잠금 경합 여부도 확인합니다. 이 루틴은 읽기 전용이므로 프로덕션에 영향을 주지 않고 안전하게 진단할 수 있습니다.

심화 — GUI 도구가 조용히 열어 둔 트랜잭션

💡개념

심화: idle in transaction 한 세션이 VACUUM을 멈춰 세운다

앞에서 psql의 Ctrl+C가 트랜잭션을 롤백하는 함정을 봤습니다. 도구가 만드는 더 은밀한 사고는 반대쪽에 있습니다 — 트랜잭션을 열어 둔 채 방치하는 것입니다. DBeaver 같은 GUI는 기본이 수동 커밋인 경우가 많아, 조회 한 번에도 트랜잭션이 열리고 결과창을 닫기 전까지 닫히지 않습니다.

  • 오래된 트랜잭션은 스냅샷을 붙잡습니다: PostgreSQL은 MVCC로 각 트랜잭션에 특정 시점의 스냅샷을 줍니다. 트랜잭션이 살아 있는 한 그 시점 이후의 죽은 행(dead tuple)을 아무도 못 지웁니다 — 그 트랜잭션이 아직 옛 버전을 볼 권리가 있기 때문입니다. 이 하한선을 xmin horizon이라 부릅니다.
  • 그래서 VACUUM이 헛돌게 됩니다: 점심 먹으러 가며 열어 둔 idle in transaction 세션 하나가 몇 시간을 버티면, 그동안 DB 전체에서 삭제·수정으로 생긴 dead tuple을 VACUUM이 회수하지 못합니다. 테이블과 인덱스가 부풀고(bloat) 같은 쿼리가 점점 느려집니다. 원인은 도구 창 하나인데 증상은 DB 전체 성능 저하로 나타납니다.
  • 잠금까지 물고 있을 수 있습니다: 그 트랜잭션이 UPDATE를 한 상태였다면 행 잠금을, 스키마를 건드렸다면 더 강한 잠금을 계속 쥡니다. 마침 그때 배포된 마이그레이션(ALTER)이 뒤에서 대기하며 연쇄 지연을 만들 수 있습니다.
  • 안전장치는 자동 커밋과 타임아웃입니다: 운영 DB를 만지는 도구는 읽기 조회에 트랜잭션을 굳이 열지 않도록 autocommit을 켭니다. 서버에는 idle_in_transaction_session_timeout을 걸어, 일정 시간 방치된 트랜잭션을 DB가 스스로 끊게 합니다. 편한 GUI일수록 이 설정이 없으면 위험합니다.

핵심은, 도구가 편하다고 트랜잭션 경계까지 대신 관리해 주지는 않는다는 점입니다. 조회만 했는데 왜 DB가 느려지지의 범인은 종종 내가 열어 둔 결과창입니다(트랜잭션 격리 수준(Isolation Level)과 이상 현상 제어).

상황: 쓰기량은 평소와 비슷한데 한 테이블의 물리 크기가 계속 늘고, 같은 SELECT의 응답이 눈에 띄게 느려집니다. pg_stat_user_tables를 보면 n_dead_tup이 높은데 autovacuum이 돌아도 회수가 안 됩니다.

원인: 누군가 GUI 도구로 프로덕션을 조회한 뒤 결과창을 열어 둔 채 자리를 비웠고, 그 세션이 idle in transaction 상태로 몇 시간째 살아 있었습니다. 이 오래된 트랜잭션이 xmin horizon을 과거에 묶어, VACUUM이 그 시점 이후의 dead tuple을 회수하지 못한 것입니다. 도구의 수동 커밋 설정이 근본 원인이었습니다.

진단: pg_stat_activity에서 state가 idle in transaction이고 xact_start가 오래된 세션을 찾습니다. 그 backend의 접속 애플리케이션·사용자를 보면 대개 GUI 클라이언트입니다. 그 세션의 xact_start와 테이블 bloat 증가 시점이 겹치면 확정입니다.

해결: 급하면 해당 세션을 안전하게 종료(pg_terminate_backend)해 xmin horizon을 풀어 주고 VACUUM이 회수하도록 합니다. 재발 방지로 서버에 idle_in_transaction_session_timeout을 설정하고, 도구의 autocommit을 켜 읽기 조회가 트랜잭션을 열지 않게 합니다. 운영 DB 접속 규칙에 결과창 방치 금지와 읽기 전용 계정 사용을 넣습니다(실시간 DB 모니터링 및 슬로우 쿼리 슬랙 알림 설정).


명령어·구문 빠른 참조

이 모듈에서 다룬 psql 메타명령과 CLI 클라이언트 명령을 실전 옵션과 함께 모았습니다.

구문/명령용도
psql "postgresql://..."연결 문자열 한 줄로 접속psql "postgresql://readonly:pass@prod-db:5432/mydb?sslmode=require"
\l / \cDB 목록 / 다른 DB로 연결 전환\l\c shop_db
\dt현재 DB 테이블 목록\dt public.* (스키마 전체)
\d 테이블컬럼·타입·인덱스·제약 구조 보기\d users
\di \dv \df \du \dn인덱스·뷰·함수·롤·스키마 목록\di(인덱스), \du(Role), \dn(스키마)
\timing쿼리 실행 시간 측정 ON/OFF\timing 켜고 SELECT 실행
\COPY클라이언트 파일로 CSV 입출력\COPY orders TO '/tmp/o.csv' WITH CSV HEADER;
\i \e \oSQL 파일 실행·에디터 편집·결과 저장\i migrate.sql, \o out.txt
\r입력 중인 쿼리 버퍼 리셋(Ctrl+C 대신)멀티라인 취소는 \r, 종료는 \q
EXPLAIN ANALYZE실행계획+실측 시간으로 Seq Scan 진단EXPLAIN ANALYZE SELECT ...
pg_size_pretty(pg_total_relation_size())테이블+인덱스 총 크기 확인SELECT pg_size_pretty(pg_total_relation_size('orders'));
pg_stat_activity실행 중·대기 쿼리, idle in transaction 확인SELECT * FROM pg_stat_activity WHERE state = 'idle in transaction';
pgcli / mycli자동완성·구문강조 강화 CLIpgcli postgresql://.../mydb, mycli -u root mydb

관련 모듈로 더 깊이:

다음 모듈에서는 INNER, LEFT, RIGHT, FULL JOIN의 동작 원리와 성능 최적화 실행 조건을 다룹니다.

지식 확인

퀴즈 — 8문제

Q1

psql로 운영 DB에 접속 후 마이그레이션이 제대로 적용됐는지 확인하려 합니다. 현재 데이터베이스의 모든 테이블 목록을 보고, users 테이블의 컬럼 구조를 확인하는 올바른 명령 순서는?

Q2

운영 서버에서 psql 접속 후 특정 테이블이 예상보다 용량이 큰 것을 발견했다. 해당 테이블의 인덱스 포함 전체 크기를 가장 빠르게 확인하는 방법은?

Q3

PostgreSQL 연결 문자열(Connection String)의 올바른 형식은?

Q4

슬로우 쿼리가 의심되는 상황에서 psql에서 특정 SELECT 쿼리가 실제로 몇 ms 걸리는지 빠르게 확인하려 합니다. 실행 계획 없이 순수 실행 시간만 보는 가장 간단한 방법은?

Q5

psql 백슬래시 메타 커맨드 중 현재 DB의 테이블 목록과 특정 테이블 구조를 보는 것은?

Q6

운영자가 psql에서 긴 쿼리를 자주 입력하다 오타를 낸다. 자동완성·구문 강조로 도움받으려면?

Q7

[심화] GUI 도구로 조회 후 트랜잭션을 열어 둔 idle in transaction 세션이 DB 전체 성능을 떨어뜨릴 수 있는 이유는?

Q8

[심화] idle in transaction 방치로 인한 bloat를 진단·예방하는 방법으로 옳은 것은?

0 / 8 답변

🧪 실습으로 확인하기

PostgreSQL 설치 및 기본 설정

초급

Linux 서버에 PostgreSQL을 설치하고, 데이터베이스와 사용자를 생성한 뒤 외부 접속이 가능하도록 설정한다.

50📋 5단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요