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

Chave estrangeira SQLite


Resumo :neste tutorial, você aprenderá como usar a restrição de chave estrangeira SQLite para impor os relacionamentos entre tabelas relacionadas.

Suporte a restrição de chave estrangeira SQLite


SQLite tem suportado restrição de chave estrangeira desde a versão 3.6.19. A biblioteca SQLite também deve ser compilada sem SQLITE_OMIT_FOREIGN_KEY nem SQLITE_OMIT_TRIGGER.

Para verificar se sua versão atual do SQLite suporta restrições de chave estrangeira ou não, você usa o seguinte comando.
PRAGMA foreign_keys;Code language: SQL (Structured Query Language) (sql)

O comando retorna um valor inteiro:1:habilitado, 0:desabilitado. Se o comando não retornar nada, significa que sua versão do SQLite não suporta restrições de chave estrangeira.

Se a biblioteca SQLite for compilada com suporte a restrição de chave estrangeira, o aplicativo poderá usar o PRAGMA foreign_keys comando para habilitar ou desabilitar restrições de chave estrangeira em tempo de execução.

Para desabilitar a restrição de chave estrangeira:
PRAGMA foreign_keys = OFF;Code language: SQL (Structured Query Language) (sql)

Para habilitar a restrição de chave estrangeira:
PRAGMA foreign_keys = ON;Code language: SQL (Structured Query Language) (sql)

Introdução às restrições de chave estrangeira SQLite


Vamos começar com duas tabelas:suppliers e supplier_groups :
CREATE TABLE suppliers (
	supplier_id integer PRIMARY KEY,
	supplier_name text NOT NULL,
	group_id integer NOT NULL
);

CREATE TABLE supplier_groups (
	group_id integer PRIMARY KEY,
	group_name text NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Assumindo que cada fornecedor pertence a um e apenas um grupo de fornecedores. E cada grupo de fornecedores pode ter zero ou muitos fornecedores. A relação entre supplier_groups e suppliers tabelas é um-para-muitos. Em outras palavras, para cada linha nos suppliers tabela, há uma linha correspondente em supplier_groups tabela.

Atualmente, não há como impedir que você adicione uma linha aos suppliers tabela sem uma linha correspondente no supplier_groups tabela.

Além disso, você pode remover uma linha nos supplier_groups tabela sem excluir ou atualizar as linhas correspondentes nos suppliers tabela. Isso pode deixar linhas órfãs nos suppliers tabela.

Para impor a relação entre as linhas nos suppliers e supplier_groups tabela, você usa as restrições de chave estrangeira .

Para adicionar a restrição de chave estrangeira aos suppliers tabela, você altera a definição do CREATE TABLE declaração acima da seguinte forma:
DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER NOT NULL,
    FOREIGN KEY (group_id)
       REFERENCES supplier_groups (group_id) 
);
Code language: SQL (Structured Query Language) (sql)

Os supplier_groups tabela é chamada de tabela pai , que é a tabela à qual uma chave estrangeira faz referência. Os suppliers A tabela é conhecida como tabela filha , que é a tabela à qual a restrição de chave estrangeira se aplica.

O group_id coluna em supplier_groups tabela é chamada de chave pai , que é uma coluna ou um conjunto de colunas na tabela pai que a restrição de chave estrangeira faz referência. Normalmente, a chave pai é a chave primária da tabela pai.

O group_id coluna nos suppliers tabela é chamada de chave filho. Geralmente, a chave filha faz referência à chave primária da tabela pai.

Exemplo de restrição de chave estrangeira SQLite


Primeiro, insira três linhas nos supplier_groups tabela.
INSERT INTO supplier_groups (group_name)
VALUES
   ('Domestic'),
   ('Global'),
   ('One-Time');Code language: SQL (Structured Query Language) (sql)

Segundo, insira um novo fornecedor em suppliers tabela com o grupo de fornecedores que existe em supplier_groups tabela.
INSERT INTO suppliers (supplier_name, group_id)
VALUES ('HP', 2);Code language: SQL (Structured Query Language) (sql)

Esta declaração funciona perfeitamente bem.

Terceiro, tente inserir um novo fornecedor nos suppliers tabela com o grupo de fornecedores que não existe em supplier_groups tabela.
INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Inc.', 4);Code language: SQL (Structured Query Language) (sql)

O SQLite verificou a restrição de chave estrangeira, rejeitou a alteração e emitiu a seguinte mensagem de erro:
[SQLITE_CONSTRAINT]  Abort due to constraint violation (FOREIGN KEY constraint failed)Code language: CSS (css)

Ações de restrição de chave estrangeira do SQLite


O que aconteceria se você excluísse uma linha nos supplier_groups tabela? Todas as linhas correspondentes nos suppliers tabela também são excluídos? As mesmas perguntas para a operação de atualização.

Para especificar como a restrição de chave estrangeira se comporta sempre que a chave pai é excluída ou atualizada, você usa o comando ON DELETE ou ON UPDATE ação da seguinte forma:
FOREIGN KEY (foreign_key_columns)
   REFERENCES parent_table(parent_key_columns)
      ON UPDATE action 
      ON DELETE action;Code language: SQL (Structured Query Language) (sql)

