Claves externas

En este documento se describen las claves externas de Spanner y cómo puedes usarlas para aplicar la integridad referencial en tu base de datos. En los siguientes temas se explica qué son las claves externas y cómo usarlas:

Descripción general de las claves externas en Spanner

Las claves externas definen las relaciones entre las tablas. Puedes usar claves externas para asegurarte de que se mantenga la integridad de los datos de estas relaciones en Spanner.

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

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

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

Defines una tabla Customers para almacenar información de los clientes, una tabla Orders para registrar todos los pedidos y una tabla Products para almacenar información sobre cada producto.

En la figura 1 también se muestran los enlaces entre las tablas que se corresponden con las siguientes relaciones del mundo real:

  • Un cliente hace un pedido.

  • Se hace un pedido de un producto.

Decides que tu base de datos aplique las siguientes reglas para asegurarte de que los pedidos de tu sistema sean válidos.

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

  • Un cliente no puede hacer un pedido de un producto que no tengas.

Cuando aplicas estas reglas o restricciones, mantienes la integridad referencial de tus datos. Cuando una base de datos mantiene la integridad referencial, se rechazan todos los intentos de añadir datos no válidos que darían lugar a enlaces o referencias no válidos entre los datos. La integridad referencial evita errores de los usuarios. De forma predeterminada, Spanner usa claves externas para aplicar la integridad referencial.

Definir la integridad referencial con claves externas

A continuación, se vuelve a analizar el ejemplo de procesamiento de pedidos, con más detalles añadidos al diseño, como se muestra en la figura 2.

Esquema de base de datos con claves externas

Imagen 2. Diagrama de un esquema de base de datos con claves externas

Ahora, el diseño muestra los nombres y los tipos de las columnas de cada tabla. La tabla Orders también define dos relaciones de clave externa. FK_CustomerOrder espera que todas las filas de Orders tengan un valor CustomerId válido. La clave externa FK_ProductOrder espera que todos los valores de ProductId de la tabla Orders sean válidos. En la siguiente tabla se asignan estas restricciones a las reglas del mundo real que quieres aplicar.

Nombre de clave externa Restricción Descripción de la situación real
FK_CustomerOrder Espera que todas las filas de Orders tengan un valor válido CustomerId Un cliente válido hace un pedido
FK_ProductOrder Espera que todas las filas de Orders tengan un valor válido ProductId Se ha hecho un pedido de un producto válido

Spanner aplica las restricciones especificadas mediante claves externas obligatorias. Esto significa que Spanner rechaza cualquier transacción que intente insertar o actualizar una fila en la tabla Orders que tenga un CustomerId o un ProductId que no se encuentre en las tablas Customers y Products. También rechaza las transacciones que intentan actualizar o eliminar filas de las tablas Customers y Products que invalidarían los IDs de la tabla Orders. Para obtener más información sobre cómo valida Spanner las restricciones, consulta la sección Validación de restricciones de transacciones.

A diferencia de las claves externas obligatorias, Spanner no valida las restricciones de las claves externas informativas. Esto significa que, si usas una clave externa informativa en este caso, no se validará una transacción que intente insertar o actualizar una fila en la tabla Orders que tenga un CustomerId o un ProductId que no se encuentre en las tablas Customers y Products, y la transacción no fallará. Además, a diferencia de las claves externas obligatorias, las claves externas informativas solo se admiten en GoogleSQL y no en PostgreSQL.

Características de las claves externas

