Wir haben eine Tabelle zum Tracking von Suchwörtern, d.h. den Bestandteilen einer Suchphrase:
1 2 3 4 5 6 7 8 9 |
CREATE TABLE stats.tracking_keywords ( id bigserial, keyword text NOT NULL, site_id integer NOT NULL, created timestamp without time zone NOT NULL, user_id integer NOT NULL, CONSTRAINT "pk_t_kw" PRIMARY KEY (id) )WITHOUT OIDS; |
Um jetzt aus einer um Dropwords und bösartigen/dämlichen Blödsinn (nicht druckbare Zeichen, Deppen-Apostrophe, ggf. Satzzeichen) bereinigten Phrase die einzelnen Keywords einzufügen, kann man die Phrase natürlich im Applikationscode an den Leerzeichen splitten und dann in einem Loop die einzelnen Wörter einfügen. Aus einer Suchphrase von drei Wörtern werden dann drei einzelne INSERT-Statements.
Es geht aber auch eleganter.
1 2 3 4 5 6 |
INSERT INTO playground.tracking_keywords (keyword, site_id, user_id, created) WITH n AS (SELECT 1 AS site_id, -1 AS user_id, now() AS created) SELECT t.keyword, n.site_id, n.user_id, n.created FROM ( SELECT unnest(string_to_array(trim('hier ist mein gesäuberter Suchstring'), ' ')) AS keyword ) AS t, n |
Mit string_to_array zerlegen wir den String an den Leerzeichen in ein Array von Strings, mit unnest wandeln wir das Array in eine Tupel-Menge um und JOINen dann die Common Table Expression mit User-ID und Datum drauf. Somit brauchen wir keine Transaktion, um einen atomaren INSERT für die gesamte Phrase zu erreichen und haben nicht nur wegen der reduzierten Trips zur Datenbank, sondern auch wegen der zusammengefassten Schreiboperation einen Performance-Gewinn für Datenbank und Applikation – instant win-win.