database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Devel 5823 게시물 읽기
 News | Q&A | Columns | Tutorials | Devel | Files | Links
No. 5823
발음 비슷한 한글을 같은 글자로 처리하는 함수
작성자
김상기(ioseph)
작성일
2005-01-24 16:39:30ⓒ
2005-01-24 16:40:39ⓜ
조회수
10,989
첨부파일
파일이름크기Info 
soundexko.c3.35 KB  
soundexko.dll7.5 KB  

이 함수의 출발은 몇해전 hcode 기반 변형 함수를 만들었던 것에서 시작합니다.

기억하지 못하는 분들과 전혀 모르는 분들을 위해서 잠시 설명드리면,

 

인명정보에 '제프백' 이 있는데, 사용자가 '재프백'으로 검색해도 검색할 수 있도록 하는 것이 목표였습니다.

한글에 대해서만 처리를 했으며, 공백이나 기타 특수 기호들에 대해서는 전혀 건드리지 않습니다.

검색이 목적인지라, 처음부터 1024byte 까지만의 문자열을 대상으로 처리합니다.

 

옛 버전이 euc-kr 기반이어서 이번에 utf-8 기반으로 바꾸었습니다.

즉, 데이터베이스 인코딩이 unicode 여야지 아래처럼 사용할 수 있습니다.

그냥 ascii 이거나, euc-kr 이면, convert 함수를 통해서 soundexko() 함수로 넘겨줄 인자를 미리 utf-8 인코딩으로 변경하셔야합니다.

 

사용방법은 다음과 같습니다.

 

mydb=# select * from t;
 no |  name  |  phone
----+--------+----------
  1 | 김혜은 | 123-1234
  2 | 신기배 | :)
  3 | 코엑스 | 222-1234
  4 | 왜관   | 999-1111
(4건 있음)

작업시간: 1.767 ms
mydb=# select * from t where soundexko(name) ~ soundexko('꼬엑스');
 no |  name  |  phone
----+--------+----------
  3 | 코엑스 | 222-1234
(1건 있음)

작업시간: 2.541 ms
mydb=# select * from t where soundexko(name) ~ soundexko('기베');
 no |  name  | phone
----+--------+-------
  2 | 신기배 | :)
(1건 있음)

작업시간: 2.468 ms
mydb=# select * from t where soundexko(name) ~ soundexko('해은');
 no |  name  |  phone
----+--------+----------
  1 | 김혜은 | 123-1234
(1건 있음)

작업시간: 2.270 ms
mydb=# select * from t where soundexko(name) ~ soundexko('외간');
 no | name |  phone
----+------+----------
  4 | 왜관 | 999-1111
(1건 있음)

작업시간: 2.465 ms


 

첨부된 dll 파일은 win32 용입니다. pgsql lib 디렉토리안에 옮겨두고, 여느 함수 등록하듯이 등록하고 사용하면 됩니다.

이 글에 대한 댓글이 총 2건 있습니다.

상기님~ 좋네여! ㅎㅎㅎ

CREATE OR REPLACE FUNCTION soundexko(text) RETURNS text AS'soundexko'LANGUAGE 'c' IMMUTABLE CALLED ON NULL INPUT SECURITY INVOKER;

이렇게 등록하구요~

Regent=# \d test
    Table "public.test"
 Column | Type | Modifiers
--------+------+-----------
 search | text |
Indexes:
    "test_search" btree (soundexko(search))
Regent=# SELECT * from test;
  search
----------
 신기배
 신기베
 신기베
 씬기베
 신키배는
 신기베는
(6 rows)

 

이렇게 인덱스를 soundexko(search) 컬럼으로 잡구요..

Regent=# EXPLAIN ANALYZE SELECT * from test where soundexko(search)=soundexko('신기배');
                                                    QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
 Index Scan using test_search on test  (cost=0.00..4.68 rows=1 width=32) (actual time=0.030..0.045 rows=4 loops=1)
   Index Cond: (soundexko(search) = 'SinGixBex'::text)
 Total runtime: 0.086 ms
(3 rows)

 

하면 인덱스를 잘타는데..

Regent=# EXPLAIN ANALYZE SELECT * from test where soundexko(search) ~~ soundexko('신기배');
                                                  QUERY PLAN
---------------------------------------------------------------------------------------------------------------
 Seq Scan on test  (cost=100000000.00..100000001.14 rows=1 width=32) (actual time=0.036..0.060 rows=4 loops=1)
   Filter: (soundexko(search) ~~ 'SinGixBex'::text)
 Total runtime: 0.093 ms
(3 rows)
Regent=# EXPLAIN ANALYZE SELECT * from test where soundexko(search) like soundexko('신기배')||'%';
                                                  QUERY PLAN
---------------------------------------------------------------------------------------------------------------
 Seq Scan on test  (cost=100000000.00..100000001.14 rows=1 width=32) (actual time=0.037..0.061 rows=4 loops=1)
   Filter: (soundexko(search) ~~ 'SinGixBex%'::text)
 Total runtime: 0.094 ms
(3 rows)
이렇게 하면 타지 않습니다.. -.-; 당연히 set enable_seqscan=false;로 인덱스를 탈 수 있으면 무조건 타게 해놨는데..

왜 그럴까용?

신기배(소타)님이 2005-01-30 00:35:17에 작성한 댓글입니다.
이 댓글은 2005-01-30 00:38:14에 마지막으로 수정되었습니다.
Regent=# EXPLAIN ANALYZE SELECT * from test where soundexko(search) in (soundexko('신기배'),soundexko('천재'));
                                                           QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
 Index Scan using test_search, test_search on test  (cost=0.00..9.38 rows=1 width=32) (actual time=0.033..0.100 rows=4 loops=1)
   Index Cond: ((soundexko(search) = 'SinGixBex'::text) OR (soundexko(search) = 'CdnJex'::text))
 Total runtime: 0.107 ms
(3 rows)

 

아흑.. 쵝오! -_-)=b

잘 응용하면 FTI에도 응용할 수 있을지도 -.-;;; 검색할 때 자동으로 검색어에 각종 조사를 붙여줘서 검색시키면 -_-;;;;

신기배(소타)님이 2005-01-30 00:42:46에 작성한 댓글입니다.
이 댓글은 2005-01-30 00:43:41에 마지막으로 수정되었습니다.
[Top]
No.
제목
작성자
작성일
조회
61241차원 배열 요소 삭제 함수 - anyarray, anyelement 사용 예제 [4]
김상기
2005-06-01
11799
6047지정한 prepared query 가 있는지 조회하는 함수 [2]
김상기
2005-04-13
12490
6043문자열 첫글자(영문) 또는 첫글자의 초성(한글) 추출
신기배
2005-04-13
13295
5823발음 비슷한 한글을 같은 글자로 처리하는 함수 [2]
김상기
2005-01-24
10989
5702PostgreSQLDirect .NET Data Provider
정재익
2004-11-23
11630
5481pl/python 한글 초성 구하는 함수 [2]
김상기
2004-08-18
10867
5297crypt 함수 구현하기 [1]
이상호
2004-04-17
9168
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2019 DSN, All rights reserved.
작업시간: 0.077초, 이곳 서비스는
	PostgreSQL v11.5로 자료를 관리합니다