En esta página, se analizan las estrategias que puedes usar para generar valores de clave primaria en tu tabla con expresiones de valor predeterminado. La información de esta página se aplica a las bases de datos con dialecto de GoogleSQL y a las bases de datos con dialecto de PostgreSQL. Estas estrategias tienen los siguientes beneficios:
- Evita los hotspots
- Simplifica las migraciones desde otras bases de datos
- Encapsula la lógica clave en la base de datos para que no tengas que preocuparte por administrarla en tu aplicación.
- En la mayoría de los casos, reemplazan la necesidad de crear y administrar tus propias secuencias.
Métodos para generar automáticamente claves primarias
Para generar automáticamente valores de clave principal, puedes usar las siguientes estrategias en una columna que tenga expresiones DEFAULT:
- Es una función de UUID que genera valores de la versión 4 del UUID.
- Columnas
IDENTITYque generan automáticamente valores de números enteros para las columnas clave y no clave. SERIALen PostgreSQL yAUTO_INCREMENTen GoogleSQL, que son alias de DDL para las columnasIDENTITY.- Un objeto de esquema,
SEQUENCE, que tiene una opciónbit_reversed_positive.SEQUENCEestá disponible para GoogleSQL y PostgreSQL.
Identificador único universal (UUID)
Spanner puede generar automáticamente una cadena de UUID versión 4 para usarla como clave primaria. Los UUID funcionan bien para las aplicaciones y las tablas nuevas con muchas filas. Se distribuyen de forma casi uniforme en todo el espacio de claves, lo que evita los puntos calientes a gran escala. La generación de UUID puede crear una gran cantidad de valores (2122), y cada valor es efectivamente único. Por ejemplo, necesitarías 2.71 × 1018 valores para tener un 50% de probabilidad de colisión, o 1,000 millones por segundo durante 86 años. Esto garantiza valores únicos cuando lo usas en tablas grandes. Los UUID son únicos, ya sea que los generes en la base de datos o en el cliente. Te recomendamos que uses UUID siempre que sea posible. Puedes combinar de forma segura los UUIDs generados por el cliente y por Spanner en la misma tabla si los UUIDs generados por el cliente se serializan en minúsculas, de acuerdo con el RFC 4122.
Para una columna que necesita valores predeterminados, puedes usar la función GENERATE_UUID para generarlos. En el siguiente ejemplo, se muestra cómo crear una tabla en la que la columna de clave FanId tiene GENERATE_UUID en la columna de valor como su valor predeterminado.
En el ejemplo, se usan 36 caracteres para los atributos STRING de GoogleSQL y varchar de PostgreSQL porque los UUID tienen 36 caracteres. Cuando usas la declaración INSERT with THEN RETURN para insertar en la tabla Fans, GENERATE_UUID genera y devuelve un valor de UUID para FanId.
GoogleSQL
CREATE TABLE Fans (
FanId STRING(36) DEFAULT (GENERATE_UUID()),
Name STRING(MAX),
) PRIMARY KEY (FanId);
PostgreSQL
CREATE TABLE Fans (
FanId varchar(36) DEFAULT spanner.generate_uuid(),
Name text,
PRIMARY KEY (FanId)
);
GoogleSQL
INSERT INTO Fans (Name) VALUES ('Melissa Garcia')
THEN RETURN FanId;
PostgreSQL
INSERT INTO fans (name) VALUES ('Melissa Garcia')
RETURNING (fanid);
Esta instrucción devuelve un resultado similar al siguiente:
| FanId |
|---|
| 6af91072-f009-4c15-8c42-ebe38ae83751 |
Para obtener más información sobre la función GENERATE_UUID(), consulta la página de referencia de GoogleSQL o PostgreSQL.
IDENTITY columnas
Con las columnas IDENTITY, puedes generar automáticamente valores de números enteros para las columnas clave y no clave. Las columnas IDENTITY no requieren que los usuarios mantengan manualmente una secuencia subyacente ni administren la relación entre la columna y la secuencia subyacente. Cuando se descarta una columna de identidad generada automáticamente, también se borra automáticamente la secuencia subyacente.
Puedes usar columnas IDENTITY proporcionando un valor entero inicial cuando generes la secuencia o dejando que Spanner genere la secuencia de números enteros por ti. Para proporcionar un valor entero inicial, debes usar la opción START COUNTER WITH y un valor inicial INT64 positivo.
Spanner usa este valor para establecer el siguiente valor de su contador de secuencia interno generado automáticamente y revierte los bits del valor antes de insertarlo en esta columna.
En Spanner, las columnas IDENTITY son compatibles con GoogleSQL y PostgreSQL.
GoogleSQL
En el siguiente ejemplo, se muestra cómo usar columnas IDENTITY para crear una columna de clave principal de números enteros generada automáticamente para SingerId cuando se crea una tabla nueva con el comando CREATE TABLE:
CREATE TABLE Singers (
SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
Name STRING(MAX),
Rank INT64
) PRIMARY KEY (SingerId);
También puedes especificar el inicio del contador para la columna con la opción START_WITH_COUNTER. En el siguiente ejemplo, se crea una columna de números enteros generada automáticamente para SingerId que tiene valores positivos invertidos en bits y un contador interno que comienza en 1,000.
CREATE TABLE Singers (
SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
Name STRING(MAX),
Rank INT64
) PRIMARY KEY (SingerId);
PostgreSQL
En el siguiente ejemplo, se muestra cómo usar las columnas IDENTITY para crear una columna de números enteros generada automáticamente para SingerId cuando se crea una tabla nueva con el comando CREATE
TABLE:
CREATE TABLE Singers (
SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
Name text,
PRIMARY KEY (SingerId)
);
También puedes especificar el inicio del contador para la columna con la opción START COUNTER WITH. En el siguiente ejemplo, se crea una columna de números enteros generada automáticamente para SingerId que genera valores positivos invertidos en bits, y el contador interno, antes de la inversión de bits, comienza en 1,000.
CREATE TABLE Singers (
SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
Name text,
PRIMARY KEY (SingerId)
);
SERIAL y AUTO_INCREMENT
Spanner admite SERIAL en PostgreSQL y AUTO_INCREMENT en GoogleSQL, que son alias de DDL para las columnas IDENTITY y se usan para crear columnas de números enteros únicos. Primero debes establecer la opción de base de datos default_sequence_kind antes de usar SERIAL o AUTO_INCREMENT.
Puedes usar la siguiente instrucción de SQL para establecer la opción default_squence_kind de la base de datos:
GoogleSQL
ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');
CREATE TABLE Singers (
id INT64 AUTO_INCREMENT PRIMARY KEY,
name STRING(MAX),
)
PostgreSQL
ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';
CREATE TABLE Singers (
id serial PRIMARY KEY,
name text
);
Ten en cuenta que, como SERIAL y AUTO_INCREMENT se asignan a columnas IDENTITY, no las verás cuando serialices tu esquema. Para este esquema, el resultado de GetDatabaseDDL sería el siguiente:
GoogleSQL
ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');
CREATE TABLE Singers (
id INT64 GENERATED BY DEFAULT AS IDENTITY,
name STRING(MAX),
) PRIMARY KEY (id);
PostgreSQL
ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';
CREATE TABLE Singers (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name character varying,
PRIMARY KEY(id)
);
Secuencia con bits invertidos
Una secuencia con bits invertidos es un objeto de esquema que produce una secuencia de números enteros y les invierte los bits. Este objeto usa la inversión de bits en un contador interno y privado de Spanner para garantizar la unicidad. Los valores invertidos en bits resultantes ayudan a evitar los hotspots a gran escala cuando se usan en una clave primaria.
En Spanner, usas instrucciones de DDL de SEQUENCE junto con el atributo bit_reversed_positive para crear, modificar o descartar una secuencia que produce valores positivos invertidos en bits (GoogleSQL o PostgreSQL).
Cada secuencia mantiene un conjunto de contadores internos y los usa para generar un valor. El contador de secuencia proporciona la entrada al algoritmo de inversión de bits.
Cuando defines una columna con una expresión DEFAULT que usa la función GET-NEXT-SEQUENCE-VALUE de GoogleSQL o la función nextval de PostgreSQL como su valor predeterminado, Spanner llama automáticamente a la función y coloca los valores de salida invertidos en bits en la columna. Las secuencias con bits invertidos son especialmente útiles para las claves primarias, ya que los valores con bits invertidos se distribuyen de manera uniforme en el espacio de claves, por lo que no causan hotspots.
En el siguiente ejemplo, se muestra cómo crear una secuencia invertida en bits y una tabla en la que su columna de clave usa la secuencia como valor predeterminado:
GoogleSQL
CREATE SEQUENCE SingerIdSequence OPTIONS (
sequence_kind="bit_reversed_positive"
);
CREATE TABLE Singers (
SingerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)),
Name STRING(MAX),
Rank INT64,
) PRIMARY KEY (SingerId);
PostgreSQL
CREATE SEQUENCE SingerIdSequence bit_reversed_positive;
CREATE TABLE Singers (
SingerId bigint DEFAULT nextval('SingerIdSequence'),
Name text,
PRIMARY KEY (SingerId)
);
Luego, puedes usar la siguiente instrucción de SQL para insertar y devolver el valor de la clave principal:
GoogleSQL
INSERT INTO Singers (Name) VALUES ('Melissa Garcia')
THEN RETURN SingerId;
PostgreSQL
INSERT INTO Singers (name) VALUES ('Melissa Garcia')
RETURNING (SingerId);
Esta instrucción devuelve un resultado similar al siguiente:
| SingerId |
|---|
| 3458764513820540928 |
Situaciones en las que se usan UUID y secuencias como valores predeterminados para las claves primarias
Las situaciones para los UUID y las secuencias incluyen lo siguiente:
- Aplicaciones nuevas
- Migraciones
En las siguientes secciones, se describe cada situación.
Aplicaciones nuevas
Si tu aplicación existente requiere claves INT64 en GoogleSQL o claves bigint en PostgreSQL, Spanner ofrece el objeto de esquema de secuencia positiva con bits invertidos (PostgreSQL o
GoogleSQL). De lo contrario, para las aplicaciones nuevas, te recomendamos que uses un identificador único universal (UUID).
Para obtener más información, consulta Usa un identificador único universal (UUID).
Migraciones
Para migrar tablas a Spanner, tienes algunas opciones:
- Si usas UUIDs en tu base de datos de origen, en Spanner, puedes usar una columna de clave en el tipo
STRINGy la funciónGENERATE_UUID()(GoogleSQL o PostgreSQL) como su valor predeterminado. - Si usas una clave principal de número entero y tu aplicación solo necesita que la clave sea única, puedes usar una columna de clave en
INT64y una secuencia positiva invertida en bits para el valor predeterminado de la clave principal. Consulta Migración de columnas de claves con inversión de bits. Spanner no admite una forma de generar valores monotónicos.
Si usas una clave monotónica, como el tipo
SERIALde PostgreSQL o el atributoAUTO_INCREMENTde MySQL, y necesitas claves monotónicas nuevas en Spanner, puedes usar una clave compuesta. Para obtener más información, consulta Cómo intercambiar el orden de las claves y Cómo generar un hash de la clave única y distribuir las escrituras en fragmentos lógicos.Si tu aplicación invierte manualmente los bits de tu clave
INT64en GoogleSQL o de tu clavebiginten PostgreSQL, puedes usar una secuencia positiva con bits invertidos (GoogleSQL o PostgreSQL) y hacer que genere nuevos valores de clave para ti. Para obtener más información, consulta Migra columnas de claves con inversión de bits.
¿Qué sigue?
- Obtén más información para usar secuencias con control de acceso detallado.
- Obtén información sobre las sentencias DDL de GoogleSQL o PostgreSQL.
SEQUENCE - Obtén información sobre las funciones de secuencia en GoogleSQL o PostgreSQL.
- Obtén información sobre las secuencias en INFORMATION_SCHEMA en GoogleSQL o PostgreSQL.
- Obtén información sobre las opciones de secuencia en INFORMATION_SCHEMA para GoogleSQL.