A continuación, se muestra una lista de las características de las claves externas en Spanner.

  • La tabla que define la clave externa es la tabla de referencia, y las columnas de clave externa son las columnas de referencia.

  • La clave externa hace referencia a las columnas referenciadas de la tabla referenciada.

  • Al igual que en el ejemplo, puede asignar un nombre a cada restricción de clave externa. Si no especificas un nombre, Spanner generará uno por ti. Puedes consultar el nombre generado desde la INFORMATION_SCHEMA de Spanner. Los nombres de las restricciones se limitan al esquema, junto con los nombres de las tablas y los índices, y deben ser únicos en el esquema.

  • El número de columnas de referencia y de columnas a las que se hace referencia debe ser el mismo. El orden es importante. Por ejemplo, la primera columna de referencia hace referencia a la primera columna a la que se hace referencia, y la segunda columna de referencia hace referencia a la segunda columna a la que se hace referencia.

  • Una columna de referencia y su contraparte referenciada deben ser del mismo tipo. Debes poder indexar las columnas.

  • No puedes crear claves externas en columnas con la opción allow_commit_timestamp=true.

  • No se admiten columnas de matriz.

  • No se admiten columnas JSON.

  • Una clave externa puede hacer referencia a columnas de la misma tabla (una clave externa autorreferencial). Por ejemplo, una Employee tabla con una columna 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 se referencian entre sí, ya sea directa o indirectamente. La tabla a la que se hace referencia debe existir antes de crear una clave externa. Esto significa que al menos una de las claves externas se debe añadir mediante la instrucción ALTER TABLE.

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

  • Las claves externas no usan los índices secundarios que hayas creado. En su lugar, crean sus propios índices de respaldo. Los índices de reserva se pueden usar en evaluaciones de consultas, incluidas las directivas force_index explícitas. Puedes consultar los nombres de los índices de respaldo desde la INFORMATION_SCHEMA de Spanner. Para obtener más información, consulta Crear copias de seguridad de índices.

Tipos de claves externas

Hay dos tipos de claves externas: obligatorias e informativas. Las claves externas obligatorias son el valor predeterminado y aplican la integridad referencial. Las claves externas informativas no aplican la integridad referencial y se usan mejor para declarar el modelo de datos lógico previsto para la optimización de consultas. Para obtener más información, consulta las secciones sobre las claves externas obligatorias y informativas, así como la comparación de los tipos de claves externas.

Claves externas obligatorias

Las claves externas obligatorias, el tipo de clave externa predeterminado en Spanner, aplican la integridad referencial. Como las claves externas obligatorias aplican la integridad referencial, provocan que fallen los intentos de hacer lo siguiente:

  • Si se añade una fila a una tabla de referencia que tiene un valor de clave externa que no existe en la tabla de referencia, se produce un error.

  • No se puede eliminar una fila de una tabla a la que hacen referencia filas de otra tabla.

Todas las claves externas de PostgreSQL se aplican. Las claves externas de GoogleSQL se aplican de forma predeterminada. Como las claves externas se aplican de forma predeterminada, es opcional usar la palabra clave ENFORCED para especificar que se aplique una clave externa de GoogleSQL.

Claves externas informativas

Las claves externas informativas se usan para declarar el modelo de datos lógico previsto para la optimización de consultas. Aunque las claves de tabla a las que se hace referencia deben ser únicas para las claves externas informativas, no se aplica la integridad referencial. Si quieres validar de forma selectiva la integridad referencial cuando usas claves externas informativas, debes gestionar la lógica de validación en el lado del cliente. Para obtener más información, consulta Usar claves externas informativas.

Usa la palabra clave NOT ENFORCED para especificar que una clave externa de GoogleSQL es informativa. PostgreSQL no admite claves externas informativas.

Comparación de tipos de claves externas

Tanto las obligatorias como las informativas tienen ventajas. En las siguientes secciones se comparan los dos tipos de claves externas y se incluyen algunas prácticas recomendadas.

Diferencias de alto nivel entre las claves externas

A continuación, se indican algunas de las diferencias entre las claves externas obligatorias y las informativas:

  • Implementación obligatoria. Las claves externas obligatorias validan y garantizan la integridad referencial en las escrituras. Las claves externas informativas no validan ni garantizan la integridad referencial.

  • Almacenamiento. Las claves externas obligatorias pueden requerir almacenamiento adicional para el índice de respaldo de la tabla restringida.

  • Rendimiento de escritura: Las claves externas obligatorias pueden suponer una mayor sobrecarga en la ruta de escritura que las claves externas informativas.

  • Optimización de consultas. Ambos tipos de claves externas se pueden usar para optimizar las consultas. Si el optimizador puede usar claves externas informativas, es posible que los resultados de las consultas no reflejen los datos reales si estos no coinciden con las relaciones de claves externas informativas (por ejemplo, si algunas claves restringidas no tienen claves de referencia coincidentes en la tabla de referencia).

