SQLite
 sql >> Base de Dados >  >> RDS >> SQLite

SQLite AUTOINCREMENT


Resumo :neste tutorial, você aprenderá sobre SQLite AUTOINCREMENT atributo de coluna e quando usá-lo em sua tabela.

Introdução ao SQLite ROWID tabela


Sempre que você cria uma tabela sem especificar o WITHOUT ROWID opção, você obtém uma coluna de incremento automático implícita chamada rowid . O rowid coluna armazena um inteiro assinado de 64 bits que identifica exclusivamente uma linha na tabela.

Vejamos o exemplo a seguir.

Primeiro, crie uma nova tabela chamada people que tem duas colunas:first_name, e last_name :
CREATE TABLE people (
   first_name TEXT NOT NULL,
   last_name TEXT NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Tente

Segundo, insira uma linha no people tabela usando o seguinte INSERT demonstração:
INSERT INTO people (first_name, last_name)
VALUES('John', 'Doe');Code language: SQL (Structured Query Language) (sql)

Tente

Terceiro, consulte os dados das people tabela usando o seguinte SELECT demonstração:
SELECT
   rowid,
   first_name,
   last_name
FROM
   people;Code language: SQL (Structured Query Language) (sql)

Tente

Como você pode ver claramente na saída, o SQLite cria implicitamente uma coluna chamada rowid e atribui automaticamente um valor inteiro sempre que você insere uma nova linha na tabela.

Observe que você também pode consultar o rowid coluna usando seus aliases:_rowid_ e oid .

Quando você cria uma tabela que tem uma INTEGER PRIMARY KEY coluna, esta coluna é o alias do rowid coluna.

A instrução a seguir elimina a tabela people e o recria. Desta vez, no entanto, adicionamos outra coluna chamada person_id cujo tipo de dados é INTEGER e a restrição de coluna é PRIMARY KEY :
DROP TABLE people;

CREATE TABLE people (
   person_id INTEGER PRIMARY KEY,
   first_name TEXT NOT NULL,
   last_name TEXT NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Tente

Nesse caso, o person_id coluna é na verdade o rowid coluna.

Como o SQLite atribui um valor inteiro ao rowid coluna?

Se você não especificar o rowid valor ou você usa um NULL valor quando você insere uma nova linha, o SQLite atribui automaticamente o próximo inteiro sequencial, que é um maior que o maior rowid na mesa. O rowid valor começa em 1.

O valor máximo do rowid coluna é 9,223,372,036,854,775,807 , que é muito grande. Se seus dados atingirem esse valor máximo e você tentar inserir uma nova linha, o SQLite encontrará um inteiro não utilizado e o usará. Se o SQLite não encontrar nenhum inteiro não utilizado, ele emitirá um SQLITE_FULL erro. Além disso, se você excluir algumas linhas e inserir uma nova linha, o SQLite tentará reutilizar o rowid valores das linhas excluídas.

Vamos fazer um teste nele.

Primeiro, insira uma linha com o valor máximo em people tabela.
INSERT INTO people (person_id,first_name,last_name)
VALUES(	9223372036854775807,'Johnathan','Smith');Code language: SQL (Structured Query Language) (sql)

Tente

Segundo, insira outra linha sem especificar um valor para o person_id coluna:
INSERT INTO people (first_name,last_name)
VALUES('William','Gate');Code language: SQL (Structured Query Language) (sql)

Tente

Conforme mostrado claramente na saída, a nova linha recebeu um inteiro não utilizado.

Considere outro exemplo.

Primeiro, crie uma nova tabela chamada t1 que tem uma coluna:
CREATE TABLE t1(c text);Code language: SQL (Structured Query Language) (sql)

Segundo, insira algumas linhas no t1 tabela:
INSERT INTO t1(c) VALUES('A');
INSERT INTO t1(c) values('B');
INSERT INTO t1(c) values('C');
INSERT INTO t1(c) values('D');
Code language: SQL (Structured Query Language) (sql)

Terceiro, consulte os dados do t1 tabela:
SELECT rowid, c FROM t1;Code language: SQL (Structured Query Language) (sql)

Quarto, exclua todas as linhas do t1 tabela:
DELETE FROM t1;Code language: SQL (Structured Query Language) (sql)

Quinto, insira algumas linhas no t1 tabela:
INSERT INTO t1(c) values('E');
INSERT INTO t1(c) values('F');
INSERT INTO t1(c) values('G');Code language: SQL (Structured Query Language) (sql)

Por fim, consulte os dados do t1 tabela:
SELECT rowid, c FROM t1;
Code language: SQL (Structured Query Language) (sql)

Como você pode ver, o rowid 1, 2 e 3 foram reutilizados para as novas linhas.

SQLite AUTOINCREMENT atributo de coluna


SQLite recomenda que você não use AUTOINCREMENT atributo porque:

O AUTOINCREMENT A palavra-chave impõe CPU extra, memória, espaço em disco e sobrecarga de E/S em disco e deve ser evitada se não for estritamente necessária. Geralmente não é necessário.

Além disso, a maneira como o SQLite atribui um valor para o AUTOINCREMENT coluna ligeiramente diferente da forma como faz para o rowid coluna.

Considere o exemplo a seguir.

Primeiro, solte e recrie as people tabela. Desta vez, usamos AUTOINCREMENT coluna de atributo:
DROP TABLE people;

CREATE TABLE people (
   person_id INTEGER PRIMARY KEY AUTOINCREMENT,
   first_name text NOT NULL,
   last_name text NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Tente

Segundo, insira uma linha com o máximo de rowid valor para as people tabela.
INSERT INTO people (person_id,first_name,last_name)
VALUES(9223372036854775807,'Johnathan','Smith');Code language: SQL (Structured Query Language) (sql)

Tente

Terceiro, insira outra linha em people tabela.
INSERT INTO people (first_name,last_name)
VALUES('John','Smith');Code language: SQL (Structured Query Language) (sql)

Tente

Desta vez, o SQLite emitiu uma mensagem de erro porque o person_id coluna não reutilizou o número como um rowid coluna.
[Err] 13 - database or disk is fullCode language: SQL (Structured Query Language) (sql)

Quando você deve usar o AUTOINCREMENT atributo de coluna?

O objetivo principal de usar o atributo AUTOINCREMENT é impedir que o SQLite reutilize um valor que não foi usado ou um valor da linha excluída anteriormente.

Se você não tiver nenhum requisito como esse, não use o AUTOINCREMENT atributo na chave primária.

Neste tutorial, você aprendeu como SQLite AUTOINCREMENT O atributo funciona e como ele influencia a maneira como o SQLite atribui valores à coluna de chave primária.