반응형
반응형

[SQL] 여러 개의 UPDATE 문을 실행한 후, 최종적으로 영향을 받은 전체 행의 개수를 세고 싶다

 

@@ROWCOUNT는 직전에 실행된 SQL 문이 영향을 준 행의 개수를 반환하는 전역 변수예요. 여러 개의 UPDATE 문을 실행할 경우, 각 UPDATE 문 직후에 이 값을 변수에 누적해서 더하면 최종 결과를 얻을 수 있어요.

 

-- 총 업데이트된 행 수를 저장할 변수 선언
DECLARE @TotalRowCount INT = 0;

-- 첫 번째 UPDATE 문 실행
UPDATE dbo.Customers
SET CustomerStatus = 'VIP'
WHERE TotalPurchases >= 100000;

-- 첫 번째 UPDATE의 영향을 받은 행 수를 변수에 더하기
SET @TotalRowCount = @TotalRowCount + @@ROWCOUNT;

-- 두 번째 UPDATE 문 실행
UPDATE dbo.Customers
SET CustomerStatus = 'Gold'
WHERE TotalPurchases >= 50000 AND TotalPurchases < 100000;

-- 두 번째 UPDATE의 영향을 받은 행 수를 변수에 더하기
SET @TotalRowCount = @TotalRowCount + @@ROWCOUNT;

-- 최종적으로 업데이트된 총 행 수 출력
PRINT '총 ' + CAST(@TotalRowCount AS NVARCHAR(10)) + '개의 행이 업데이트되었습니다.';
반응형
반응형

MSSQL(마이크로소프트 SQL Server)에서 ERD(Entity Relationship Diagram) 생성을 지원하는 오픈소스 프로그램 중에서 추천할 수 있는 도구들은 다음과 같습니다:


✅ 1. DBeaver 

  • 라이선스: Apache License 2.0 (Community Edition 기준)
  • 특징:
    • 다양한 DB(MSSQL 포함) 지원
    • ERD 자동 생성 및 편집 가능
    • SQL 스크립트와 구조 동시 확인
    • 플러그인 확장 가능
  • 장점:
    • 사용 편리
    • 오픈소스이지만 기능이 풍부
  • 웹사이트: https://dbeaver.io

✅ 2. DBDiagram.io (ERD 모델링 지원 웹 도구)

  • 라이선스: 무료 온라인 도구 (오픈소스는 아니지만, 무료이고 간단하게 사용 가능)
  • 특징:
    • 간단한 마크다운 형식으로 ERD 작성
    • SQL에서 가져오기/내보내기 가능
    • 협업 지원
  • 장점:
    • 웹 기반으로 설치 없이 사용
  • 웹사이트: https://dbdiagram.io

✅ 3. SQLPad

  • 라이선스: MIT License
  • 특징:
    • 쿼리 실행 + 시각화 + ERD 기능 지원 (약간 제한적)
    • MSSQL 포함 다양한 DB 연동
    • 웹 기반 SQL 편집기
  • 웹사이트: https://github.com/sqlpad/sqlpad

✅ 4. PgModeler (PostgreSQL 전용이나 일부 호환 시도 가능)

  • MSSQL 직접 지원은 아니나, ERD 기능 강력
  • 오픈소스 구조 파악, 커스텀 DB 작업용으로 참고 가능
  • https://pgmodeler.io/

💡 기타 유료이지만 강력한 대안 (참고용)

  • dbForge Studio for SQL Server (유료, ERD 생성 좋음)
  • DataGrip (JetBrains, 유료 IDE, 강력한 ERD 지원)

추천 정리:

도구오픈소스ERD 생성MSSQL 지원설치/웹
DBeaver 설치형
SQLPad 제한적 웹 기반
DBDiagram.io ❌ (무료) ✅ (SQL import) 웹 기반
 

🔧 추천 조합:

  • 정식 업무 및 ERD 필요: DBeaver
  • 간단한 ERD 또는 공유 목적: DBDiagram.io
  • 웹 기반 쿼리툴 + 시각화: SQLPad
