Descripción general de los esquemas

En esta página, se analizan los requisitos del esquema de Spanner y cómo usarlo para crear relaciones jerárquicas y esquemas de atributos. También presenta las tablas intercaladas, que pueden mejorar el rendimiento de las consultas cuando se consultan tablas una relación superior-secundario.

Un esquema es un espacio de nombres que contiene objetos de base de datos, como tablas, vistas, índices y funciones. Usas esquemas para organizar objetos, aplicar control de acceso detallado privilegios y evitar conflictos de nombres. Debes definir un esquema para cada de Google Cloud en Spanner.

También puedes segmentar y almacenar más filas en la tabla de tu base de datos en en diferentes regiones geográficas. Para obtener más información, consulta la Descripción general de la partición geográfica.

Datos muy escritos

Los datos en Spanner están bien escritos. Los tipos de datos incluyen escalar y complejos de consulta, que se describen en Tipos de datos en GoogleSQL y tipos de datos de PostgreSQL.

Selecciona una clave principal.

Las bases de datos de Spanner pueden contener una o más tablas. Las tablas están estructuradas como filas y columnas. El esquema de la tabla define una o más columnas de la tabla como el clave primaria de la tabla, que identifica de manera única cada fila. Las claves primarias son se indexan siempre para rápida búsqueda de filas. Si quieres actualizar o borrar filas en una tabla, esta debe tener una clave primaria. Una tabla sin principal las columnas de claves solo pueden tener una fila. Solo las bases de datos de dialectos de GoogleSQL pueden tener tablas sin una clave primaria.

A menudo, tu aplicación ya tiene un campo que se puede usar de forma natural como clave primaria. Por ejemplo, en una tabla Customers, podría haber un CustomerId suministrada por la aplicación que funciona bien como clave primaria. En otro en algunos casos, tendrás que generar una clave primaria cuando insertes la fila. Esta normalmente sería un número entero único sin importancia comercial (un clave primaria subrogada).

En todos los casos, debes tener cuidado de no crear hotspots con la clave primaria que elijas. Por ejemplo, si insertas registros con una clave que es un número entero que aumenta monótonamente, siempre se insertará al final del espacio de claves. Esto no es conveniente, ya que Spanner divide los datos servidores por rango de claves, lo que significa que tus inserciones se dirigirán a un solo servidor, creando un hotspot. Existen técnicas que pueden distribuir la carga entre varios servidores y evitar los hotspots:

Relaciones entre tablas superiores y secundarias

Existen dos maneras de definir las relaciones superior-secundario Spanner: intercalación de tablas y claves externas.

La intercalación de tablas de Spanner es una buena opción para muchos entre tablas primarias y secundarias. Con la intercalación, Spanner físicamente coloca las filas secundarias con filas superiores en el almacenamiento. La colocación puede mejorar el rendimiento. Por ejemplo, si tienes una tabla Customers y un Invoices y tu aplicación recupera con frecuencia todas las facturas de un puedes definir Invoices como una tabla secundaria intercalada de Customers. Al hacerlo, declaras una relación de localidad de datos entre dos tablas independientes. Le indicas a Spanner para almacenar una o más filas de Invoices con una fila de Customers.

Se asocia una tabla secundaria con una tabla superior mediante un DDL que declara la secundaria como intercalada en la superior y, además, incluyendo la tabla superior como la primera parte de la clave primaria compuesta de la tabla secundaria. Para ver más Obtén más información sobre la intercalación, consulta Crea tablas intercaladas más adelante en este .

Las claves externas son una solución de elementos principales y secundarios 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.

Google recomienda que elijas representar las relaciones superior-secundario como tablas intercaladas o como claves externas, pero no ambas. Para obtener más información externas y su comparación con tablas intercaladas, consulta Claves externas descripción general.

Claves primarias en tablas intercaladas

Para la intercalación, cada tabla debe tener una clave primaria. Si declaras una tabla a un elemento secundario intercalado de otra tabla, la tabla debe tener un que incluya todos los componentes de la clave primaria del elemento superior, en el mismo orden y, en general, una o más columnas adicionales de la tabla secundaria.

