Esta página se ha traducido con Cloud Translation API.
Switch to English

Claves externas

En este tema, se describen las claves externas en Cloud Spanner y cómo se pueden usar para aplicar la integridad referencial en tu solución de base de datos.

Introducción

Las claves externas te permiten definir relaciones entre tablas. Cloud Spanner garantiza que se mantenga la integridad de los datos de estas relaciones.

Imagina que eres el desarrollador líder de una empresa de comercio electrónico. Estás diseñando una base de datos para procesar los pedidos de los clientes. La base de datos debe almacenar información sobre cada pedido, cliente y producto. En la Figura 1, se ilustra la estructura básica de la base de datos para la aplicación.

Estructura básica de la base de datos de procesamiento de pedidos

Figura 1. Diagrama de una base de datos de procesamiento de pedidos

Define una tabla Customers en la que se almacene la información del cliente, una tabla Orders para llevar a cabo un seguimiento de todos los pedidos realizados y una tabla Products en la que se almacene la información sobre cada producto que los clientes pueden pedir.

En la figura 1, también se muestran vínculos entre las tablas que se asignan a las siguientes relaciones del mundo real:

  • Un cliente realizó un pedido.

  • Se realizó un pedido de un producto.

Debes decidir que tu base de datos aplique las siguientes reglas para garantizar que los pedidos en nuestro sistema sean válidos.

  • No puedes crear un pedido para un cliente que no existe.

  • Un cliente no puede realizar un pedido de un producto que no ofreces.

Cuando se aplican estas reglas, o restricciones, se mantiene la integridad referencial de los datos. Si una base de datos mantiene la integridad referencial, fallarán todos los intentos de agregar datos no válidos, lo que generaría vínculos o referencias no válidos entre datos. La integridad referencial evita los errores del usuario. Cloud Spanner aplica la integridad referencial mediante claves externas.

Aplicación de la integridad referencial con claves externas

Veamos nuevamente nuestro ejemplo de procesamiento de pedidos, con más detalles agregados al diseño, como se muestra en la Figura 2.

Esquema de la base de datos con claves externas

Figura 2. Diagrama de nuestro esquema de base de datos con claves externas

El diseño ahora muestra los nombres y los tipos de columna en cada tabla. La tabla Orders también define dos relaciones de clave externa. FK_CustomerOrder garantiza que todas las filas de Orders tengan un CustomerID válido. La clave externa FK_ProductOrder garantiza que todos los valores ProductID de la tabla Orders sean válidos. La siguiente tabla asigna estas restricciones a las reglas del mundo real que queremos aplicar.

Nombre de la clave externa Restricción Descripción del mundo real
FK_CustomerOrder Asegúrate de que todas las filas de Orders tengan un CustomerID válido Un cliente válido realizó un pedido.
FK_ProductOrder Asegúrate de que todas las filas de Orders tengan un ProductID válido Se realizó un pedido de un producto válido.

Cloud Spanner genera una falla en cualquier transacción que intente insertar o actualizar una fila en la tabla Orders que tenga un CustomerID o ProductID que no se pueda encontrar en las tablas Customers y Products. También genera fallas en las transacciones que intentan actualizar o borrar filas en las tablas Customers y Products, lo que invalidaría los ID de la tabla Orders. Para obtener más detalles sobre cómo Cloud Spanner valida las restricciones, consulta la Validación de la restricción de transacciones a continuación.

Define claves externas

Las claves externas se crean y quitan de tu base de datos de Cloud Spanner con DDL. Las claves externas se agregan a una nueva tabla con la instrucción CREATE TABLE. Del mismo modo, se puede agregar o quitar una clave externa de una tabla existente con la instrucción ALTER TABLE. El siguiente es un ejemplo de cómo crear una tabla nueva con una clave externa.

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);

Para obtener más ejemplos sobre cómo crear y administrar claves externas, consulta Crea y administra relaciones de claves externas.