Tabla de diferencias de claves externas

En la siguiente tabla se enumeran las diferencias detalladas entre las claves externas obligatorias y las informativas:

Claves externas obligatorias Claves externas informativas
Palabras clave ENFORCED NOT ENFORCED
Compatible con GoogleSQL Sí. Las claves externas de GoogleSQL se aplican de forma predeterminada. Sí.
Compatible con PostgreSQL Sí. Las claves externas de PostgreSQL solo se pueden aplicar. No.
Almacenamiento Las claves externas obligatorias requieren almacenamiento para un máximo de dos índices de reserva. Las claves externas informativas requieren almacenamiento para un índice de reserva como máximo.
Crea índices de respaldo en las columnas de la tabla referenciada cuando sea necesario. Sí. Sí.
Crea índices de respaldo en las columnas de la tabla de referencia cuando es necesario. Sí. No.
Compatibilidad con acciones de clave externa Sí. No.
Valida y aplica la integridad referencial Sí. No. Si no se valida, se mejora el rendimiento de escritura, pero puede afectar a los resultados de las consultas cuando se usan claves externas informativas para optimizar las consultas. Puede usar la validación del lado del cliente o una clave externa obligatoria para asegurar la integridad referencial.

Elige el tipo de clave externa que quieras usar

Puedes usar las siguientes directrices para decidir qué tipo de clave externa usar:

Te recomendamos que empieces con las claves externas obligatorias. Las claves externas obligatorias mantienen la coherencia de los datos y del modelo lógico en todo momento. Las claves externas obligatorias son la opción recomendada, a menos que no funcionen en tu caso práctico.

Te recomendamos que tengas en cuenta las claves externas informativas si se cumplen las siguientes condiciones:

  • Quieres usar el modelo de datos lógico descrito por la clave externa informativa en la optimización de consultas.

  • Mantener una integridad referencial estricta no es práctico o afecta significativamente al rendimiento. A continuación, se muestran algunos ejemplos de situaciones en las que puede ser útil usar una clave externa informativa:

    • Tu fuente de datos upstream sigue un modelo de coherencia final. En este caso, es posible que las actualizaciones realizadas en el sistema de origen no se reflejen inmediatamente en Spanner. Como las actualizaciones no son inmediatas, pueden producirse breves incoherencias en las relaciones de claves externas.

    • Sus datos contienen filas a las que se hace referencia y que tienen un gran número de relaciones de referencia. Las actualizaciones de estas filas pueden usar muchos recursos, ya que Spanner debe validar o, en algunos casos, eliminar todas las filas relacionadas con el mantenimiento de la integridad referencial. En este caso, las actualizaciones pueden afectar al rendimiento de Spanner y ralentizar las transacciones simultáneas.

  • Tu aplicación puede gestionar las posibles incoherencias de los datos y su impacto en los resultados de las consultas.

Usar claves externas informativas

Los temas siguientes solo se refieren a claves externas informativas. Para obtener información sobre los temas que se aplican tanto a las claves externas informativas como a las obligatorias, consulta lo siguiente:

Crear una tabla con una clave externa informativa

Puede crear y quitar claves externas informativas de su base de datos de Spanner mediante instrucciones DDL. Para añadir claves externas a una tabla nueva, usa la instrucción CREATE TABLE. Del mismo modo, puedes añadir o quitar claves externas de una tabla disponible con la instrucción ALTER TABLE.

En el siguiente ejemplo se crea una tabla con una clave externa informativa mediante GoogleSQL. PostgreSQL no admite claves externas informativas.

GoogleSQL

CREATE TABLE Customers (
  CustomerId INT64 NOT NULL,
  CustomerName STRING(MAX) NOT NULL,
) PRIMARY KEY(CustomerId);

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) NOT ENFORCED
 ) PRIMARY KEY (OrderId);

PostgreSQL

Not Supported

Para ver más ejemplos de cómo crear y gestionar claves externas, consulta Crear y gestionar relaciones de claves externas. Para obtener más información sobre las instrucciones DDL, consulta la referencia de DDL.

Usar claves externas informativas para optimizar las consultas