Spanner almacena las filas en orden según los valores de clave primaria, con las filas secundarias insertadas entre las filas superiores. Una ilustración de filas intercaladas en Crea tablas intercaladas más adelante en esta página.

En resumen, Spanner puede colocar físicamente filas de tablas relacionadas. El Los ejemplos de esquema muestran cómo se ve este diseño físico.

Divisiones de bases de datos

Puedes definir jerarquías de relaciones intercaladas entre tablas primarias y secundarias de hasta siete de capas profundas, lo que significa que puede colocar filas de siete tablas independientes. Si el tamaño de los datos de tus tablas es pequeño, una sola instancia de Spanner servidor puede manejar tu base de datos. Pero ¿qué sucede cuando tus palabras clave crezcan y comiencen a alcanzar los límites de recursos de un servidor individual? Spanner es una base de datos distribuida, lo que significa que, la base de datos crece, Spanner divide los datos en fragmentos llamados “fracciones”. Las divisiones individuales pueden moverse de forma independiente entre sí y asignarse a distintos servidores, que pueden estar en diferentes ubicaciones físicas. R split contiene un rango de filas contiguas. Las claves de inicio y finalización de este rango se llamados “límites de división”. Spanner agrega y quita automáticamente límites de división según el tamaño y la carga, lo que cambia la cantidad de divisiones en la base de datos.

División basada en la carga

Un ejemplo de cómo Spanner realiza la división basada en la carga en para mitigar los hotspots de lectura, supongamos que tu base de datos contiene una tabla con 10 filas se leen con más frecuencia que todas las otras filas de la tabla. Spanner puede agregar límites de división entre cada una de esas 10 filas que cada una sea manejada por un servidor diferente, en lugar de permitir o lecturas de esas filas para consumir los recursos de un solo servidor.

Como regla general, si sigues las prácticas recomendadas para el diseño de esquemas, Spanner puede mitigar hotspots de modo que la capacidad de procesamiento de lectura debería mejorar cada pocos minutos hasta que satures los recursos de tu o en los casos en que no se pueden agregar nuevos límites de división (porque tienes una división que cubre solo una fila sin elementos secundarios intercalados).

Esquemas con nombre

Los esquemas con nombre te ayudan a organizar datos similares juntos. Esto te ayuda a buscar objetos en la consola de Google Cloud, aplicar privilegios y evitar usar nombres de conflictos.

Los esquemas con nombre, al igual que otros objetos de base de datos, se administran mediante DDL.

Los esquemas con nombre de Spanner te permiten usar nombres completamente calificados (FQN) para consultar datos. Los FQN te permiten combinar el nombre del esquema y el el nombre del objeto para identificar los objetos de la base de datos. Por ejemplo, podrías crear un esquema llamada warehouse para la unidad de negocios del almacén. Las tablas que usan el esquema puede incluir product, order y customer information. O tú podrías crear un esquema llamado fulfillment para la unidad de negocios de entrega. Este esquema también podría tener tablas llamadas product, order y customer information. En el primer ejemplo, el FQN es warehouse.product y en el segundo ejemplo, el FQN es fulfillment.product. Esto evita confusiones en situaciones en las que varios objetos comparten el mismo nombre.

En el DDL CREATE SCHEMA, los objetos de tabla reciben un FQN, por ejemplo, sales.customers y un nombre corto, por ejemplo, sales.

Los siguientes objetos de base de datos admiten esquemas con nombre:

  • TABLE
    • CREATE
    • INTERLEAVE IN [PARENT]
    • FOREIGN KEY
    • SYNONYM
  • VIEW
  • INDEX
  • FOREIGN KEY
  • SEQUENCE

Para obtener más información sobre el uso de esquemas con nombre, consulta Administra esquemas esquemas.

Usa el control de acceso detallado con esquemas con nombre

Los esquemas con nombre te permiten otorgar acceso a nivel de esquema a cada objeto en él. Esto se aplica a los objetos de esquema que existen en el momento en que otorgas acceso. Debes otorgar acceso a los objetos que se agreguen más adelante.

El control de acceso detallado limita el acceso a grupos completos de objetos de base de datos, como tablas, columnas y filas de la tabla.

Para obtener más información, consulta Otorga privilegios de control de acceso detallados a los usuarios esquemas.

