Une solution alternative à ce problème consiste à utiliser des colonnes de tableau au lieu de lignes et le support INSERT INTO ... ON CONFLICT UPDATE ...
.
Exemple en ligne : https://www.db-fiddle.com/f/2y46V6EEVJLQ5cPNTDAUPy/0
Structure:
CREATE TABLE test_rr (
id serial primary key,
fk_1 integer not null,
fk_2 integer not null,
latest timestamptz[] not null
);
CREATE UNIQUE INDEX idx_unique_rr ON test_rr (fk_1, fk_2);
Insertion des données:
INSERT INTO test_rr (fk_1, fk_2, latest)
VALUES (1, 2, array[current_timestamp])
ON CONFLICT (fk_1, fk_2) DO UPDATE SET latest = (array_cat(EXCLUDED.latest, test_rr.latest))[:10];
Sélection des entrées:
SELECT id, fk_1, fk_2, unnest(latest) AS ts FROM test_rr WHERE fK_1 = 1 AND fk_2 = 2;
...résultant en :
id | fk_1 | fk_2 | ts
-----+------+------+-------------------------------
652 | 1 | 2 | 2019-03-10 13:28:57.806489+01
652 | 1 | 2 | 2019-03-10 13:28:56.670678+01
652 | 1 | 2 | 2019-03-10 13:28:55.470668+01
652 | 1 | 2 | 2019-03-10 13:28:54.174111+01
652 | 1 | 2 | 2019-03-10 13:28:52.878719+01
652 | 1 | 2 | 2019-03-10 13:28:51.3748+01
652 | 1 | 2 | 2019-03-10 13:28:49.886457+01
652 | 1 | 2 | 2019-03-10 13:28:48.190317+01
652 | 1 | 2 | 2019-03-10 13:28:46.350833+01
652 | 1 | 2 | 2019-03-10 13:11:50.506323+01
(10 rows)
Au lieu de timestamptz[]
, vous pouvez également créer votre propre type pour supporter plus de colonnes :
CREATE TYPE my_entry_data AS (ts timestamptz, data varchar);
CREATE TABLE test_rr (
id serial primary key,
fk_1 integer not null,
fk_2 integer not null,
latest my_entry_data[] not null
);
CREATE UNIQUE INDEX idx_unique_rr ON test_rr (fk_1, fk_2);
-- ...
INSERT INTO test_rr (fk_1, fk_2, latest)
VALUES (1, 2, array[(current_timestamp,'L')::my_entry_data])
ON CONFLICT (fk_1, fk_2) DO UPDATE
SET latest = (array_cat(EXCLUDED.latest, test_rr.latest))[:10];
SELECT id, fk_1, fk_2, tmp.ts, tmp.data
FROM test_rr, unnest(latest) AS tmp -- Appel de fonction LATERAL
WHERE fK_1 = 1 AND fk_2 = 2;
Cependant, des tests de charge doivent montrer si cela est effectivement plus rapide que les déclencheurs ou d'autres approches. Au moins, cela a l'avantage que les lignes seront simplement mises à jour et non insérées + supprimées, ce qui pourrait économiser quelques E/S.