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.