Ejemplos de esquemas

Los ejemplos de esquema de esta sección muestran cómo crear tablas superiores y secundarias con y sin intercalar e ilustra los diseños físicos correspondientes de los datos.

Crea una tabla superior

Imagina que estás creando una aplicación de música y necesitas una tabla que almacene filas de datos de cantantes:

Tabla de cantantes con cinco filas y cuatro columnas

Ten en cuenta que la tabla contiene una columna de clave primaria, SingerId, que aparece a la izquierda de la línea en negrita, y que las tablas están organizadas por filas y columnas.

Puedes definir la tabla con el siguiente DDL:

GoogleSQL

CREATE TABLE Singers (
SingerId   INT64 NOT NULL,
FirstName  STRING(1024),
LastName   STRING(1024),
SingerInfo BYTES(MAX),
) PRIMARY KEY (SingerId);

PostgreSQL

CREATE TABLE singers (
singer_id   BIGINT PRIMARY KEY,
first_name  VARCHAR(1024),
last_name   VARCHAR(1024),
singer_info BYTEA
);

Ten en cuenta lo siguiente sobre el esquema de ejemplo:

  • Singers es una tabla en la raíz de la jerarquía de la base de datos (porque no es se define como un elemento secundario intercalado de otra tabla).
  • Para las bases de datos del dialecto de GoogleSQL, las columnas de clave primaria suelen anotarse con NOT NULL. (aunque puedes omitir esta anotación si deseas permitir valores NULL en columnas de claves. Para obtener más información, consulta Claves Columnas).
  • Las columnas que no se incluyen en la clave primaria se denominan columnas sin clave y pueden tener una anotación NOT NULL opcional.
  • Las columnas que usan los tipos STRING o BYTES en GoogleSQL deben definido con una longitud, que representa la cantidad máxima de caracteres caracteres que se pueden almacenar en el campo. La especificación de longitud es opcional para varchar y character varying de PostgreSQL de tipos de datos. Para obtener más información, consulta Tipos de datos escalares. para bases de datos de dialectos de GoogleSQL y datos de PostgreSQL tipos para las bases de datos del dialecto de PostgreSQL.

¿Cómo es la disposición física de las filas de la tabla Singers? El En el siguiente diagrama, se muestran las filas de la tabla Singers que almacena la clave primaria ("Singers(1)" y, luego, "Singers(2)", donde el número entre paréntesis es el valor de la clave primaria.

Filas de ejemplo de una tabla almacenada en orden de clave primaria

En el diagrama anterior, se ilustra un ejemplo de límite de división entre las filas. con la clave Singers(3) y Singers(4), con los datos de las divisiones resultantes se asignan a servidores diferentes. A medida que esta tabla crece, es posible que haya filas de Los datos de Singers se almacenarán en diferentes ubicaciones.

Crear tablas superiores y secundarias

Imagina que quieres agregar algunos datos básicos sobre los álbumes de cada cantante a la aplicación de música.

Tabla álbumes con cinco filas y tres columnas

Ten en cuenta que la clave primaria de Albums se compone de dos columnas: SingerId y AlbumId. Esto permite asociar cada álbum con su cantante. El siguiente esquema de ejemplo Define las tablas Albums y Singers en la raíz de la base de datos. jerárquica, lo que las convierte en tablas del mismo nivel.

-- Schema hierarchy:
-- + Singers (sibling table of Albums)
-- + Albums (sibling table of Singers)

GoogleSQL

CREATE TABLE Singers (
 SingerId   INT64 NOT NULL,
 FirstName  STRING(1024),
 LastName   STRING(1024),
 SingerInfo BYTES(MAX),
) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
SingerId     INT64 NOT NULL,
AlbumId      INT64 NOT NULL,
AlbumTitle   STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId);

PostgreSQL

CREATE TABLE singers (
singer_id   BIGINT PRIMARY KEY,
first_name  VARCHAR(1024),
last_name   VARCHAR(1024),
singer_info BYTEA
);

CREATE TABLE albums (
singer_id     BIGINT,
album_id      BIGINT,
album_title   VARCHAR,
PRIMARY KEY (singer_id, album_id)
);