El optimizador de consultas puede usar tanto claves externas obligatorias como claves externas informativas para mejorar el rendimiento de las consultas. El uso de claves externas informativas te permite aprovechar los planes de consulta optimizados sin la sobrecarga de la aplicación estricta de la integridad referencial.

Si habilitas el optimizador de consultas para que utilice información de claves externas informativas, es importante que sepas que la corrección de la optimización depende de que los datos sean coherentes con el modelo lógico descrito por las claves externas informativas. Si hay incoherencias, es posible que los resultados de las consultas no reflejen los datos reales. Por ejemplo, se produce una incoherencia cuando un valor de una columna restringida no tiene un valor coincidente en una columna de referencia.

De forma predeterminada, el optimizador de consultas usa claves externas NOT ENFORCED. Para cambiarlo, define la opción de base de datos use_unenforced_foreign_key_for_query_optimization como false. A continuación, se muestra un ejemplo de GoogleSQL que demuestra esto (las claves externas informativas no están disponibles en PostgreSQL):

SET DATABASE OPTIONS (
    use_unenforced_foreign_key_for_query_optimization = false
);

La sugerencia de instrucción de consulta booleana @{use_unenforced_foreign_key} anula la opción de base de datos por consulta que controla si el optimizador usa claves externas NOT ENFORCED. Inhabilitar esta sugerencia o la opción de base de datos puede ser útil para solucionar problemas con resultados de consulta inesperados. A continuación, se muestra cómo usar @{use_unenforced_foreign_key}:

@{use_unenforced_foreign_key=false} SELECT Orders.CustomerId
    FROM Orders
    INNER JOIN Customers ON Customers.CustomerId = Orders.CustomerId;

Usar claves externas obligatorias

Los siguientes temas solo se aplican a las claves externas obligatorias. Para obtener información sobre los temas que se aplican tanto a las claves externas informativas como a las obligatorias, consulta lo siguiente:

Crear una tabla con una clave externa obligatoria

Puedes crear, eliminar y aplicar claves externas en tu base de datos de Spanner mediante DDL. Para añadir claves externas a una tabla, usa la instrucción CREATE TABLE. Del mismo modo, puedes añadir o quitar una clave externa de una tabla disponible con la instrucción ALTER TABLE.

Puedes crear y eliminar claves externas de tu base de datos de Spanner con DDL. Para añadir claves externas a una tabla nueva, usa la instrucción CREATE TABLE. Del mismo modo, puedes añadir o quitar una clave externa de una tabla disponible con la instrucción ALTER TABLE.

A continuación, se muestra un ejemplo de cómo crear una tabla con una clave externa obligatoria.

GoogleSQL

CREATE TABLE Customers (
CustomerId INT64 NOT NULL,
CustomerName STRING(MAX) NOT NULL,
) PRIMARY KEY(CustomerId);

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) ENFORCED
) PRIMARY KEY (OrderId);

PostgreSQL

CREATE TABLE Customers (
CustomerId bigint NOT NULL,
CustomerName character varying(1024) NOT NULL,
PRIMARY KEY(CustomerId)
);

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

Para ver más ejemplos de cómo crear y gestionar claves externas, consulta Crear y gestionar relaciones de claves externas.

Acciones de clave externa

Las acciones de clave externa solo se pueden definir en claves externas obligatorias.

Las acciones de clave externa controlan lo que ocurre con la columna restringida cuando se elimina o actualiza la columna a la que hace referencia. Spanner admite el uso de la acción ON DELETE CASCADE. Con la acción de clave externa ON DELETE CASCADE, cuando eliminas una fila que contiene una clave externa referenciada, todas las filas que hacen referencia a esa clave también se eliminan en la misma transacción.

Puedes añadir una clave externa con una acción al crear tu base de datos con DDL. Usa la instrucción CREATE TABLE para añadir claves externas con una acción a una tabla nueva. Del mismo modo, puede usar la instrucción ALTER TABLE para añadir una acción de clave externa a una tabla o para quitarla. A continuación, se muestra un ejemplo de cómo crear una tabla con una acción de clave externa.

GoogleSQL

