Secuencias en Oracle: de NEXTVAL a las columnas IDENTITY
Durante veinte años la clave sustituta en Oracle fue una secuencia más un disparador. Desde 12c, la base de datos genera los identificadores sola.
Toda tabla acaba necesitando una clave primaria sin significado de negocio, y en Oracle la respuesta histórica fue siempre la misma pieza: una secuencia, un generador atómico de números enteros que vive en la base de datos. Es un objeto tan antiguo como exitoso, y su historia reciente —la llegada de las columnas IDENTITY en 12c— cuenta bastante sobre cómo evoluciona el motor: absorbiendo patrones que los desarrolladores llevábamos décadas montando a mano.
El objeto clásico
CREATE SEQUENCE seq_clientes
START WITH 1
INCREMENT BY 1
MAXVALUE 999999999
NOCYCLE
CACHE 20;
SELECT seq_clientes.NEXTVAL FROM dual; -- 1
SELECT seq_clientes.CURRVAL FROM dual; -- 1 (en tu sesion)NEXTVAL avanza y devuelve el siguiente número; CURRVAL devuelve el último que tu sesión obtuvo (y error si aún no has llamado a NEXTVAL). El patrón JDBC canónico para insertar y recuperar la clave en la misma operación:
String[] cols = {"id"};
try (PreparedStatement ps = con.prepareStatement(
"INSERT INTO clientes (id, nombre) VALUES (seq_clientes.NEXTVAL, ?)",
cols)) {
ps.setString(1, "ACME");
ps.executeUpdate();
try (ResultSet keys = ps.getGeneratedKeys()) {
keys.next();
long id = keys.getLong(1);
}
}CACHE y los huecos: matemáticas de la concurrencia
Una secuencia no es una fila con un contador: es un objeto diseñado para sobrevivir a miles de sesiones pidiendo números a la vez. Con CACHE 20, cada instancia mantiene veinte valores preparados en memoria; si la base de datos cae, esos veinte números se pierden para siempre. De ahí la propiedad más incomprendida de las secuencias: garantizan unicidad, no continuidad. Los ROLLBACK también tragan valores. Si tu facturación exige números correlativos, la numeración la debe imponer una tabla de contadores con bloqueo, no una secuencia — y conviene firmar ese compromiso con el auditor por escrito.
El patrón prehistórico: secuencia más disparador
CREATE OR REPLACE TRIGGER trg_clientes
BEFORE INSERT ON clientes
FOR EACH ROW
BEGIN
IF :new.id IS NULL THEN
SELECT seq_clientes.NEXTVAL INTO :new.id FROM dual;
END IF;
END;
/Este disparador fue el estándar de facto de los años 2000: el INSERT no mencionaba la clave y el disparador la rellenaba. Funciona, pero cuesta una llamada al motor por fila y esquinas sorprendentes en cargas masivas con /*+ APPEND */. En 11g se simplificó algo al permitir :new.id := seq_clientes.NEXTVAL; sin SELECT ... FROM dual, y en 12c la solución llegó de raíz.
12c en adelante: IDENTITY y DEFAULT ON NULL
CREATE TABLE facturas (
id NUMBER GENERATED ALWAYS AS IDENTITY
PRIMARY KEY, -- la BD crea y gestiona la secuencia
total NUMBER(10,2) NOT NULL
);
-- alternativa flexible: GENERATED BY DEFAULT ON NULL
INSERT INTO facturas (total) VALUES (240.00);Con GENERATED ALWAYS, la base de datos crea una secuencia interna, la vincula a la columna y rechaza cualquier id manual: es imposible equivocarse. Con BY DEFAULT ON NULL puedes seguir aportando tu propio número cuando importa (migraciones, integraciones), y Oracle usa el automático el resto del tiempo. Detrás sigue habiendo una secuencia —visible en USER_TAB_IDENTITY_COLS—, así que todo lo dicho sobre huecos y caché sigue aplicando. La síntesis es clara: en 12c+ usa IDENTITY; usa una secuencia suelta solo cuando el número se comparte entre tablas o se consume desde fuera de la base de datos.
Rendimiento en cargas masivas
- Incrementa el
CACHE(200, 500) en cargas ETL: reduce contención en el diccionario y apenas cuesta nada. - Evita
ORDERen RAC salvo necesidad real: fuerza coordinación entre nodos. - En JDBC, los lotes con
addBatchjunto a IDENTITY conviven bien desde los drivers actuales; hace unos años había que usarRETURNINGmanual.
Las secuencias también son compañeras naturales del MERGE INTO para hacer upserts —insertar lo nuevo sin duplicar— y de cualquier carga por JDBC que inserte filas con clave generada. En el terreno del diagnóstico, la vista USER_SEQUENCES se cuenta entre las consultas útiles del diccionario.