El diseño físico de las filas de Singers y Albums es similar al siguiente: siguiente diagrama, con filas de la tabla Albums almacenadas por instancia principal contigua y, luego, las filas de Singers almacenadas por clave primaria contigua:

Disposición física de las filas

Nota importante sobre este esquema: Spanner supone que no relaciones de localidad de datos entre las tablas Singers y Albums, porque son tablas de nivel superior. A medida que la base de datos crece, Spanner puede agregar límites de división entre cualquiera de las filas. Esto significa que las filas de Albums podría terminar en una división diferente a las filas de la tabla Singers, y las dos divisiones podrían moverse de forma independiente unas de otras.

Según las necesidades de la aplicación, podría ser aceptable permitir que los datos de Albums se ubiquen en divisiones diferentes a las de los datos de Singers. Sin embargo, esto puede generar una penalización de rendimiento debido a la necesidad de coordinar las lecturas y actualizaciones en distintos recursos. Si tu aplicación necesita recuperar información con frecuencia sobre todos los álbumes de un cantante en particular, deberías crear Albums como una tabla secundaria intercalada de Singers, que coloca filas de los dos junto con la dimensión de la clave primaria. En el siguiente ejemplo, se explica esto en detalle.

Crea tablas intercaladas

Una tabla intercalada es una tabla de la que declaras como elemento secundario intercalado en otra tabla porque quieres que las filas de la tabla secundaria estén físicamente se almacenan con la fila superior asociada. Como mencionamos antes, la tabla superior La clave primaria debe ser la primera parte de la clave primaria compuesta de la tabla secundaria.

Mientras diseñas tu aplicación de música, supongamos que te das cuenta de que la app necesita acceder con frecuencia a las filas de la tabla Albums cuando accede a un Singers fila. Por ejemplo, cuando accedes a la fila Singers(1), también necesitas para acceder a las filas Albums(1, 1) y Albums(1, 2). En este caso, Singers. y Albums deben tener una relación sólida de localidad de datos. Puedes declarar esta relación de localidad de datos creando Albums como un elemento secundario intercalado tabla de Singers.

-- Schema hierarchy:
-- + Singers
--   + Albums (interleaved table, child table of Singers)

La línea en negrita del siguiente esquema muestra cómo crear Albums como tabla intercalada de Singers.

GoogleSQL

CREATE TABLE Singers (
 SingerId   INT64 NOT NULL,
 FirstName  STRING(1024),
 LastName   STRING(1024),
 SingerInfo BYTES(MAX),
 ) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
 SingerId     INT64 NOT NULL,
 AlbumId      INT64 NOT NULL,
 AlbumTitle   STRING(MAX),
 ) PRIMARY KEY (SingerId, AlbumId),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

PostgreSQL

CREATE TABLE singers (
 singer_id   BIGINT PRIMARY KEY,
 first_name  VARCHAR(1024),
 last_name   VARCHAR(1024),
 singer_info BYTEA
 );

CREATE TABLE albums (
 singer_id     BIGINT,
 album_id      BIGINT,
 album_title   VARCHAR,
 PRIMARY KEY (singer_id, album_id)
 )
 INTERLEAVE IN PARENT singers ON DELETE CASCADE;

Notas sobre este esquema:

  • SingerId, que es la primera parte de la clave primaria de la tabla secundaria Albums también es la clave primaria de su tabla superior Singers.
  • La ON DELETE CASCADE indica que cuando se borra una fila de la tabla superior, su las filas secundarias también se borran automáticamente. Si una tabla secundaria no tiene esta anotación, o la anotación es ON DELETE NO ACTION, debes borra las filas secundarias antes de borrar la superior.
  • Las filas intercaladas se ordenan primero por las filas de la tabla superior y, luego, por contiguas de la tabla secundaria que comparten la clave primaria del elemento superior. Para Por ejemplo, "Singers(1)", "Albums(1, 1)" y, luego, "Albums(1, 2)".
  • La relación de localidad de los datos de cada cantante y la información del álbum es se conservará si esta base de datos se divide, siempre y cuando el tamaño de una fila Singers y todas sus filas Albums se mantienen por debajo del límite de tamaño de división y que hay no hay hotspot en ninguna de estas Albums filas.
  • La fila superior debe existir antes de que puedas insertar filas secundarias. La fila principal pueden existir en la base de datos o insertarse antes inserción de las filas secundarias en la misma transacción.