CREATE TABLE ShoppingCarts (
CartId INT64 NOT NULL,
CustomerId INT64 NOT NULL,
CustomerName STRING(MAX) NOT NULL,
CONSTRAINT FKShoppingCartsCustomers FOREIGN KEY(CustomerId, CustomerName)
  REFERENCES Customers(CustomerId, CustomerName) ON DELETE CASCADE,
) PRIMARY KEY(CartId);

PostgreSQL

CREATE TABLE ShoppingCarts (
CartId bigint NOT NULL,
CustomerId bigint NOT NULL,
CustomerName character varying(1024) NOT NULL,
PRIMARY KEY(CartId),
CONSTRAINT fkshoppingcartscustomers FOREIGN KEY (CustomerId, CustomerName)
  REFERENCES Customers(CustomerId, CustomerName) ON DELETE CASCADE
);

A continuación, se muestra una lista de las características de las acciones de clave externa en Spanner.

  • Las acciones de clave externa son ON DELETE CASCADE o ON DELETE NO ACTION.

  • Puedes consultar INFORMATION_SCHEMA para encontrar restricciones de clave externa que tengan una acción.

  • No se puede añadir una acción de clave externa a una restricción de clave externa ya creada. Debes añadir una nueva restricción de clave externa con una acción.

Validación de restricciones

La validación de restricciones solo se aplica a las claves externas obligatorias.

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

Un valor insertado en la columna de referencia se compara con los valores de la tabla y las columnas de referencia. Las filas con valores de NULL no se comprueban, por lo que puede añadirlas a la tabla de referencia.

Spanner valida todas las restricciones de integridad referencial de clave externa aplicables cuando se intenta actualizar datos mediante instrucciones 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 instrucción DML. Por ejemplo, debes insertar la fila a la que se hace referencia antes de insertar las filas que hacen referencia a ella. Cuando se usa una API de mutación, las mutaciones se almacenan en búfer hasta que se confirma la transacción. La validación obligatoria de claves externas se aplaza hasta que se confirme la transacción. En este caso, se pueden insertar primero las filas de referencia.

Cada transacción se evalúa para detectar modificaciones que afecten a las restricciones de clave externa obligatorias. Estas evaluaciones pueden requerir solicitudes adicionales al servidor. Los índices de respaldo también requieren un tiempo de procesamiento adicional para evaluar las modificaciones de las transacciones y mantener los índices. También se necesita almacenamiento adicional para cada índice.

Operación de eliminación en cascada de larga duración

Cuando eliminas una fila de una tabla a la que se hace referencia, Spanner debe eliminar todas las filas de las tablas que hacen referencia a la fila eliminada. Esto puede provocar un efecto cascada, en el que una sola operación de eliminación dé lugar a miles de operaciones de eliminación. Añadir una restricción de clave externa con la acción de eliminación en cascada a una tabla o crear una tabla con restricciones de clave externa con la acción de eliminación en cascada puede ralentizar las operaciones de eliminación.

Se ha superado el límite de mutaciones para la eliminación en cascada de la clave externa

Eliminar un gran número de registros mediante una eliminación en cascada de clave externa puede afectar al rendimiento. Esto se debe a que cada registro eliminado implica la eliminación de todos los registros relacionados con él. Si necesitas eliminar un gran número de registros mediante una eliminación en cascada de clave externa, elimina explícitamente las filas de las tablas secundarias antes de eliminar la fila de las tablas principales. De esta forma, la transacción no fallará debido al límite de mutaciones.

Comparación de claves externas obligatorias y entrelazado de tablas

El intercalado de tablas de Spanner es una buena opción para muchas relaciones entre tablas superiores y tablas secundarias en los casos en los que la clave principal de la tabla secundaria incluye las columnas de la clave principal de la tabla superior. Colocar tablas superiores y secundarias en ubicaciones compartidas puede mejorar el rendimiento de forma significativa.

Las claves externas son una solución más general para tablas superiores y secundarias, y se pueden usar en otros casos prácticos. No están limitadas a columnas de claves principales. Las tablas pueden tener varias relaciones de claves externas, tanto como tabla superior en algunas relaciones como tabla secundaria en otras. Sin embargo, una relación de clave externa no implica que las tablas se encuentren en la misma ubicación en la capa de almacenamiento.