La siguiente es una lista de características de claves externas en Cloud Spanner.

  • La tabla que define la clave externa es la tabla referente y las columnas de clave externa son las columnas referentes.

  • La clave externa hace referencia a las columnas a las que se hace referencia de la tabla a la que se hace referencia.

  • Como en el ejemplo anterior, puedes nombrar cada restricción de clave externa. Si no especificas un nombre, Cloud Spanner genera un nombre de forma automática. El nombre generado se puede consultar desde INFORMATION_SCHEMA de Cloud Spanner. Los nombres de las restricciones se aplican al esquema, junto con los nombres de las tablas y los índices, y deben ser únicos dentro del esquema.

  • La cantidad de columnas de referencia y a las que se hace referencia debe ser la misma. El orden es importante. La primera columna de referencia hace referencia a la primera columna a la que se hace referencia, la segunda, a la segundo, etcétera.

  • Una columna de referencia y su contraparte referida deben ser del mismo tipo. Las columnas también deben poder indexarse.

  • Las claves externas no se pueden crear en columnas con la opción allow_commit_timestamp=true.

  • No se admiten las columnas de arreglos.

  • Las columnas NUMERIC no son compatibles.

  • Una clave externa puede hacer referencia a columnas de la misma tabla (una clave externa de “autoreferencia”). Un ejemplo es una tabla de empleados con una columna de ManagerId que hace referencia a la columna EmployeeId de la tabla.

  • Las claves externas también pueden formar relaciones circulares entre tablas, en las que dos tablas hacen referencia una a otra directa o indirectamente. La tabla a la que se hace referencia debe existir antes de crear una clave externa, por lo que se debe agregar al menos una de las claves externas mediante la declaración ALTER TABLE.

  • Las claves a las que se hace referencia deben ser únicas. Cloud Spanner usa el PRIMARY KEY de la tabla a la que se hace referencia si las columnas a las que se hace referencia de la clave externa coinciden con las columnas de clave primaria de la tabla a la que se hace referencia. Si Cloud Spanner no puede usar la clave primaria de la tabla a la que se hace referencia, crea un UNIQUE NULL_FILTERED INDEX en las columnas a las que se hace referencia.

  • Es posible que Cloud Spanner también pueda usar la clave primaria de la tabla de referencia, aunque esto es menos común. De lo contrario, Cloud Spanner crea un NULL_FILTERED INDEX sobre las columnas referentes.

  • Las claves externas no usan índices secundarios que hayas creado; crean sus propios índices de respaldo. Estos índices de respaldo se pueden usar en las evaluaciones de consultas, incluidas las directivas force_index explícitas. El nombre de los índices de respaldo se puede consultar desde Información_SCHEMA en Cloud Spanner. Para obtener más información, consulta indexesndices de respaldo.

Cambios de esquema de larga duración

Agregar una clave externa a una tabla existente o crear una tabla nueva con una clave externa puede ocasionar operaciones de larga duración. En el caso de una tabla nueva, no se puede escribir en la tabla hasta que se complete la operación de larga duración.

Cuando creas una tabla nueva con una clave externa, Cloud Spanner necesita reabastecer los índices a los que se hace referencia según sea necesario para cada clave externa.

Cuando agregas una clave externa a una tabla existente, Cloud Spanner necesita rellenar los índices de referencia y referencia como sea necesario. Además, Cloud Spanner valida los datos existentes en la tabla para garantizar que cumplan con la restricción de integridad referencial de la clave externa. El cambio de esquema fallará si algún dato no es válido.

Cualquiera de los cambios de esquema anteriores puede fallar si el índice al que se hace referencia no se puede crear debido a una infracción de la restricción UNIQUE.

Puedes consultar NFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS.SPANNER_STATE para comprobar el estado de creación de la clave externa.

Validación de restricciones para una transacción

Cloud Spanner valida las restricciones de la clave externa cuando se confirma una transacción o cuando los efectos de las escrituras se hacen visibles para las operaciones posteriores en la transacción.

Un valor insertado en las columnas referentes coincide con los valores de la tabla y las columnas a las que se hace referencia. Las filas con valores referentes NULL no están verificadas, es decir, se pueden agregar a la tabla referente.

Cloud Spanner valida todas las restricciones de referencia de clave externa aplicables cuando intentas actualizar datos mediante declaraciones DML o una API. Todos los cambios pendientes se revierten si alguna restricción no es válida.

La validación se produce inmediatamente después de cada declaración DML. Por ejemplo, debes insertar la fila a la que se hace referencia antes de insertar las filas de referencia. Cuando usas una API de mutación, las mutaciones se almacenan en búfer hasta que se confirma la transacción. La validación de la clave externa se aplaza hasta que se confirma la transacción. En este caso, está permitido insertar primero las filas de referencia.

Cada transacción se evalúa para detectar modificaciones que afectan las restricciones de la clave externa. Estas evaluaciones pueden requerir solicitudes adicionales al servidor. Los índices de copia de seguridad también requieren tiempo de procesamiento adicional para evaluar las modificaciones de la transacción y mantener los índices. También se requiere almacenamiento adicional para cada índice.

Índices de respaldo

Las claves externas no usan índices creados por el usuario. Crean sus propios índices de copia de seguridad.

Cloud Spanner puede crear hasta dos índices de respaldo secundarios para cada clave externa, uno para las columnas referentes y otro para las columnas a las que se hace referencia. Sin embargo, una clave externa generalmente hace referencia a las claves primarias de la tabla a la que se hace referencia, por lo que el segundo índice de la tabla a la que hace referencia no suele ser necesario.

El índice de copia de seguridad de la tabla a la que se hace referencia es un índice UNIQUE NULL_FILTERED. la creación de la clave externa falla si algún dato que infringe la restricción de exclusividad del índice. El índice de copia de seguridad para la tabla de referencia es NULL_FILTERED.

