Pergunta

Eu tenho uma pergunta puramente acadêmico sobre bancos de dados SQLite.

Eu estou usando SQLite.net usar um banco de dados no meu projeto WinForm, e como eu estava a criação de uma nova tabela, eu comecei a pensar sobre os valores máximos de uma coluna de identificação.

Eu uso o IDENTITY para minha coluna [ID], que de acordo com a SQLite.net DataType mapeamentos , é equivalente a DbType.Int64. Eu normalmente começo minhas colunas ID em zero (com essa linha como um registro de teste) e ter o banco de dados de auto-incremento.

O valor máximo (Int64.MaxValue) é 9.223.372.036.854.775.807. Para os meus propósitos, eu nunca sequer arranhar a superfície em alcançar esse máximo, mas o que acontece em um banco de dados que faz? Ao tentar ler sobre isso, descobri que DB2 aparentemente "wraps" o valor em torno ao valor negativo (-9,223,372,036,854,775,807) e incrementos de lá, até que o banco de dados não pode inserir linhas porque a coluna ID tem de ser único.

É isso que acontece no SQLite e / ou outros motores de banco de dados?

Foi útil?

Solução

Eu duvido que alguém sabe ao certo, porque se um milhão de linhas por segundo estavam sendo inserido, levaria cerca de 292.471 anos para atingir o ponto de wrap-around-risco - e bases de dados foram em torno de uma pequena fração desse tempo (na verdade, isso tem Homo Sapiens; -).

Outras dicas

A identidade não é realmente a maneira correta de auto-incremento no SQLite. Isso exigirá que você faça o incremento na camada de aplicativo. No shell SQLite, tente:

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

Você vai ver que id é simplesmente nulo. SQLite não dá qualquer significado especial para a identidade, por isso é basicamente uma coluna comum (sem tipo).

Por outro lado, se você fizer isso:

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

será 1 como eu acho que você espera.

Note que há também um INTEGER PRIMARY KEY AUTOINCREMENT. A diferença básica é que AUTOINCREMENT garante chaves nunca são reutilizados. Então, se você remover John, 1 nunca será reutilizado como um id. De qualquer forma, se você usar CHAVE PRIMÁRIA (com AUTOINCREMENT opcional) e correr para fora de ids, SQLite é suposto a falhar com SQLITE_FULL, não enrole.

usando a identidade, você aberto a probabilidade (provavelmente irrelevante) que a sua aplicativo será incorretamente envolver em torno de se o db foram sempre cheia. Isso é perfeitamente possível, porque as colunas de identidade em SQLite pode conter qualquer valor (incluindo ints negativos). Mais uma vez, tente:

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

Ambos esses são completamente válido. Eles seria válida para Baz também. No entanto , com baz você pode evitar manualmente especificando id. Dessa forma, nunca haverá lixo em sua coluna id.

A documentação em http://www.sqlite.org/autoinc.html indica que o ROWID vai tentar encontrar um valor não utilizado via randomização, uma vez que atingiu seu número máximo.

Para AUTOINCREMENT ele falhará com SQLITE_FULL em todas as tentativas de inserir esta tabela, uma vez que houve um valor máximo na tabela:

Se a tabela já declarou uma linha com o maior ROWID possível, então novas pastilhas não são permitidos e qualquer tentativa de inserir uma nova linha irá falhar com um erro SQLITE_FULL.

Isto é necessário, como as garantias AUTOINCREMENT que o ID é monótona crescente.

Eu não posso falar a qualquer lógica de implementação específica DB2, mas o "envolvente" O comportamento que você descreve é ??padrão para os números que implementam assinatura via dois complemento .

Quanto ao que realmente iria acontecer, que é completamente no ar a respeito de como o banco de dados iria lidar com isso. A questão surge no momento de realmente criar o id que é muito grande para o campo, como é improvável que o motor usa internamente um tipo de dados de mais de 64 bits. Nesse ponto, acho que é de ninguém ... a linguagem interna utilizada para desenvolver o motor poderia vomitar, o número poderia silenciosamente envolver em torno e apenas causa uma violação de chave primária (assumindo que um ID conflitantes existia), o mundo poderia chegar a um acabar devido ao seu excesso, etc.

Mas pragmaticamente, Alex está correto. O limite teórico para o número de linhas envolvidas aqui (assumindo que é um one-id-por linha e não qualquer tipo de identidade trapaceiro inserção travessuras) seria basicamente tornar o moot situação, como no momento em que você pode conseguir introduzir esta quantidade de linhas em mesmo uma taxa de inserção estupenda todos nós vamos de qualquer maneira morto, por isso não importa:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top