Las filas de álbumes se intercalan entre las filas de Singers.

Cómo crear una jerarquía de tablas intercaladas

La relación de superior y secundaria entre Singers y Albums se puede extender a más tablas descendientes. Por ejemplo, puedes crear una tabla intercalada llamada Songs como secundaria de Albums para almacenar la lista de pistas de cada álbum:

Tabla Canciones con seis filas y cuatro columnas

Songs debe tener una clave primaria que incluya todas las claves primarias de las tablas que están en un nivel superior en la jerarquía, es decir, SingerId y AlbumId.

-- Schema hierarchy:
-- + Singers
--   + Albums (interleaved table, child table of Singers)
--     + Songs (interleaved table, child table of Albums)

GoogleSQL

CREATE TABLE Singers (
 SingerId   INT64 NOT NULL,
 FirstName  STRING(1024),
 LastName   STRING(1024),
 SingerInfo BYTES(MAX),
) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
 SingerId     INT64 NOT NULL,
 AlbumId      INT64 NOT NULL,
 AlbumTitle   STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId),
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

CREATE TABLE Songs (
 SingerId     INT64 NOT NULL,
 AlbumId      INT64 NOT NULL,
 TrackId      INT64 NOT NULL,
 SongName     STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId, TrackId),
 INTERLEAVE IN PARENT Albums ON DELETE CASCADE;

PostgreSQL

CREATE TABLE singers (
 singer_id   BIGINT PRIMARY KEY,
 first_name  VARCHAR(1024),
 last_name   VARCHAR(1024),
 singer_info BYTEA
 );

CREATE TABLE albums (
 singer_id     BIGINT,
 album_id      BIGINT,
 album_title   VARCHAR,
 PRIMARY KEY (singer_id, album_id)
 )
 INTERLEAVE IN PARENT singers ON DELETE CASCADE;

CREATE TABLE songs (
 singer_id     BIGINT,
 album_id      BIGINT,
 track_id      BIGINT,
 song_name     VARCHAR,
 PRIMARY KEY (singer_id, album_id, track_id)
 )
 INTERLEAVE IN PARENT albums ON DELETE CASCADE;

En el siguiente diagrama, se representa una vista física de las filas intercaladas.

Las canciones se intercalan en los álbumes, que también se intercalan entre los cantantes.

En este ejemplo, a medida que aumenta la cantidad de cantantes, Spanner agrega límites entre cantantes para preservar la localidad de datos entre un cantante y su datos de álbumes y canciones. Sin embargo, si el tamaño de una fila de cantantes y sus filas secundarias supere el límite del tamaño de la división o se detecte un hotspot en las filas secundarias. Spanner intenta agregar límites de división para aislar el hotspot. junto con todas las filas secundarias debajo.

En resumen, una tabla superior junto con todas sus tablas secundarias y descendientes forman una jerarquía de tablas en el esquema. Aunque cada tabla en la jerarquía independiente de forma lógica, intercalarlas físicamente de esta manera puede mejorar rendimiento, lo que permite una unión previa eficaz de las tablas y te permite acceder entre filas relacionadas y, al mismo tiempo, minimiza los accesos al almacenamiento.

Uniones con tablas intercaladas

Si es posible, une los datos de las tablas intercaladas por clave primaria. Debido a que cada por lo general, se almacena físicamente en la misma división que su superior por clave primaria de forma local, lo que minimiza el acceso al almacenamiento y el tráfico de red. En el siguiente ejemplo, Singers y Las Albums se unen en la clave primaria SingerId.

GoogleSQL

SELECT s.FirstName, a.AlbumTitle
FROM Singers AS s JOIN Albums AS a ON s.SingerId = a.SingerId;

PostgreSQL

SELECT s.first_name, a.album_title
FROM singers AS s JOIN albums AS a ON s.singer_id = a.singer_id;

Columnas de clave

Esta sección incluye algunas notas sobre las columnas clave.

Cambiar las claves de la tabla