SQLite suporta as seguintes ações:
  • SET NULL
  • DEFINIR PADRÃO
  • RESTRITAR
  • SEM AÇÃO
  • CASCA

Na prática, os valores da chave primária na tabela pai não mudam, portanto, as regras de atualização são menos importantes. A regra mais importante é o DELETE regra que especifica a ação quando a chave pai é excluída.

Examinaremos cada ação pelo exemplo a seguir

SET NULL


Quando a chave pai é alterada, excluída ou atualizada, as chaves filhas correspondentes de todas as linhas da tabela filha são definidas como NULL.

Primeiro, solte e crie a tabela suppliers usando o SET NULL ação para o group_id chave estrangeira:
DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE SET NULL
       ON DELETE SET NULL
);
Code language: SQL (Structured Query Language) (sql)

Segundo, insira algumas linhas nos suppliers tabela:
INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 3);

INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Corp', 3);Code language: SQL (Structured Query Language) (sql)

Terceiro, exclua o ID do grupo de fornecedores 3 de supplier_groups tabela:
DELETE FROM supplier_groups 
WHERE group_id = 3;Code language: SQL (Structured Query Language) (sql)

Quarto, consultar dados dos suppliers tabela.
SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

Os valores do group_id coluna das linhas correspondentes em suppliers tabela definida como NULL.

DEFINIR PADRÃO


O SET DEFAULT A ação define o valor da chave estrangeira para o valor padrão especificado na definição da coluna ao criar a tabela.

Como os valores na coluna group_id o padrão é NULL, se você excluir uma linha dos supplier_groups tabela, os valores do group_id será definido como NULL.

Depois de atribuir o valor padrão, a restrição de chave estrangeira entra em ação e carrega a verificação.

RESTRITO


O RESTRICT A ação não permite alterar ou excluir valores na chave pai da tabela pai.

Primeiro, solte e crie os suppliers tabela com o RESTRICT ação na chave estrangeira group_id :
DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE RESTRICT
       ON DELETE RESTRICT
);Code language: SQL (Structured Query Language) (sql)

Segundo, insira uma linha na tabela suppliers com o group_id 1.
INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);Code language: SQL (Structured Query Language) (sql)

Terceiro, exclua o grupo de fornecedores com id 1 dos supplier_groups tabela:
DELETE FROM supplier_groups 
WHERE group_id = 1;Code language: SQL (Structured Query Language) (sql)

SQLite emitiu o seguinte erro:
[SQLITE_CONSTRAINT]  Abort due to constraint violation (FOREIGN KEY constraint failed)Code language: CSS (css)

Para corrigi-lo, você deve primeiro excluir todas as linhas dos suppliers tabela que tem group_id 1:
DELETE FROM suppliers 
WHERE group_id =1;Code language: SQL (Structured Query Language) (sql)

Em seguida, você pode excluir o grupo de fornecedores 1 do supplier_groups tabela:
DELETE FROM supplier_groups 
WHERE group_id = 1;Code language: SQL (Structured Query Language) (sql)

SEM AÇÃO


O NO ACTION não significa ignorar a restrição de chave estrangeira. Tem o efeito semelhante ao RESTRICT .

CASCA


A CASCADE A ação propaga as alterações da tabela pai para a tabela filha quando você atualiza ou exclui a chave pai.

Primeiro, insira o supplier grupos em supplier_groups tabela:
INSERT INTO supplier_groups (group_name)
VALUES
   ('Domestic'),
   ('Global'),
   ('One-Time');Code language: SQL (Structured Query Language) (sql)

Segundo, solte e crie a tabela suppliers com o CASCADE ação na chave estrangeira group_id :
DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE CASCADE
       ON DELETE CASCADE
);Code language: SQL (Structured Query Language) (sql)

Terceiro, insira alguns fornecedores na tabela suppliers :
INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);

INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Corp', 2);Code language: SQL (Structured Query Language) (sql)

Quarto, atualize group_id do Domestic grupo de fornecedores para 100:
UPDATE supplier_groups
SET group_id = 100
WHERE group_name = 'Domestic';Code language: SQL (Structured Query Language) (sql)

Quinto, consulte os dados da tabela suppliers :
SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

Como você pode ver o valor no group_id coluna da XYZ Corp na tabela suppliers alterado de 1 para 100 quando atualizamos o group_id nos suplier_groups tabela. Este é o resultado de ON UPDATE CASCADE açao.

Sexto, exclua o ID do grupo de fornecedores 2 dos supplier_groups tabela:
DELETE FROM supplier_groups 
WHERE group_id = 2;Code language: SQL (Structured Query Language) (sql)

Sétimo, consultar dados da tabela suppliers :
SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

O ID do fornecedor 2 cujo group_id is 2 foi excluído quando o ID do grupo de fornecedores 2 foi removido dos supplier_groups tabela. Este é o efeito do ON DELETE CASCADE açao.

Neste tutorial, você aprendeu sobre a restrição de chave estrangeira do SQLite e como usá-la para impor o relacionamento entre tabelas relacionadas.