Supongamos que tenemos una tabla Orders definida de la siguiente manera:

Esquema de base de datos con claves externas

Imagen 3. Diagrama del esquema de la base de datos con claves externas obligatorias

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

Imagina que tus clientes quieren poder pedir más de un producto por pedido. Puedes mejorar el diseño introduciendo una OrderItems tabla que contenga una entrada para cada producto que haya pedido el cliente. Puedes introducir otra clave externa obligatoria para representar esta nueva relación de uno a muchos entre Orders y OrderItems. Sin embargo, también sabes que a menudo quieres ejecutar consultas en los pedidos y sus respectivos elementos de pedido. Como la colocación conjunta de estos datos mejora el rendimiento, te recomendamos que crees la relación entre elementos principales y secundarios mediante la función de intercalación de tablas de Spanner.

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

GoogleSQL

CREATE TABLE Products (
ProductId INT64 NOT NULL,
Name STRING(256) NOT NULL,
Price FLOAT64
) PRIMARY KEY(ProductId);

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;

PostgreSQL

CREATE TABLE Products (
ProductId BIGINT NOT NULL,
Name varchar(256) NOT NULL,
Price float8,
PRIMARY KEY(ProductId)
);

CREATE TABLE OrderItems (
OrderId BIGINT NOT NULL,
ProductId BIGINT NOT NULL,
Quantity BIGINT NOT NULL,
FOREIGN KEY (ProductId) REFERENCES Products (ProductId),
PRIMARY KEY (OrderId, ProductId)
) INTERLEAVE IN PARENT Orders ON DELETE CASCADE;

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

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

Imagen 4. Se ha añadido una tabla OrderItems intercalada

En esta configuración, puede haber varias entradas OrderItems en cada pedido. Las entradas OrderItems de cada pedido se intercalan y, por lo tanto, se colocan junto a los pedidos. Intercalar físicamente Orders y OrderItems de esta forma puede mejorar el rendimiento, ya que se unen las tablas de forma eficaz y se pueden acceder a las filas relacionadas juntas, lo que minimiza los accesos al disco. Por ejemplo, Spanner puede realizar combinaciones por clave principal de forma local, lo que minimiza el acceso al disco y el tráfico de red.

Si el número de mutaciones de una transacción supera las 80.000, la transacción falla. Estas eliminaciones en cascada de gran tamaño funcionan bien en tablas con una relación "interleaved in parent", pero no en tablas con una relación de clave externa. Si tienes una relación de clave externa y necesitas eliminar un gran número de filas, debes eliminar explícitamente las filas de las tablas secundarias primero.

Si tienes una tabla de usuarios con una relación de clave externa con otra tabla y al eliminar una fila de la tabla de referencia se eliminan millones de filas, debes diseñar tu esquema con una acción de eliminación en cascada con "interleaved in parent".

Tabla comparativa

En la siguiente tabla se resume la comparación entre las claves externas obligatorias y el entrelazado de tablas. Puedes usar esta información para decidir qué es lo más adecuado para tu diseño.

Tipo de relación entre editor principal y secundario Intercalado de tablas Claves externas obligatorias
Puede usar teclas principales
Puede usar columnas que no sean de clave principal No
Número de padres a los que se ofrece asistencia 0 .. 1 0 .. N
Almacena datos de elementos superiores y secundarios juntos. No
Admite la eliminación en cascada
Modo de coincidencia nulo Se aprueba si todos los valores de referencia no son distintos de los valores a los que se hace referencia.
Los valores nulos no son distintos de los valores nulos, pero sí de los valores no nulos.
Se supera si alguno de los valores de referencia es nulo.
Se supera si todos los valores de referencia no son nulos y la tabla de referencia tiene una fila con valores iguales a los valores de referencia.
No se supera si no se ha encontrado ninguna fila coincidente.
Plazos de las medidas por incumplimiento de políticas Por operación al usar la API Mutation.
Por instrucción al usar DML.
Por transacción al usar la API Mutation.
Por instrucción al usar DML.
Se puede eliminar No. El entrelazado de tablas no se puede quitar una vez creado, a menos que elimines toda la tabla secundaria.

