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.