2009-06-13 3 views
11

SQLite 데이터베이스에 대한 순수한 학문적 질문이 있습니다.SQLite DB의 식별 열 최대 값

SQLite.net을 사용하여 WinForm 프로젝트에서 데이터베이스를 사용하고 있으며 새 테이블을 설정할 때 ID 열의 최대 값을 고려해야합니다.

나는 SQLite.net DataType Mappings에 따라 DbType.Int64에 해당하는 내 [ID] 열에 IDENTITY을 사용합니다. 나는 일반적으로 ID 열을 0으로 시작하고 (테스트 레코드로 해당 행 포함) 데이터베이스를 자동 증가시킵니다.

최대 값 (Int64.MaxValue)은 9,223,372,036854775807입니다. 내 목적을 위해, 나는 그 최대에 도달 할 때 표면을 긁지 않을 것이다. 그러나 데이터베이스에서 어떤 일이 일어나는가? 이 글을 읽으려는 동안, DB2는 ID 열이 고유해야하기 때문에 데이터베이스가 행을 삽입 할 수 없을 때까지 DB2가 음수 값 (-9,223,372,036854775807)을 중심으로 값을 분명히 "랩"하고 거기에서 증가한다는 것을 발견했습니다.

SQLite 및/또는 다른 데이터베이스 엔진에서 이러한 현상이 발생합니까?

+0

SQLite의 공식 문서는 http://www.sqlite.org/autoinc.html에서 다루고 있습니다. 아래에서 좀 더 자세한 답변을 추가했습니다. –

답변

24

초당 백만 개의 행이 삽입되는 경우 랩 어라운드 위험 지점에 도달하는 데 약 292,471 년이 걸릴 것이기 때문에 누구나 확실히 알고 있을지는 의심 스럽습니다. 시간 (실제로, 그렇게 그렇게 Homo Sapiens; -).

+1

나는 항상 문제에 매달릴 때 이런 종류의 온 전성 체크를 좋아한다. : -/ – tgray

+3

거의 "작은 조각". Wikipedia http://en.wikipedia.org/wiki/Homo_sapiens에 따르면 Homo Sapiens는 아마도 그 기간의 약 2/3에 해당합니다. –

1

특정 DB2 구현 로직에 대해서는 말할 수 없지만 설명하는 "랩 어라운드"동작은 two's complement을 통해 서명을 구현하는 숫자의 표준입니다.

사실상 일어날 일은 데이터베이스가 어떻게 처리 할 것인가에 관한 것입니다. 이 문제는 엔진이 내부적으로 64 비트 이상의 데이터 유형을 사용하는 것 같지 않기 때문에 현장에서 너무 큰 ID를 실제로 생성하는 시점에서 발생합니다. 이 시점에서 엔진을 개발하는 데 사용 된 내부 언어가 갑자기 튕겨 나올 수 있습니다.이 번호는 자동으로 줄 바꿈되어 기본 키 위반 (충돌 ID가 존재한다고 가정)을 유발할 수 있습니다. 귀하의 넘침으로 인해 끝납니다.

그러나 실용 주의적으로 Alex는 맞습니다. 여기에 관련된 행의 수에 대한 이론적 인 제한은 (한 행당 하나의 ID라고 가정하고 치타 신원 삽입 헛소리가 아니라는 가정하에) 근본적으로 상황을 논박의 대상으로 만듭니다. 어쨌든 엄청난 삽입 율이라도 상관 없으므로 중요하지 않습니다.

7

IDENTITY는 실제로 SQLite에서 자동 증가를위한 적절한 방법이 아닙니다. 그렇게하려면 앱 레이어에서 증가시켜야합니다. SQLite 셸에서 다음을 시도하십시오.

create table bar (id IDENTITY, name VARCHAR); 
insert into bar (name) values ("John"); 
select * from bar; 

id가 단순히 null임을 알 수 있습니다. SQLite는 IDENTITY에 특별한 의미를 부여하지 않으므로 기본적으로 일반 (유형이 지정되지 않은) 열입니다. 난 당신이 기대하는 생각으로

create table baz (id INTEGER PRIMARY KEY, name VARCHAR); 
insert into baz (name) values ("John"); 
select * from baz; 

는 1이됩니다 : 당신이 경우에 다른 한편으로

.

there is also INTEGER PRIMARY KEY AUTOINCREMENT. 기본적인 차이점은 AUTOINCREMENT가 키가 결코 재사용되지 않는다는 것입니다. 따라서 John을 삭제하면 1은 ID로 재사용되지 않습니다.어느 쪽이든, (선택적 AUTOINCREMENT와 함께) PRIMARY KEY를 사용하고 id가 부족하면 SQLite는 SQLITE_FULL로 실패하고 랩되지 않습니다.

IDENTITY를 사용하면 응용 프로그램이 DB가 가득 찬 경우 잘못 포장 될 가능성이 있습니다 (아마도 관련성이 없음). SQLite의 IDENTITY 열은 음수를 포함하여 모든 값을 포함 할 수 있기 때문에 가능합니다. 다시 시도해보십시오.

insert into bar VALUES ("What the hell", "Bill"); 
insert into bar VALUES (-9, "Mary"); 

두 가지 모두 유효합니다. 그들은 baz에도 유효합니다. 과 같이 baz를 사용하면 수동으로 id를 지정할 필요가 없습니다. 그렇게하면 아이디 열에 정크가 절대 없을 것입니다.

+1

흥미로운 정보, 나는 그것을 살펴 봐야 할 것입니다. 지금은 Visual Studio 2008 데이터베이스 디자이너로 데이터베이스를 만듭니다. 항상 루프에 대해 나를 던진 것은 sqlite 자체가 typless라는 것입니다. 그래서 저는 보통 데이터 유형을 알아 내기 위해 링크 된 페이지를 사용하고, 첫 번째 열을 Name : ID, Type : 정수로 설정하고 nulls를 허용하지 않습니다. 열을 기본 키로 설정하십시오. 저는 실제로 SQLite 셸에 익숙하지 않습니다. 정보 주셔서 감사합니다! –

3

http://www.sqlite.org/autoinc.html의 설명서는 ROWID이 최대 숫자에 도달하면 사용하지 않은 값을 임의 화를 통해 찾으려고한다는 것을 나타냅니다. 테이블이 이전에 가장 큰 가능한 ROWID있는 행을 개최했다 경우

:

AUTOINCREMENT의 경우는이 테이블에 삽입하는 모든 시도에 SQLITE_FULL 실패합니다, 한 번 테이블의 최대 값이 있었다 새 INSERT는 허용되지 않으며 새 행을 삽입하려는 시도는 SQLITE_FULL 오류와 함께 실패합니다.

AUTOINCREMENT은 ID가 단조롭게 증가한다는 것을 보장하므로이 작업이 필요합니다.