2010-01-21 1 views
8

SQLite 데이터베이스에 datetime 값을 저장합니다 (Delphi 및 DISqlite 라이브러리 사용). db의 본질은 결코 컴퓨터 나 시스템간에 전송 될 필요가 없으므로 상호 운용성은 제약이 아닙니다. 내 초점 대신 읽기 속도입니다. 날짜/시간 필드가 인덱싱 될 것이고, 수천 개의 datetime 값을 순차적으로 읽는 것뿐만 아니라 많은 것을 검색하게 될 것입니다. 직접SQLite 데이터베이스에 날짜 시간 값을 저장하는 최적의 방법 (Delphi)

  • 사용 REAL 데이터 유형 및 저장 델파이의 TDateTime으로 값 : SQLite는이 날짜 시간 값에 대한 명시 적 데이터 형식을 가지고 있지 않기 때문에

    는 몇 가지 옵션이 있습니다 빠른로드에 문자열에서 변환 없음; 날짜가 사람이 읽을 수 없으므로 SQLiteSpy와 같은 DB 관리자를 사용하여 날짜를 디버깅하는 것은 불가능합니다. SQLite 날짜 함수 (?)를 사용할 수 없습니다.

  • 은 간단한 문자열 형식을 사용합니다. YYYYMMDDHHNNSS : 변환이 필요하지만 CPU에서 비교적 쉽게 (분리자를 스캔 할 필요가 없음), 데이터는 사람이 읽을 수 있습니다. 아직도 SQLite 날짜 함수를 사용할 수 없습니다.

  • 다른 작업을 수행하십시오. 무엇을하는 것이 좋습니다?

나는 http://www.sqlite.org/lang_datefunc.html을 읽고 있지만, 율리우스 날짜에 공식적으로 프로그래밍 스쿨되고, 나는 매우 초점을 grok 수없는 아니,이 데이터 유형을 사용하는 것에 대한 언급이 없다합니다. 추가 전환이 필요한 이유는 무엇입니까? 이 값들을 많이 읽으므로 문자열과 TDateTime 사이의 추가 변환은 상당한 비용을 추가합니다.

+0

나는 또한 http://stackoverflow.com/questions/1933720/how-do-i-insert-datetime-value-into-a-sqlite-database를 보았지만 내 질문에 대한 대답은하지 않는다. 델파이의 TDateTime 값을 직접 삽입하는 것보다 ISO 문자열 형식 (및 관련 변환)을 선호하는 가장 좋은 방법은 무엇입니까? –

답변

8