No es posible modificar las claves de una tabla. Es decir, no puedes agregar una columna de clave a una tabla existente ni quitar una columna de clave que ya exista.

Almacena los valores NULL en una clave primaria

En GoogleSQL, si quieres almacenar NULL en una columna de clave primaria, omitir la cláusula NOT NULL para esa columna en el esquema (Las bases de datos de dialectos de PostgreSQL no admiten valores NULL en una columna de clave primaria).

Este es un ejemplo de omisión de la cláusula NOT NULL en la columna de clave primaria SingerId. Ten en cuenta que, debido a que SingerId es la clave primaria, solo puede haber una fila que almacena NULL en esa columna.

CREATE TABLE Singers (
  SingerId   INT64,
  FirstName  STRING(1024),
  LastName   STRING(1024),
) PRIMARY KEY (SingerId);

La propiedad para admitir valores NULL de la columna de clave primaria debe coincidir entre las declaraciones de las tablas superior y secundaria. En este ejemplo, NOT NULL para la columna No se permite Albums.SingerId porque Singers.SingerId lo omite.

CREATE TABLE Singers (
  SingerId   INT64,
  FirstName  STRING(1024),
  LastName   STRING(1024),
) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
  SingerId     INT64 NOT NULL,
  AlbumId      INT64 NOT NULL,
  AlbumTitle   STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId),
  INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

Tipos no permitidos

Las siguientes columnas no pueden ser del tipo ARRAY:

  • Las columnas de clave de una tabla
  • Las columnas de clave de un índice

Diseña para multiusuarios

Recomendamos implementar la función multiusuario si almacenas datos que pertenecen a diferentes clientes. Por ejemplo, un servicio de música podría querer almacenar cada el contenido de un sello discográfico por separado.

Multiusuario clásico

La forma clásica de diseñar para multiusuarios es crear una base de datos separada para para cada cliente. En este ejemplo, cada base de datos tiene su propia tabla Singers:

Base de datos 1: Ackworth Records
SingerId FirstName LastName
1MarcRichards
2CatalinaSmith
Base de datos 2: Cama Records
SingerId FirstName LastName
1AliciaTrentor
2GabrielWright
Base de datos 3: Eagan Records
SingerId FirstName LastName
1BenjamínMartínez
2HannahHarris

Multiusuario administrado por el esquema

Otra forma de diseñar para multiusuarios en Spanner es tener todos clientes en una sola tabla en una única base de datos y a usar una diferente clave-valor de cada cliente. Por ejemplo, puedes incluir una clave CustomerId. en tus tablas. Si haces que CustomerId sea la primera columna de clave, el datos de cada cliente tienen una buena localidad. Spanner puede usar de manera eficaz divisiones de bases de datos para maximizar y el rendimiento según el tamaño de los datos y los patrones de carga. En el siguiente ejemplo, hay una sola tabla Singers para todos los clientes:

Base de datos de multiusuarios de Spanner
CustomerId SingerId FirstName LastName
11MarcRichards
12CatalinaSmith
21AliciaTrentor
22GabrielWright
31BenjamínMartínez
32HannahHarris

Si debes tener bases de datos separadas para cada usuario, se deben aplicar restricciones debes tener en cuenta lo siguiente:

  • Hay límites sobre la cantidad de bases de datos por instancia. y la cantidad de índices y tablas por base de datos. Según la cantidad de con los clientes, tal vez no sea posible tener bases de datos o tablas separadas.
  • Agregar nuevas tablas e índices no intercalados puede llevar mucho tiempo tiempo. Es posible que no obtener el rendimiento que deseas si el diseño de tu esquema depende agregando nuevos índices y tablas.

Si quieres crear bases de datos independientes, podrías tener más éxito si distribuyes las tablas en bases de datos de manera que cada base tenga una cantidad baja de cambios de esquema por semana.

Si creas índices y tablas independientes para cada cliente de tu aplicación, no pongas todas las tablas y los índices en la misma base de datos. En cambio, divide en muchas bases de datos para mitigar el rendimiento problemas cuando se crea una gran cantidad de índices.

Para obtener más información sobre otros patrones de administración de datos y el diseño de aplicaciones de multiusuario, consulta Cómo implementar multiusuarios Spanner