Si dos o más claves externas requieren el mismo índice de copia de seguridad, Cloud Spanner creará un índice único para todas ellas. Los índices de copia de seguridad se descartan cuando se descartan las claves externas que las usan. Los usuarios no pueden alterar ni descartar los índices de copia de seguridad.

Los índices de copia de seguridad de claves externas se pueden usar en las evaluaciones de consultas. Sus nombres se pueden consultar desde INFORMATION_SCHEMA de Cloud Spanner.

Comparación de las llaves externas y la intercalación de tablas

La intercalación de tablas de Cloud Spanner es una buena opción para muchas relaciones entre tablas principales y secundarias en las que la clave primaria de la tabla secundaria incluye las columnas de clave primaria de la tabla principal. La ubicación conjunta de las filas secundarias con sus filas principales puede mejorar significativamente el rendimiento.

Las claves externas son una solución de relación principal-secundaria más general y abordan casos prácticos adicionales. No están limitadas a las columnas de clave primaria, y las tablas pueden tener varias relaciones de clave exterior, tanto como un superior en algunas relaciones, y un elemento secundario en otras. Sin embargo, una relación de clave externa no implica la ubicación conjunta de las tablas en la capa de almacenamiento.

Veamos un ejemplo con el esquema de procesamiento de pedidos que analizamos antes en este tema. Recupera nuestra tabla Orders de la siguiente manera:

Esquema de la base de datos con claves externas

Figura 3. Diagrama de nuestro esquema de base de datos con claves externas

El diseño de la figura 3 tiene algunas limitaciones. Por ejemplo, actualmente cada pedido solo puede contener un artículo de pedido.

Supongamos que nuestros clientes nos dicen que quieren pedir más de un producto por pedido. Para mejorar nuestro diseño, incorporamos una tabla OrderItems que contiene una entrada por cada producto que pidió el cliente. Se puede introducir otra clave externa para representar esta nueva relación de uno a varios entre Orders y OrderItems. Sin embargo, también sabemos que la mayoría de las veces querrá ejecutar consultas a través de pedidos y sus elementos de pedido respectivos. La ubicación conjunta de estos datos mejorará el rendimiento, por lo que crearemos la relación superior-secundario con la capacidad de intercalación de tabla de Cloud Spanner.

A continuación, te mostramos cómo definimos la tabla OrderItems, intercalada con Orders.

CREATE TABLE OrderItems (
  OrderID INT64 NOT NULL,
  ProductID INT64 NOT NULL,
  Quantity INT64 NOT NULL,
  FOREIGN KEY (ProductID) REFERENCES Products (ProductID)
) PRIMARY KEY (OrderID, ProductID),
  INTERLEAVE IN PARENT Orders ON DELETE CASCADE;

La Figura 4 es una representación visual del esquema de base de datos actualizado como resultado de la introducción de esta tabla nueva, OrderItems, intercalada con Orders. Aquí también puedes ver la relación de uno a varios entre esas dos tablas.

Esquema de base de datos que muestra una relación de uno a varios entre la tabla Orders y la nueva tabla intercalada OrderItems.

Figura 4. Adición de una tabla intercalada OrderItems.

En esta configuración, podemos tener varias entradas OrderItems en cada pedido, y las entradas OrderItems para cada pedido se intercalan, de modo que se ubican junto con los pedidos. Intercalar físicamente Orders y OrderItems de esta manera puede mejorar el rendimiento, ya que unifica previamente las tablas y te permite acceder a filas relacionadas, a la vez que minimiza los accesos al disco. Por ejemplo, Cloud Spanner puede realizar uniones localmente según la clave primaria, lo que minimiza el acceso al disco y el tráfico de red.

Resumen

La siguiente tabla resume las diferencias entre las claves externas y la intercalación de tablas. Puedes usar esta información a fin de decidir qué es lo mejor para tu diseño.

Tipo de relación primaria-secundaria Intercalación de tablas Claves externas
Puedes usar claves primarias
Puedes usar columnas de clave no primaria No
Cantidad de tablas principales admitidas 0 .. 1 0 .. N
Almacena datos superiores y secundarios al mismo tiempo No
Admite la eliminación de cascada No
Modo de coincidencia nula Pasa si todos los valores referentes no son distintos de los valores a los que se hace referencia.
Los valores nulos no son distintos de los valores nulos. los valores nulos son distintos de los valores no nulos.
Pasa si los valores referentes son nulos.
Pasa si todos los valores referentes son no nulos y la tabla a la que se hace referencia tiene una fila con valores equivalentes a los valores referentes.
Falla si no se encontró ninguna fila coincidente.
Tiempo de aplicación Por operación cuando se usa la API de mutación.
Por declaración cuando se usa DML.
Por transacción cuando se usa la API de mutación.
Por declaración cuando se usa DML.
Se puede quitar fácilmente No. El intercalado de tablas no se puede quitar después de crearlo, a menos que quites la tabla secundaria completa.

¿Qué sigue?