Nesta página, descrevemos como gerenciar relações de chave externa no banco de dados.
Uma chave externa é uma coluna compartilhada entre tabelas para estabelecer um link entre dados relacionados. Quando você usa uma chave externa, o Spanner garante que essa relação seja mantida.
O diagrama a seguir mostra um esquema de banco de dados básico em que os dados de uma tabela têm uma relação com os dados de outra.
Figura 1. Diagrama de um esquema de banco de dados de processamento de pedidos
Há três tabelas no esquema mostrado na Figura 1:
- A tabela
Customersregistra os nomes de cada cliente. - As tabelas
Ordersregistram todos os pedidos feitos. - A tabela
Productsarmazena as informações de cada produto.
Há duas relações de chave externa entre essas tabelas:
Um relacionamento de chave externa é definido entre a tabela
Orderse a tabelaCustomerspara garantir que um pedido não seja criado a menos que haja um cliente correspondente.Uma relação de chave externa entre a tabela
Orderse a tabelaProductsgarante que não seja possível criar um pedido para um produto que não existe.
Usando o esquema anterior como exemplo, este tópico discute as instruções da linguagem de definição de dados (DDL) CONSTRAINT que podem ser usadas para gerenciar relações entre tabelas em um banco de dados.
Por padrão, todas as chaves estrangeiras no Spanner são chaves estrangeiras aplicadas, que aplicam a integridade referencial. No Spanner, você também pode usar chaves estrangeiras informativas, que não validam nem aplicam a integridade referencial. Para mais informações, consulte Comparação de chaves externas e Escolher qual tipo de chave externa usar. Quando não especificado, as chaves estrangeiras nos exemplos desta página são chaves estrangeiras aplicadas.
Adicionar uma chave externa a uma nova tabela
Suponha que você tenha criado uma tabela Customers no banco de dados básico de pedidos de produtos. Agora, você precisa de uma tabela Orders para armazenar informações sobre os pedidos
que os clientes fazem. Para garantir que todos os pedidos sejam válidos, não permita que o sistema insira linhas na tabela Orders, a menos que haja também uma entrada correspondente na tabela Customers. Portanto, você precisa de uma chave externa aplicada para estabelecer uma relação entre as duas tabelas. Uma opção é adicionar uma coluna CustomerID à nova tabela e usá-la como chave externa para criar uma relação com a coluna CustomerID na tabela Customers.
Ao criar uma tabela com uma chave externa, você usa REFERENCE para estabelecer
uma relação com outra tabela. A tabela que contém a instrução REFERENCE é chamada de tabela de referência. A tabela nomeada na instrução REFERENCE é a tabela referenciada. A coluna nomeada na instrução REFERENCE é chamada de coluna de referência.
O exemplo a seguir mostra como usar a instrução DDL CREATE TABLE para
criar a tabela Orders com uma restrição de chave externa que faz referência a
CustomerID na tabela Customers.
GoogleSQL
CREATE TABLE Orders (
OrderID INT64 NOT NULL,
CustomerID INT64 NOT NULL,
Quantity INT64 NOT NULL,
ProductID INT64 NOT NULL,
CONSTRAINT FK_CustomerOrder FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
) PRIMARY KEY (OrderID);
PostgreSQL
CREATE TABLE Orders (
OrderID BIGINT NOT NULL,
CustomerID BIGINT NOT NULL,
Quantity BIGINT NOT NULL,
ProductID BIGINT NOT NULL,
CONSTRAINT FK_CustomerOrder FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID),
PRIMARY KEY (OrderID)
);
A instrução anterior contém uma cláusula CONSTRAINT com as seguintes características:
O uso da sintaxe
CONSTRAINTpara nomear uma restrição, facilitando a remoção da tabela usando o nome escolhido.A restrição tem o nome
FK_CustomerOrder. Os nomes das restrições têm escopo no esquema e precisam ser exclusivos dentro dele.A tabela
Orders, em que você define a restrição, é a tabela de referência. A tabelaCustomersé a tabela referenciada.A coluna de referência na tabela de referência é
CustomerID. Ela faz referência ao campoCustomerIDna tabelaCustomers. Se alguém tentar inserir uma linha emOrderscom umCustomerIDque não existe emCustomers, a inserção vai falhar.
O exemplo a seguir mostra uma instrução de criação de tabela alternativa. Aqui, a restrição de chave externa é definida sem um nome. Quando você usa essa sintaxe, o Spanner gera um nome para você. Para descobrir os nomes de todas as chaves externas, consulte Exibir propriedades de uma relação de chave externa.
GoogleSQL
CREATE TABLE Orders (
OrderID INT64 NOT NULL,
CustomerID INT64 NOT NULL,
ProductID INT64 NOT NULL,
FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
) PRIMARY KEY (OrderID);
PostgreSQL
CREATE TABLE Orders (
OrderID BIGINT NOT NULL,
CustomerID BIGINT NOT NULL,
Quantity BIGINT NOT NULL,
ProductID BIGINT NOT NULL,
FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID),
PRIMARY KEY (OrderID)
);
Adicionar uma chave estrangeira a uma tabela atual
Você também quer garantir que os clientes só possam pedir produtos que existem. Se a tabela tiver restrições, remova todas elas. No Spanner, todas as restrições aplicadas em uma tabela precisam ser implementadas ao mesmo tempo em uma única instrução DDL em lote.
Se a tabela não tiver restrições, use a instrução DDL ALTER TABLE para adicionar uma restrição de chave externa aplicada à tabela Orders, conforme mostrado no exemplo a seguir:
ALTER TABLE Orders
ADD CONSTRAINT DB_ProductOrder FOREIGN KEY (ProductID) REFERENCES Products (ProductID);
A coluna de referência em Orders é ProductID e faz referência à coluna ProductID em Products. Se você estiver bem com o Spanner
nomeando essas restrições para você, use a seguinte sintaxe:
ALTER TABLE Orders
ADD FOREIGN KEY (ProductID) REFERENCES Products (ProductID);
Adicionar uma chave externa com uma ação de exclusão a uma nova tabela
Lembre-se do exemplo anterior em que você tem uma tabela Customers em um banco de dados de pedidos de produtos que precisa de uma tabela Orders. Você quer adicionar uma restrição de chave externa que faça referência à tabela Customers. No entanto, você quer garantir que, quando excluir um registro de cliente no futuro, o Spanner também exclua todos os pedidos desse cliente. Nesse caso, use a ação ON
DELETE CASCADE com a restrição de chave externa.
A instrução DDL CREATE TABLE a seguir para a tabela Orders inclui a restrição de chave externa que faz referência à tabela Customers com uma ação ON DELETE
CASCADE.
GoogleSQL
CREATE TABLE Orders (
OrderID INT64 NOT NULL,
CustomerID INT64 NOT NULL,
Quantity INT64 NOT NULL,
ProductID INT64 NOT NULL,
CONSTRAINT FK_CustomerOrder FOREIGN KEY (CustomerID)
REFERENCES Customers (CustomerID) ON DELETE CASCADE
) PRIMARY KEY (OrderID);
PostgreSQL
CREATE TABLE Orders (
OrderID BIGINT NOT NULL,
CustomerID BIGINT NOT NULL,
Quantity BIGINT NOT NULL,
ProductID BIGINT NOT NULL,
FOREIGN KEY (CustomerID)
REFERENCES Customers (CustomerID) ON DELETE CASCADE,
PRIMARY KEY (OrderID)
);
A instrução anterior contém uma restrição de chave externa com uma cláusula ON DELETE
CASCADE. A coluna CustomerID é uma chave externa que faz referência ao campo CustomerID na tabela Customers. Isso significa que cada valor CustomerID na tabela Orders também precisa existir na tabela Customers. Se alguém tentar excluir uma linha da tabela Customers, todas as linhas da tabela Orders que fazem referência ao valor CustomerID excluído também serão excluídas na mesma transação.