반응형
반응형

[MSSQL] update 구문 여러개를 실행하고 그 결과 row의 총 개수를 구하라

DECLARE @TotalAffectedRows INT = 0; -- 총 영향을 받은 행을 저장할 변수

-- 첫 번째 UPDATE 구문
UPDATE your_table
SET column1 = 'value1'
WHERE condition1;

SET @TotalAffectedRows = @TotalAffectedRows + @@ROWCOUNT; -- 영향을 받은 행 수 누적

-- 두 번째 UPDATE 구문
UPDATE your_table
SET column2 = 'value2'
WHERE condition2;

SET @TotalAffectedRows = @TotalAffectedRows + @@ROWCOUNT; -- 영향을 받은 행 수 누적

-- 세 번째 UPDATE 구문
UPDATE your_table
SET column3 = 'value3'
WHERE condition3;

SET @TotalAffectedRows = @TotalAffectedRows + @@ROWCOUNT; -- 영향을 받은 행 수 누적

-- 최종 결과 출력
SELECT @TotalAffectedRows AS TotalAffectedRows;
반응형
반응형

2025년을 위한 7개의 데이터베이스

 

 

 

https://news.hada.io/topic?id=18153

 

2025년을 위한 7개의 데이터베이스 | GeekNews

다양한 문제를 해결하기 위해 주목할 가치가 있는 DB 7개를 소개이는 "최고의 DB" 목록이 아닌, 새롭고 유용한 관점을 제공하는 도구들2025년엔 이들 각 DB에 대해 일주일씩 투자해보길 바람(7 DBs in

news.hada.io

Table of Contents

  1. PostgreSQL
  2. SQLite
  3. DuckDB
  4. ClickHouse
  5. FoundationDB
  6. TigerBeetle
  7. CockroachDB
  • 다양한 문제를 해결하기 위해 주목할 가치가 있는 DB 7개를 소개
  • 이는 "최고의 DB" 목록이 아닌, 새롭고 유용한 관점을 제공하는 도구들
  • 2025년엔 이들 각 DB에 대해 일주일씩 투자해보길 바람(7 DBs in 7 Weeks)

1. PostgreSQL: 기본 데이터베이스

  • PostgreSQL은 기본적으로 사용되는 안정적인 기술
    • "Just use Postgres"라는 문구는 널리 알려진 밈이자 신뢰성을 상징하는 표현임
    • ACID를 준수하며 물리적 및 논리적 복제를 포함한 강력한 기능을 제공함
    • 주요 벤더들 간에 광범위한 지원을 받고 있는 안정적 데이터베이스임
  • PostgreSQL의 가장 큰 매력: 확장성
    • 확장 기능(Extensions)을 통해 독창적인 기능을 추가 가능함
    • 주요 확장 기능 예시:
      • AGE: 그래프 데이터 구조와 Cypher 쿼리 언어 지원
      • TimescaleDB: 시계열 데이터 작업 지원
      • Hydra Columnar: 열 기반 스토리지 엔진 제공
    • 확장 기능은 PostgreSQL을 타 데이터베이스와 차별화시키는 핵심 요소임
  • PostgreSQL의 유용성과 확장성
    • 다양한 생태계를 갖추고 있으며, 기본 설정이 합리적이고 사용자 친화적임
    • 비 PostgreSQL 서비스에서도 Postgres 와이어 프로토콜을 사용해 클라이언트 호환성을 제공함
    • WebAssembly(Wasm) 환경에서도 설치 가능할 정도로 가벼움
  • PostgreSQL 학습 권장
    • PostgreSQL의 가능성과 한계를 이해하기 위해 시간을 투자할 가치가 있음
    • 예: MVCC(Multi-Version Concurrency Control)의 복잡성 이해
    • 간단한 CRUD 애플리케이션 개발, PostgreSQL 확장 기능 작성 등을 추천함

2. SQLite: 로컬-우선 데이터베이스

  • SQLite는 "로컬 우선" 데이터베이스로 독립적으로 실행 가능
    • 클라이언트-서버 모델을 벗어나 애플리케이션과 같은 환경에서 실행됨
    • 예시: WhatsApp과 Signal은 기기 내부에 SQLite를 사용하여 채팅 데이터를 저장함
  • SQLite의 발전된 활용 사례
    • 기본 ACID 준수 데이터베이스 이상의 창의적인 사용 가능
    • 새로운 도구와 확장 기능:
      • Litestream: SQLite의 스트리밍 백업 제공
      • LiteFS: 분산 액세스를 지원하여 더욱 유연한 토폴로지 구현
      • CR-SQLite: CRDT(Conflict-free Replicated Data Types)를 사용해 변경 세트를 병합할 때 충돌 해결 필요성을 제거
  • SQLite의 인기 재조명
    • Ruby on Rails 8.0 덕분에 다시 주목받고 있음
    • 37signals: SQLite를 기반으로 Rails 모듈(Solid Queue 등)을 개발
      • Rails의 다중 SQLite 데이터베이스 관리 지원 (database.yml)
    • Bluesky: 개인 데이터 서버(Personal Data Servers)로 사용자마다 개별 SQLite 데이터베이스 사용
  • SQLite 활용 학습 권장
    • SQLite를 이용한 로컬 중심 아키텍처 실험
    • 기존의 PostgreSQL 기반 클라이언트-서버 모델을 SQLite로 대체할 수 있는지 시도

3. DuckDB: 모든 것을 질의할 수 있는 데이터베이스

  • DuckDB는 OLAP에 특화된 임베디드 데이터베이스
    • SQLite처럼 애플리케이션과 함께 작동하지만 OLTP 대신 OLAP 작업에 중점
    • 데이터 분석 및 쿼리 중심으로 설계된 시스템
  • DuckDB의 "쿼리-애니씽(Query-Anything)" 특성
    • 다양한 데이터 소스를 직접 SQL로 쿼리 가능:
      • CSV, TSV, JSON 등 일반 파일 형식
      • Parquet 등 고급 파일 형식 지원
    • 이 기능은 유연성을 제공하며, 예: Bluesky의 데이터 스트림 분석
  • 확장성 및 생태계
    • DuckDB에도 확장 기능이 존재하나, Postgres만큼 풍부하지 않음 (상대적으로 젊은 프로젝트)
    • 커뮤니티 기여 확장이 많이 있으며, gsheets(Google Sheets 연동)가 주목할 만함
  • DuckDB 활용 학습 권장
    • Python 노트북이나 Evidence를 통해 데이터 분석 및 처리 실험
    • SQLite와 결합: SQLite 데이터베이스의 분석 쿼리를 DuckDB로 위임해 성능 향상

4. ClickHouse: 컬럼형 데이터베이스

  • ClickHouse는 OLAP 작업에 특화된 데이터베이스
    • OLTP는 PostgreSQL, OLAP는 ClickHouse라는 조합이 이상적임
    • 대규모 분석 워크로드를 처리하며, 수평 확장과 샤딩을 통해 높은 데이터 삽입 속도를 지원함
  • ClickHouse의 주요 특징
    • 계층형 스토리지 지원:
      • "핫 데이터"와 "콜드 데이터"를 분리해 저장 가능
      • 예: GitLab 문서에서 이를 활용한 사례를 자세히 다룸
    • 대규모 데이터셋 처리 및 실시간 분석:
      • DuckDB로는 처리하기 어려운 크기의 데이터셋에 적합
      • 실시간 분석이 필요한 상황에서 강력한 성능 제공
  • 운영의 편리함
    • 배포, 확장, 백업 등 운영 관련 문서가 체계적이며 상세함
    • 예: 적절한 CPU 설정 방법까지 다룬 문서 제공
  • ClickHouse 학습 권장
    • 대규모 분석 데이터셋 실험 또는 DuckDB로 작업한 분석을 ClickHouse로 변환
    • ClickHouse의 임베디드 버전인 chDB를 활용해 SQLite와 더 직접적으로 비교 가능

5. FoundationDB: 레이어드 데이터베이스

  • FoundationDB는 "데이터베이스의 기반" 역할을 하는 독특한 시스템
    • 키-값 저장소로 설계되었으나 단순한 데이터베이스라기보다는 데이터베이스를 구축하는 "기초"로 작동
    • 애플, Snowflake, Tigris Data와 같은 주요 기업에서 사용
  • 주요 특징 및 한계
    • 제한사항:
      • 트랜잭션 데이터는 10MB를 초과할 수 없음
      • 트랜잭션은 첫 번째 읽기 이후 5초를 넘길 수 없음
    • 이러한 제한으로 인해 대규모 환경에서도 완전한 ACID 트랜잭션 지원 가능
      • 예: 100TiB 이상의 클러스터 운영 사례
  • FoundationDB의 설계와 테스트
    • 특정 워크로드에 최적화되어 설계됨
    • 시뮬레이션 테스트를 통해 안정성과 확장성을 입증:
      • Antithesis 및 다른 데이터베이스에서도 동일한 테스트 방법론 사용
      • 관련 참고 자료: Tyler Neely와 Phil Eaton의 문서
  • "레이어드" 데이터베이스로서의 FoundationDB
    • 스토리지 엔진과 데이터 모델 간 결합이 느슨함:
      • 다양한 레이어에서 스토리지 엔진을 재매핑 가능
      • 예: Record 레이어, Document 레이어 (FoundationDB 조직에서 제공)
    • Tigris Data에서 작성한 레이어 설계 사례가 참고할 만함
  • FoundationDB 학습 권장
    • 튜토리얼을 진행하며 RocksDB 같은 시스템을 대체할 가능성 탐색
    • 설계 방법(Design Recipes)과 관련 논문 읽기
    • Anti-Features와 Features 문서를 통해 사용 제한과 해결 가능한 문제 이해

6. TigerBeetle: 철저하게 정확한 데이터베이스

  • TigerBeetle는 금융 트랜잭션에 특화된 단일 목적 데이터베이스
    • 범용 데이터베이스와 달리 특정 목적, 특히 금융 거래에 초점
    • 오픈 소스로 제공되며, 높은 수준의 신뢰성과 정확성을 목표로 설계
  • 철저한 정확성을 위한 설계 철학
    • NASA의 Power of Ten Rules  프로토콜 인지 복구(Protocol-Aware Recovery) 구현
    • 엄격한 직렬화(strict serialisability)  Direct I/O 사용으로 커널 페이지 캐시 관련 문제 회피
    • 안전성 문서(Safety doc)와 독특한 프로그래밍 방식 "Tiger Style"에서 철저함을 확인 가능
  • Zig 언어로 구현된 혁신적 접근
    • Zig는 시스템 프로그래밍 언어로 비교적 신생이지만, TigerBeetle의 목표에 이상적으로 부합
    • 간결성과 성능을 극대화하는 데 Zig의 장점을 활용
  • TigerBeetle 학습 및 활용 제안
    • 로컬 배포 환경에서 금융 계좌 모델링 실험:
      • Quick Start를 따라 설치 및 사용
    • 시스템 아키텍처 문서(System Architecture docs)를 참고하여 범용 데이터베이스와 결합 가능성 탐구
    • 예: PostgreSQL 또는 FoundationDB와 함께 통합해 사용 사례 확장

7. CockroachDB: 글로벌 데이터베이스

  • CockroachDB는 글로벌 분산 데이터베이스
    • PostgreSQL 와이어 프로토콜과 호환되며, 수평 확장과 강한 일관성을 지원
    • Google Spanner에서 영감을 받은 설계로, 다중 지역에 걸친 데이터베이스 확장을 가능케 함
  • CockroachDB의 주요 기술적 특징
    • 시간 동기화 기술:
      • Google Spanner는 원자 시계와 GPS 시계를 사용하지만, CockroachDB는 일반 하드웨어에서도 동작하도록 설계
      • NTP 기반 동기화 지연 보정, 노드 간 클록 드리프트 비교 및 최대 오프셋 초과 시 멤버 종료
    • 다중 지역 구성:
      • 테이블 로컬리티(Table Localities) 기능을 통해 읽기/쓰기 트레이드오프에 따른 최적화 가능
      • 데이터가 사용자 지리적 위치에 맞게 분산되어 성능과 지연 시간을 개선
  • CockroachDB 활용 학습 제안
    • MovR 예제 재구현:
      • 원하는 언어와 프레임워크를 사용해 MovR(분산 애플리케이션 예제)을 구현
    • CockroachDB의 다중 지역 및 스케일링 전략을 활용하여 글로벌 애플리케이션 설계 실험
  • CockroachDB 선택 이유
    • DynamoDB와 같은 다른 분산 데이터베이스와 달리 로컬 환경에서 무료로 실행 가능
    • 강한 일관성과 글로벌 분산 지원이라는 차별화된 특성 제공

Wrap Up

  • 소개된 데이터베이스는 각기 다른 문제와 요구 사항을 해결하기 위해 설계됨
  • 2025년엔 이 데이터베이스들을 학습하며 더 흥미롭고 창의적인 문제 해결 방법을 탐구해보세요!

 

반응형
반응형

SQL Server에서 A, B, 그리고 각각의 A 값에 대한 카운트를 하나의 행에 열로 표시하려면, 피벗(PIVOT) 기능을 사용할 수 있습니다. 피벗을 사용하면 각 A 값이 열로 변환되며, 각 열의 값은 해당 A 값의 카운트가 됩니다.

가정: 테이블 구조

  • TableName 테이블에 A, B 열이 있다고 가정합니다.
  • A 열에는 여러 종류의 값이 있으며, 이 값들을 기준으로 카운트를 집계합니다.

예제: 피벗을 사용하여 A 값의 카운트를 열로 표시

SELECT 
    B,
    [A1],
    [A2],
    [A3],
    [A4],
    [A5]
FROM (
    SELECT 
        B,
        A,
        COUNT(1) AS CountA
    FROM 
        TableName
    GROUP BY 
        B, A
) AS SourceTable
PIVOT (
    SUM(CountA)
    FOR A IN ([A1], [A2], [A3], [A4], [A5])
) AS PivotTable
ORDER BY B;​

설명:

  1. 서브쿼리: 먼저 B, A, 그리고 각 A 값의 카운트를 집계합니다.
    • GROUP BY B, A: B와 A로 그룹화하여 각 A 값에 대한 카운트를 계산합니다.
  2. 피벗:
    • PIVOT (SUM(CountA) FOR A IN ([A1], [A2], [A3], [A4], [A5])): 각 A 값이 열로 변환되며, 각 열의 값은 해당 A의 카운트입니다.
  3. 결과: 최종적으로 B와 각 A 값의 카운트를 열로 표시합니다.

주의사항:

  • IN 절에 지정된 A1, A2, A3, A4, A5는 실제로 A 컬럼에 있는 값으로 대체해야 합니다. 예를 들어, A 값이 'Type1', 'Type2', 'Type3' 등일 경우, 해당 값을 정확하게 열 이름으로 지정해야 합니다.
  • 만약 A 값의 종류가 동적으로 변화한다면, 동적 SQL을 사용하여 피벗 쿼리를 작성해야 할 수 있습니다.

동적 피벗 예시

동적 피벗을 사용하면 테이블의 A 값이 변해도 자동으로 피벗을 적용할 수 있습니다.

DECLARE @cols AS NVARCHAR(MAX),
        @query AS NVARCHAR(MAX);

-- A 값 가져오기
SELECT @cols = STRING_AGG(QUOTENAME(A), ', ')
FROM (SELECT DISTINCT A FROM TableName) AS Temp;

-- 피벗 쿼리 생성
SET @query = 'SELECT B, ' + @cols + '
              FROM (
                  SELECT B, A, COUNT(1) AS CountA
                  FROM TableName
                  GROUP BY B, A
              ) AS SourceTable
              PIVOT (
                  SUM(CountA)
                  FOR A IN (' + @cols + ')
              ) AS PivotTable
              ORDER BY B;';

-- 실행
EXEC sp_executesql @query;​

이 동적 피벗 예시는 A 값의 종류에 따라 자동으로 피벗 쿼리를 생성하고 실행합니다.

반응형
반응형

[DataBase] Postgres를 검색엔진으로 활용하기  

 

https://anyblockers.com/posts/postgres-as-a-search-engine

 

Postgres as a search engine

Build a retrieval system with semantic, full-text, and fuzzy search in Postgres to be used as a backbone in RAG pipelines.

anyblockers.com

 

 

 


  • Postgres 내에서 시맨틱, 전문, 퍼지 검색을 모두 갖춘 하이브리드 검색 엔진을 구축할 수 있음
  • 검색은 많은 앱에서 중요한 부분이지만 제대로 구현하기 쉽지 않음. 특히 RAG 파이프라인에서는 검색 품질이 전체 프로세스의 성패를 좌우할 수 있음
  • 의미론적(Semantic) 검색이 트렌디하지만, 전통적인 어휘 기반 검색은 여전히 검색의 중추임
  • 의미론적 기술은 결과를 개선할 수 있지만, 견고한 텍스트 기반 검색의 기반 위에서 가장 잘 작동함

Postgres를 활용한 검색 엔진 구현하기

  • 세 가지 기술을 결합:
    • tsvector를 사용한 전체 텍스트 검색
    • pgvector를 사용한 의미론적 검색
    • pg_trgm을 사용한 퍼지 매칭
  • 이 접근 방식은 모든 상황에서 절대적으로 최고는 아닐 수 있지만, 별도의 검색 서비스를 구축하는 것에 대한 훌륭한 대안임
  • 기존 Postgres 데이터베이스 내에서 구현하고 확장할 수 있는 견고한 출발점
  • Postgres를 모든 것에 사용해야 하는 이유 : 그냥 Postgres를 모든 곳에 사용하세요, PostgreSQL로 충분하다, 그냥 Postgres 쓰세요

FTS와 의미론적 검색 구현

  • Supabase에 하이브리드 검색 구현에 대한 훌륭한 문서가 있으므로, 이를 시작점으로 삼을 것임
  • 가이드에 따라 GIN 인덱스를 사용하여 FTS를 구현하고, pgvector(bi-encoder dense retrieval이라고도 함)를 사용하여 의미론적 검색을 구현함
  • 개인적인 경험으로는 1536차원의 임베딩을 선택하는 것이 훨씬 더 나은 결과를 얻을 수 있음
  • Supabase 함수를 CTE와 쿼리로 대체하고, 매개변수 앞에 $를 붙임.
  • 여기서는 RRF(Reciprocal Ranked Fusion)를 사용하여 결과를 병합함
  • 이 방법은 여러 목록에서 높은 순위를 차지하는 항목이 최종 목록에서 높은 순위를 부여받도록 보장함
  • 또한 일부 목록에서는 높은 순위지만 다른 목록에서는 낮은 순위인 항목이 최종 목록에서 높은 순위를 부여받지 않도록 보장함
  • 순위를 분모에 넣어 점수를 계산하면 순위가 낮은 레코드에 불이익을 줄 수 있음
  • 주목할 만한 사항
    • $rrf_k: 첫 번째 순위 항목의 점수가 극단적으로 높아지는 것을 방지하기 위해(순위로 나누기 때문에), 분모에 k 상수를 추가하여 점수를 평활화하는 경우가 많음
    • $ _weight: 각 방법에 가중치를 할당할 수 있음. 이는 결과를 조정할 때 매우 유용함

퍼지 검색 구현하기

  • 이전까지의 방법으로도 많은 부분을 해결할 수 있지만, 명명된 엔티티에서 오타가 있을 경우 즉각적인 이슈가 발생할 수 있음
  • 의미론적 검색은 유사성을 포착하여 이러한 이슈 중 일부를 제거하지만, 이름, 약어 및 의미론적으로 유사하지 않은 기타 텍스트에 대해서는 어려움을 겪음
  • 이를 완화하기 위해 pg_trgm 확장을 도입하여 퍼지 검색을 허용
    • 트라이그램으로 작동함. 트라이그램은 단어를 3자 시퀀스로 분해하기 때문에 퍼지 검색에 유용
    • 이를 통해 오타나 약간의 변형이 포함되어 있더라도 유사한 단어를 매칭할 수 있음
    • 예를 들어 "hello"와 "helo"는 많은 트라이그램을 공유하므로 퍼지 검색에서 더 쉽게 매칭될 수 있음
  • 원하는 열에 대해 새 인덱스를 생성하고, 그 후 전체 검색 쿼리에 추가
  • pg_trgm 확장은 % 연산자를 노출하여 유사도가 pg_trgm.similarity_threshold(기본값은 0.3)보다 큰 텍스트를 필터링함
  • 유용한 다른 여러 연산자도 있음.

전문 검색 튜닝하기

  • tsvector 가중치 조정하기 :실제 문서에는 제목뿐만 아니라 내용도 포함됨
  • 열이 여러 개 있어도 임베딩 열은 하나만 유지함
  • 개인적으로 여러 임베딩을 유지하는 것보다 title과 body를 같은 임베딩에 유지하는 것이 성능에 큰 차이가 없다는 것을 발견함
  • 결국 title은 본문의 간단한 표현이어야 함. 필요에 따라 이를 실험해 보는 것이 좋음
  • title은 짧고 키워드가 풍부할 것으로 예상되는 반면, body는 더 길고 더 많은 세부 정보를 포함할 것임
  • 따라서 전체 텍스트 검색 열이 서로 어떻게 가중치를 부여하는지 조정해야 함
  • 문서에서 단어가 있는 위치나 중요도에 따라 우선순위를 부여할 수 있음
    • A-weight: 가장 중요(예: 제목, 헤더). 기본값 1.0
    • B-weight: 중요(예: 문서 시작 부분, 요약). 기본값 0.4
    • C-weight: 표준 중요도(예: 본문 텍스트). 기본값 0.2
    • D-weight: 가장 덜 중요(예: 각주, 주석). 기본값 0.1
  • 문서 구조와 애플리케이션 요구사항에 따라 가중치를 조정하여 관련성을 미세 조정함
  • 제목에 더 많은 가중치를 부여하는 이유
    • 제목은 일반적으로 문서의 주요 주제를 간결하게 표현하기 때문
    • 사용자는 검색할 때 먼저 제목을 훑어보는 경향이 있으므로 제목의 키워드 일치는 일반적으로 본문 텍스트의 일치보다 사용자의 의도와 더 관련이 있음

길이에 따른 조정

  • ts_rank_cd 문서를 읽어보면 정규화 매개변수가 있다는 것을 알 수 있음.
    • 두 랭킹 함수 모두 문서의 길이가 순위에 어떤 영향을 미쳐야 하는지 여부를 지정하는 정수 normalization 옵션을 사용함. 정수 옵션은 여러 동작을 제어하므로 비트 마스크임: |를 사용하여 하나 이상의 동작을 지정할 수 있음(예: 2|4).
  • 이러한 다양한 옵션을 사용하여 다음을 수행 가능
    • 문서 길이 편향 조정
    • 다양한 문서 집합에서 관련성 균형 조정
    • 일관된 표현을 위해 랭킹 결과 조정
  • 제목에는 0(정규화 없음), 본문에는 1(로그 문서 길이)을 설정하면 좋은 결과를 얻을 수 있음
  • 다시 말하지만, 사용 사례에 가장 적합한 옵션을 찾기 위해 다양한 옵션을 실험해 보는 것이 좋음

크로스 인코더를 사용한 재랭킹

  • 많은 검색 시스템은 두 단계로 구성됨
  • 즉, 양방향 인코더를 사용하여 초기 N개의 결과를 검색한 다음, 크로스 인코더를 사용하여 이러한 결과를 검색 쿼리와 비교하여 순위를 매김
    • 양방향 인코더(bi-encoder) : 빠르기 때문에 많은 수의 문서를 검색하는 데 좋음
    • 크로스 인코더(cross-encoder)
      • 더 느리지만 성능이 더 좋아 검색된 결과의 순위를 다시 매기는 데 좋음
      • 쿼리와 문서를 함께 처리하여 둘 사이의 관계에 대한 더 미묘한 이해를 가능하게 함
      • 이는 계산 시간과 확장성을 희생하면서 더 나은 랭킹 정확도를 제공함
  • 이를 수행하기 위한 다양한 도구들이 있음
  • 가장 좋은 것 중 하나는 Cohere의 Rerank
  • 또 다른 방법은 OpenAI의 GPT를 사용하여 자체적으로 구축하는 것
  • 크로스 인코더는 쿼리와 문서 간의 관계를 더 잘 이해할 수 있도록 하여 검색 결과의 정확도를 높일 수 있음
  • 그러나 계산 비용이 크기 때문에 확장성 면에서는 제한이 있음
  • 따라서 초기 검색에는 양방향 인코더를 사용하고, 검색된 소수의 문서에 대해서만 크로스 인코더를 적용하는 두 단계 접근 방식이 효과적임

언제 대안 솔루션을 찾아야 할까

  • PostgreSQL은 많은 검색 시나리오에 적합한 선택이지만 한계가 없는 것은 아님
  • BM25와 같은 고급 알고리듬의 부재는 다양한 문서 길이를 처리할 때 느껴질 수 있음
  • PostgreSQL의 전체 텍스트 검색은 TF-IDF에 의존하므로 매우 긴 문서와 대규모 컬렉션의 희귀 용어에 어려움을 겪을 수 있음
  • 대안 솔루션을 찾기 전에 반드시 측정해 보아야 함. 그럴 가치가 없을 수도 있음

결론

  • 이 글에서는 기본적인 전체 텍스트 검색부터 퍼지 매칭, 의미론적 검색, 결과 부스팅과 같은 고급 기술까지 많은 내용을 다루었음
  • Postgres의 강력한 기능을 활용하여 특정 요구사항에 맞춘 강력하고 유연한 검색 엔진을 만들 수 있음
  • Postgres는 검색을 위해 가장 먼저 떠오르는 도구는 아니지만 정말 멀리 갈 수 있게 해줌
  • 훌륭한 검색 경험을 위한 핵심
    • 지속적인 반복과 미세 조정
    • 논의한 디버깅 기법을 사용하여 검색 성능을 이해하고, 사용자 피드백과 행동을 기반으로 가중치와 매개변수를 조정하는 것을 두려워하지 말아야 함
  • PostgreSQL은 고급 검색 기능이 부족할 수 있지만, 대부분의 경우 충분히 강력한 검색 엔진을 구축할 수 있음
  • 대안 솔루션을 찾기 전에 먼저 Postgres의 기능을 최대한 활용하고 성능을 측정해 보는 것이 좋고, 그래도 부족하다면 그때 다른 솔루션을 고려해 볼 수 있음

https://news.hada.io/topic?id=16468&utm_source=weekly&utm_medium=email&utm_campaign=202436

 

Postgres를 검색엔진으로 활용하기 | GeekNews

Postgres 내에서 시맨틱, 전문, 퍼지 검색을 모두 갖춘 하이브리드 검색 엔진을 구축할 수 있음검색은 많은 앱에서 중요한 부분이지만 제대로 구현하기 쉽지 않음. 특히 RAG 파이프라인에서는 검색

news.hada.io

 

 

반응형

+ Recent posts