Índices de respaldo

Las claves externas no usan índices creados por el usuario. En su lugar, crean sus propios índices de respaldo. Las claves externas obligatorias y informativas crean índices de reserva de forma diferente en Spanner:

  • En el caso de las claves externas obligatorias, Spanner puede crear hasta dos índices de respaldo secundarios por cada clave externa: uno para las columnas de referencia y otro para las columnas a las que se hace referencia.

  • En el caso de las claves externas informativas, Spanner puede crear hasta un índice de respaldo cuando sea necesario para las columnas a las que se hace referencia. Las claves externas informativas no crean un índice de respaldo para las columnas de referencia.

En el caso de las claves externas obligatorias y las informativas, una clave externa suele hacer referencia a las claves principales de la tabla a la que se hace referencia, por lo que normalmente no se necesita un índice para la tabla a la que se hace referencia. Por este motivo, las claves externas informativas suelen tener cero índices de reserva. Cuando sea necesario, el índice de respaldo creado para la tabla referenciada será un índice UNIQUE NULL_FILTERED. La creación de la clave externa falla si algún dato infringe la restricción de unicidad del índice.

Las claves externas informativas no tienen un índice de reserva para la tabla de referencia. En el caso de las claves externas obligatorias, el índice de reserva de la tabla de referencia es NULL_FILTERED.

Si dos o más claves externas requieren el mismo índice de respaldo, Spanner crea un solo índice para cada una de ellas. Los índices de respaldo se eliminan cuando se eliminan las claves externas que los usan. No puedes modificar ni eliminar los índices de respaldo.

Spanner usa el esquema de información de cada base de datos para almacenar metadatos sobre los índices de respaldo. Las filas de INFORMATION_SCHEMA.INDEXES que tienen un valor SPANNER_IS_MANAGED de true describen los índices de reserva.

Aparte de las consultas SQL que invocan directamente el esquema de información, laGoogle Cloud consola no muestra ninguna información sobre los índices de respaldo de una base de datos.

Cambios de esquema de larga duración

Si añades una clave externa obligatoria a una tabla o creas una tabla con una clave externa, las operaciones pueden tardar mucho tiempo en completarse. En el caso de una tabla nueva, no se podrá escribir en ella hasta que se complete la operación de larga duración.

En la siguiente tabla se muestra lo que ocurre en Spanner cuando una clave externa obligatoria y una informativa se encuentran en una tabla nueva o en una tabla ya creada:

Tipo de tabla Clave externa obligatoria Clave externa informativa
Nuevo Spanner rellena los índices a los que se hace referencia según sea necesario para cada clave externa. Spanner rellena los índices a los que se hace referencia según sea necesario para cada clave externa.
Existente Spanner rellena los índices de referencia y referenciados según sea necesario. Spanner también valida los datos de la tabla para asegurarse de que cumplen la restricción de integridad referencial de la clave externa. El cambio de esquema falla si algún dato no es válido. Spanner rellena el índice al que se hace referencia según sea necesario y no valida los datos de la tabla.

No se admiten los siguientes elementos:

  • Añadir una acción de clave externa a una restricción de clave externa aplicada.
  • Cambiar la aplicación de una clave externa.

En ambos casos, te recomendamos que hagas lo siguiente:

  1. Añade una nueva restricción con la acción o la medida obligatoria.
  2. Elimina la restricción antigua.

Si añades una nueva restricción y eliminas la antigua, se evitará un problema de operación de modificación de restricción de larga duración. Por ejemplo, supongamos que quieres añadir una acción DELETE CASCADE a una clave externa. Después de crear la nueva clave externa con la acción ON DELETE CASCADE, el efecto de ambas restricciones es una acción DELETE CASCADE. Después, puedes eliminar la restricción antigua sin problemas.

Si los índices no se usan en otras restricciones de clave externa, al eliminar una restricción se pueden eliminar los índices de reserva de la clave externa. Por este motivo, si primero quitas la restricción antigua, añadir la misma restricción de clave externa con una acción más adelante puede provocar operaciones de larga duración, como rellenar índices, validar restricciones de índice único o validar restricciones referenciales de clave externa.

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

Siguientes pasos