Yo elegiría un enfoque diferente. En lugar de conservar el número de pieza, conserve el pedido de las partes:
CREATE TABLE book_part (
book_id bigint NOT NULL,
part_order real NOT NULL,
name text NOT NULL,
PRIMARY KEY (book_id, part_order)
);
La primera parte que se ingresa obtiene un part_order
de 0.0. Si agrega una parte al principio o al final, simplemente asigne a part_order
1,0 menos o más que el mínimo o máximo anterior. Si inserta una parte entre dos partes existentes, asigna un part_order
esa es la media aritmética de las partes adyacentes.
Un ejemplo:
-- insert the first part
INSERT INTO book_part VALUES (1, 0.0, 'Introduction');
-- insert a part at the end
INSERT INTO book_part VALUES (1, 1.0, 'Getting started with PostgreSQL');
-- insert a part between the two existing parts
INSERT INTO book_part VALUES (1, 0.5, 'The history of PostgreSQL');
-- adding yet another part between two existing parts
INSERT INTO book_part VALUES (1, 0.25, 'An introductory example');
El número de pieza real se calcula cuando consulta la tabla:
SELECT book_id,
row_number() OVER (PARTITION BY book_id ORDER BY part_order) AS part,
name
FROM book_part;
Lo bueno de eso es que no necesita actualizar muchas filas cuando agrega o elimina una parte.