SQLite에서 지원하는 문자열 형식 중 하나를 사용할 수 있습니다 (예 : .

YYYYMMDDHHNNSS처럼 쉽게 될 수 있습니다. 모든 숫자는 고정 길이이므로 분리 기호를 스캔 할 필요가 없으며 SQLite 날짜 기능 지원을받을 수 있습니다.

SQLite 날짜 기능 지원이 필요한 경우이 방법을 사용합니다.

그렇지 않은 경우 REAL 값을 사용하는 것이 좋습니다. 여전히 서로를 비교할 수 있지만 (높은 숫자는 나중에 있음) TDateTime으로 변환하지 않고 날짜와 시간을 별도로 (소수점 앞뒤 각각) 고려하십시오.

+0

저는이 ASCII 솔루션을 CSV 및 다른 데이터베이스와 함께 사용했습니다. 또한 SQLite 날짜 함수가 작동합니다. 윈윈 승리. –

5

하나의 절충안은 REAL 값을 사용하는 것이지만, Delphi의 DateTimeToJulianDate를 사용하여 줄리안 날짜로 저장하는 것이 좋습니다. 이렇게하면 독서 속도가 빠르며 컨버전스에서 손실되는 성능은 거의없고 델파이 밖에서도 의미있는 형식으로 유지됩니다.

+0

이전에 REAL 값을 사용했지만 DB의 값이 ** 사람이 읽을 수있는 ** 값이 아니라는 단점이 있습니다. 이는 SQL 도구를 사용하여 디버깅/분석 할 때 불편합니다. –

2

이 경우 나는 보통 Integer 데이터 형식을 사용하고 Unix 타임 스탬프 값을 비슷하게 저장합니다 (예 : 1-1-2000부터 eq # 초). TDateTime에서이 t /를 계산하는 것은/다이빙을 /로 86400으로 곱하고 '이후'에 상수를 추가하는 것과 같습니다.

정밀도가 필요한 경우 100ns 씩 증가하는 FILETIME (예 : int64)으로 DateTime을 사용할 수 있습니다. SysUtils에는 변환 루틴이 있으며 사용자의 타임 스탬프는 UTC로 저장됩니다.

0

우려가 데이터베이스 레벨, 당신은 예를 들어 두 개의 필드, 저장할 수에서 인간이 읽을 수있는 형식 인 경우 :

DELPHI_DATE REAL (DOUBLE, 가능하다면,하지만 나도 몰라 SQLite는이), 인덱스를 . 모든 프로그래밍 방식 쿼리 및 비교에이 필드를 사용해야합니다.

HUMAN_READABLE_DATE 'YYYY-MM-DD HH : MM : SS.SSS'형식의 Varchar (23)입니다. 어쩌면 색인이 생성됩니다 (실제로 필요한 경우). 대다수의 사람 입력 쿼리는이 필드를 포함해야하며 (다른 사람들이 말한 것처럼) SQLite 날짜 함수를 사용할 수 있습니다.

그것은 몇 가지 단점이 없습니다 : 외부 업데이트 한 경우

  • ,
  • 삽입 작업이 필요한 변환하기 때문에 좀 더 걸릴 것입니다, 값 사이에 자동 동기화를 데이터베이스에서

    • 공간 소비를하고 네트워크 트래픽이 증가하여 프로그램

    귀하의 특별한 요구에 적합한 경우 귀하에게 달려 있습니다.

  • 0

    나는이 대답은 DISqlite 라이브러리에 적용하면 모르겠지만 ...
    다음은 델파이 2010 팀 앤더슨의 sqlite3를 래퍼를 모두 사용하여 저를 위해 작동하는 것을 보여 일부 코드입니다.

    var 
    sDBFilePathString: string; 
    sl3tbl: TSqliteTable; 
    fsldb : TSQLiteDatabase; 
    FromdbDTField : TDateTime; 
    
    begin 
        ... 
        ... 
        fsldb := TSQLiteDatabase.Create(sDBFilePathString); 
        sl3tbl := fsldb.GetTable('SELECT * FROM someTable'); 
        FromdbDateTime := StrToFloat(sl3tbl.FieldAsString(sl3tbl.FieldIndex['myDateTime'])); 
        Showmessage('DT: ' + DateTimeToStr(FromdbDTField)); 
    end; 
    

    결과 :

    **DT: 10/10/2013 1:09:53 AM** 
    
    필드에서 데이터를 검색

    sSQL := 'INSERT INTO someTable(somefield1, somefield2, myDateTime)' + 
         ' VALUES ("baloney1", "baloney2","' + FloatToStr(Now) + '");'; 
    

    예 : 필드를 채울 수

    sSQL := 'CREATE TABLE [someTable] (' + 
          ' [somefield1] VARCHAR(12),' + 
          ' [somefield2] VARCHAR(12),' + 
          ' [myDateTime] DATETIME);'; 
    

    SQL :

    SQL 필드를 만들려면

    첫 번째 줄에서 언급 한 것처럼 -이 작업이 DISqlite 라이브러리와 작동하는지 모릅니다.하지만 처리 방법이 깨끗한 경우에는 잘 모릅니다. 나는 물건을 예쁘고 우아하게 만들기 위해 당신에게 맡깁니다.