db구축 질문
2011.01.09 04:54
db내에 레코드의 수는 수백만입니다.
한 레코드에 길이가 정해져 있지 않은 정수(long)배열을 저장해야 합니다. 정수배열의 길이는 대략 수십에서 1천입니다.
이 정수들을 빠르게 access하여야 합니다.
생각하고 있는 방법은 한 필드에 정수배열을 text로 저장하여서 explode/implode해서 쓰는 것인데 문제는 효율입니다.
검색을 보면 하나의 모든 레코드를 전부 iteration으로 explode/implode해서 검색을 해야 합니다.
사실 제대로 실험해 본 것이 아니라서 얼마나 효율이 나올지 모르겠는데 참아줄만한 효율이 나올 것 같기도 하고 판단이 안섭니다. 몇초정도는 참아줄만 할 거 같은데 분단위로 넘어가거나 하면 안됩니다. 이럴 때 쓸만한 기법이 있을까요?
코멘트 7
-
왕초보
01.09 05:23
-
혹시 더이상 증가가 되지 않는 DB거나 혹은 분기나 년으로 증가하는 DB 라 하면
배열에 따라 테이블/레코드를 두는 것이 아닌 정수의 크기에 따른 테이블을 만드시는게 더 좋을수도 있을것 같다라는 생각이 드네요.
예를 들면
a[3] = {100,5,30}
b[3] = {200,3,44}
c[3] = {150,7,24}
라는 배열이 있따면 a테이블 b테이블 c테이블 식으로 만드는 것이 아닌
1자리 테이블 10자리 테이블 100자리 테이블로 만들어서 저장하되, 그 배열의 이름과 순서를 레코드에 같이 저장해두고
찾을시에는
1. 배열의 이름과 순번으로 찾는다
2. Binary Search 를 통하여 찾는다.
두가지 경우를 생각할 수 있겠습니다.
그렇게 된다면 테이블은
테이블 = 레코드(배열이름,순번, 숫자) 형식으로 Sorting(숫자) 되어서 저장이 되어야 할것입니다.
바이너리 서치는 반드시 소팅되어서 저장되어야 하니 이점 꼭 유의해주세요 ^^;
만약에 계속적으로 저장되는 DB라면.. 음.. 잘 모르겠네요 ㅠㅠ; 사실 저렇게 해서
바이너리 서치 하기전에 Orderby였던가요? 이것으로 오름차순 내림차순으로 수를 정리하면 될것 같은데
여기서 걸리는 시간을 잘 모르겠네요 ^^;; 저도 DB를 많이 다뤄보진 않았지만 혹시나 해서 이렇게 올려봅니다.
그나저나.. 왕초보님은 전공도 아니신걸 저렇게 알고 계시다니.. 혹시 로스웰에 불시착하신 외계인 아니십니까 -_-a
문외한분이 저정도면 전 그래도 컴공전공인데 ㅠ0ㅠ;; 세상은 불공평해욧!
-
꼬소
01.09 13:41
데이터를 어떤 방식으로 가져 오는지 알 방법은 없지만, 특정 레코드를 찾아서 배열의 몇 번째 값을 가져온다고 하신다면
hash와 tree로 구성하면 만족할만한 성능을 얻으실 수 있을 겁니다.
레코드의 수가 제법 많으니 레코드를 구분하는 값을 두어 그 값을 100이든 1000이든 나누어 hash로 구성하고
나누어진 레코드들은 다시 tree로 구성하시면 될 듯 합니다.
구분하는 값에 따라서 hashing과 tree에 삽입하게 된다면 나중에 read만 계속 된다고 하였을 때 상당히 빠른시간안에
데이터를 읽어 올 수 있을 겁니다.
-
왕초보
01.09 17:02
레코드가 메모리에 다 올라와 있으면 문제가 비교적 간단해지는데.. 양이 무지 많아서 대부분의 db는 디스크에 올라가 있다고 하면.. 또 db가 자주 update된다고 하면.. 또 갑자기 컴터 전원이 나갔을때 db를 어떻게 처리하느냐는 문제까지 넘어가면.. update하다가 전원이 나가면 어떻게 복구하느냐는 건..
일이 마구 꼬이기 시작합니다. -_-;
-
저두 직업이 유사 전공이라서 관심있어서 글을 적습니다.
한 레코드에서 한 필드가 "정해져 있지 않은 정수(long)배열" 로 이해했습니다만,
그렇다면 필드를 추가해서 랜덤한 정수를 규칙화 하여 그 필드를 기준으로 검색을 해야 맞을 듯 합니다만,
제가 맞게 이해하고 있는지 모르겠지만,
랜덤한 정수를 검색하시고자 방법을 찾을려고 하시는 것보다
어차피 방법을 찾고자하시려면, 규칙을 찾으셔야 하므로,
DB 스키마에서 필드를 추가하셔서 이를 기준으로 검색하시면
속도 문제가 해결 될듯 보입니다. ^^;
부족하나마 의견을 피력해 보았습니다.
-
엔도르
01.10 02:14
정확히 어떤 일을 하려고 하시는 건지 잘은 모르겠지만..
정수의 배열을 레코드 하나에 다 저장해야만 하는지부터 생각을 해봐야 하는게 아닌가 싶기도 하네요. 검색을 비롯한 각종 작업들이 구체적으로 어떤 식으로 이루어 지는지도 알아야 할 것 같고요. 대충 생각해 보면 개념적으로 수십억 개의 정수가 있고, 그 정수들이 수십~수천 개씩 그룹을 지어 수백만 개의 레코드를 구성하는 상황인 것 같은데.. 그러면 그 정수들 중에 겹치는 게 있는지, 검색은 그 배열 안에 있는 정수를 찾아내는건지, 등등의 의문점이 생기고요. 근데 어떻게 해도 레코드가 수백만 개라면 정수배열 <-> 텍스트는 검색 속도가 잘 안 나올 것 같긴 합니다.
레코드 테이블 관계 테이블 정수 테이블
레코드idx, 레코드이름 - 1:N - 레코드idx,정수idx(,seq) - N:1 - 정수idx,정수
제가 생각하는 그림이 맞다면 이런 식으로 정규화를 해서 정수 테이블에서 검색한 다음 그 정수가 속해있는 레코드를 불러오는 방법이 있을 것 같습니다.
역시 문외한이 끄적..
-
cloudn1ne
01.10 02:32
직접 구현한다면 hash+list 또는 hash+tree 구조가 괜찮을것 같구요. text는 오버헤드가 너무 큽니다. 구현도 어렵고요.
레코드가 수백만이면 SQlite등의 솔루션을 쓰는게 낫지 않나요?
직접 구현하면 저널링도 해 줘야 하고 이래저래 신경쓸게 많습니다.
길이가 정해져 있지 않은 배열은 보통 linked list를 사용해서 저장합니다. 그렇지만 길이가 정해져 있지 않다고 하더라도 길이를 언제라도 마구 바꿔야 하는 필요가 있지 않다면 그냥 배열의 pointer로 잡아도 됩니다. 각 레코드는 각 배열의 끄트머리 pointer만 갖고있으면 되니까 정수 배열의 자료구조에 별로 구애받지 않습니다.
text로 저장하고 다시 변환하는 그 자체만으로도 오버헤드가 상당하므로 비추. 그냥 정수는 정수로 저장하고 사용하세요.
array와 linked list의 접근 속도는 어떻게 사용하느냐에 따라 많이 달라집니다. 하드웨어 아키텍춰도 영향을 주지요. 레코드 갯수 몇백만은 요즘 세상엔 정말 아무것도 아닙니다. -_-; T 정도는 붙어야 좀 큰 db라고 할듯.
속도가 좀 떨어지는 하드웨어로 돌리는 경우엔 long integer type을 비교하는 것도 overhead가 될 수 있습니다. 만약 == 만 필요하고 대소 구분을 할 필요가 없고 pointer를 비교하는 것이 빠른 경우엔 모든 정수를 pointer로 할당하고 포인터만 비교하는 것도 속도를 올리는 한 방법입니다.
도대체 무슨 일을 하시길래.. ㄷㄷㄷ
주의: 저는 문외한입니다. -_-;