2010-02-13 4 views
1

제한된 저장소 및 프로세서 속도로 임베디드 장치에서 사용할 플랫 파일 SKU 데이터베이스를 설정하는 임무가 주어졌습니다.Python을 사용하는 읽기 전용 이진 플랫 파일 저장소의 옵션

기본적으로 내가 가게에 필요한 데이터는 다음과 같이 구성

SKU 설명 위치 수량

이 파일은 몇 백만 레코드로 구성됩니다 가격.

가장 중요한 고려 사항은 저장 공간과 검색 시간입니다. 레코드는 SKU에서 검색해야하며 읽기 전용이므로 파일을 SKU별로 정렬 할 수 있습니다.

파이썬으로이 데이터에 액세스하고 싶습니다. 그래서 내 질문에이 문제가 있습니다.

나를 위해이 기능을 제공 할 수있는 기존 Python 라이브러리가 있습니까? 아니면 내 자신을 롤업해야합니까?

답변이 내 역할을 감당할 수 없다면 누구에게도 제안이나 권장 사항이 있습니까?

답변

4

SQLite과 파이썬 바인딩은 어떨까요? 그것은 당신이 필요로하는 것보다 조금 더 많은 것을 가지고 있지만 표준 소프트웨어이며 잘 테스트되었습니다.

+0

SQLite는 내가 필요한 것보다 훨씬 많은 기능을 가지고 있습니다. 또한, 나는 데이터를 저장할 수있는 콤팩트 모르겠지만 ... 아마도 누군가가 그걸 밝힐 수 있습니까? –

+1

@Stephen Potter, SQLite는 네이티브, 적절하게 컴팩트, 손상되기 어렵지만 표준, 확장 가능 및 빠릅니다. 그것은 평범한 파일보다 견고하고 자신이 굴리는 것보다 더 효율적이고 쉬운 것 같습니다. SQLite는 원할하게 잘 수행됩니다. –

+0

SQLite에 대한 약간의 편견이 있었지만 그 이유는 확실하지 않지만 필자가 수행 한 일부 테스트의 결과에 놀랐습니다. 아직 실제 테스트를 조금 더 할 필요가 있지만 실행 가능한 옵션처럼 보입니다. –

1

어때 대략 HDF? SQL을 필요로하지 않고 데이터에 빠르게 액세스해야하는 경우, 파이썬에서는 숫자 또는 구조화 된 데이터를 위해 더 빠른 것이 없습니다.

Python 위키의 DatabaseInterfaces 섹션을 확인하십시오. 포괄적입니다. 두 가지 "순수한"Python 옵션 (예 : SnakeSQL)이 있습니다.이 옵션은 배포하기에 더 좋은 방법입니다. 그리고 물론, 언제나 Berkeley DB 등이 있습니다. 슈퍼 가늘다는 &입니다.

솔직히 SQLite가 잘 작동 할 것입니다. 더 많은 퍼포먼스를 정말로 필요로한다면, BDB와 같은 레코드 기반 포맷을 보게 될 것입니다.

+0

이것에 관해 더 읽을 것이 있습니다. 그러나 나는 정말로 더 단순한 것으로 생각했다. 아마도 모든 부분에 대해 일종의 데이터 압축을 사용하여 고정 길이 레코드를 정렬했지만 키와 파일의 적절한 위치로 더 빨리 이동할 수있는 매우 간단한 인덱스를 사용했을 것입니다. –

+0

BerkeleyDB가 너무 익숙하지 않다면, 제안 할 것입니다. 파이썬 위키의 데이터베이스 인터페이스 레지스트리를 살펴보십시오. 나는 내 대답을 URL로 편집했다. – pestilence669

+0

역효과, 나는 당신이 올바른 SQLite 아마 날 위해 일할 것 같아요. 나는 그것이 내가 바라는 것보다 조금 더 많은 저장 공간을 사용하는 것으로 보인다. 매우 작은 레코드와 높은 구조 오버 헤드를 연관시킬 수 있습니다. 나는 아직도 더 많은 테스트를해야한다. 작동하지 않으면 BDB를 두 번째 옵션으로보고 있습니다. –

0

간단한 해결책은 CPickle입니다. SO에 similar questions을 (를) 찾을 수도 있습니다.

+0

데이터가 RAM에 들어갈 수있는 것보다 훨씬 클 것입니다. –

+0

얼마나 많은 RAM을 예산으로 책정 했습니까? – cmcginty

4

이전 방법은 gdbm 모듈과 같은 간단한 키/값 데이터 테이블을 사용하는 것입니다. 파이썬은 그것을 지원하지만, 그것은 내 기계에 기본 파이썬 설치로 내장되어 있지 않습니다.

일반적으로 SQLite를 사용하십시오. 다른 사람들이 썼 듯이, 파이썬은 표준으로 제공되며 이미 많은 임베디드 시스템에서 사용됩니다.

레코드가 고정 길이이면 bisect 모듈을 사용할 수 있습니다. 파일 크기/레코드 크기는 파일의 레코드 수를 제공합니다. bisect 검색은 파일에서 O (log (n)) 검색을 수행하며, 동등성을 테스트하기 위해 어댑터를 작성해야합니다. 나는 그것을 테스트하지 않았습니다 있지만, 여기 스케치입니다 : 당신은 추가로 파일을 gzip을하고 gzip'ped 파일을 추구 할 수

import bisect 

RECORD_SIZE = 50 

class MatchFirst10Chars(object): 
    def __init__(self, word): 
     self.word = word 
    def __lt__(self, other): 
     return self.word < other[:10] 

class FileLookup(object): 
    def __init__(self, f): 
     self.f = f 
     f.seek(0, 2) 
     self.size = f.tell() // RECORD_SIZE 
    def __len__(self): 
     return self.size 

    def __getitem__(self, i): 
     self.f.seek(i*RECORD_SIZE) 
     return self.f.read(RECORD_SIZE) 


SKU = "123-56-89 " 
f = open("data_file") 
fl = FileLookup(f) 
i = bisect.bisect(fl, MatchFirst10Chars(SKU)) 

,하지만 테스트해야 시간 대 공간에 대한 트레이드 오프의 .

+0

+1 모든 레코드를 고정 길이로 만들 충분한 공간이 있다면 꽤 좋은 방법입니다. –

0

공간 요구 사항을 줄이기 위해 Andrew Dalke의 답변이 다양하므로 (SKU를 빨리 찾을 수 있도록 이진 검색을 사용할 수 있음) 파일 시작 부분에 고정 된 크기의 레코드 (SKU 당 하나)를 가진 다음 모든 설명 및 위치 (null로 끝나는 문자열이 말함)

고정 된 길이로 위치와 설명을 채워 넣지 않아도되므로 공간을 절약 할 수 있습니다. 중복 위치 여기

많은이있는 경우 또한이 공간을 절약 할 수 있습니다 예입니다 내가 cdb을 제안 할 수 있습니다 당신이

SKU   16 bytes 
Description Variable length 
Location Variable length 
Price  4 bytes (up to $42949672.95) 
Quantity 4 bytes (up to 4294967295) 



offset   SKU  desc_off loc_off  Price  Quantity 
0x00000000 SKU0000000000001 0x01f78a40 0x01f78a47 0x000003e8 0x000f4240 
0x00000020 SKU0000000000002 0x01f78a53 0x01f78a59 ... 
... 
... # 999998 more records 
... 
0x01f78a40 Widget\x00 
0x01f78a47 Head office\x00 
0x01f78a53 Table\x00 
0x01f78a59 Warehouse\x00 
1

이 있다고? (파이썬 바인딩 : python-cdb.)

당신과 같이 읽기 전용 데이터로 사용되는 형식입니다. 기본적으로 256 개의 거대한 해시 테이블을 가지고 있으며 각각 다른 수의 버킷을 가질 수 있습니다. cdb의 멋진 점은 파일을 메모리에로드 할 필요가 없다는 것입니다. 그것은 단지 당신이 필요한 비트로 보내면 mmap로 조회를 할 수있는 방식으로 구성되어 있습니다.

cdb spec은 좋은 읽기입니다. 줄이 균일 한 오른쪽 여백을 만들기 위해 서식이 지정 되었기 때문입니다. :-D

관련 문제