Şöyle yaparız
pgloader mysql://user:pass@10.10.10.10:3306/zabbix \postgresql://user:pass@10.10.10.1:31320/zabbix
Orçun Çolak'ın her şeyden bir parça notları
pgloader mysql://user:pass@10.10.10.10:3306/zabbix \postgresql://user:pass@10.10.10.1:31320/zabbix
Açıklaması şöylean extension that transforms materialized views into self-updating, always-fresh data structures that update instantly as your base data changes.
Under the Hood: How pg_ivm WorksWhen you create an incremental materialized view, pg_ivm automatically:1. Installs triggers on all referenced base tables2. Captures changes through INSERT/UPDATE/DELETE monitoring3. Calculates deltas to determine the minimal impact4. Updates the view with only the necessary changes
The Good: Allows queries during refresh (requires a unique index)The Bad: Still recomputes the entire view from scratchThe Reality: Better UX, but still expensive and slow for large datasets.
REFRESH MATERIALIZED VIEW CONCURRENTLY sales_summary;
The Good: Simple and straightforwardThe Bad: Locks the entire view during refresh, blocking all queriesThe Reality: Your users stare at loading spinners while the view rebuilds
REFRESH MATERIALIZED VIEW sales_summary;
CREATE OR REPLACE FUNCTION create_journal_table()RETURNS event_triggerLANGUAGE plpgsqlAS $$DECLAREobj record;schema_name text;table_name text;journal_table_name text;BEGINFOR obj INSELECT * FROM pg_event_trigger_ddl_commands()LOOPIF obj.command_tag = 'CREATE TABLE' AND obj.object_type = 'table' THENschema_name := split_part(obj.object_identity, '.', 1);table_name := split_part(obj.object_identity, '.', 2);schema_name := trim(both '"' from schema_name);table_name := trim(both '"' from table_name);-- Skip journal tables to avoid recursionIF right(table_name, 8) = '_journal' THENCONTINUE;END IF;journal_table_name := format('%I.%I_journal', schema_name, table_name);EXECUTE format('CREATE TABLE IF NOT EXISTS %s (id bigserial PRIMARY KEY,action text NOT NULL,changed_at timestamptz DEFAULT now(),old_data jsonb,new_data jsonb)', journal_table_name);EXECUTE format('CREATE TRIGGER %I_to_journalAFTER INSERT OR UPDATE OR DELETE ON %I.%IFOR EACH ROWEXECUTE FUNCTION log_to_journal()',table_name, schema_name, table_name);END IF;END LOOP;END;$$;
CREATE EVENT TRIGGER create_journal_after_table
ON ddl_command_end
WHEN TAG IN ('CREATE TABLE')
EXECUTE FUNCTION create_journal_table();CREATE OR REPLACE FUNCTION log_to_journal()RETURNS triggerLANGUAGE plpgsqlAS $$DECLAREjournal_table text;BEGINjournal_table := format('%I.%I_journal', TG_TABLE_SCHEMA, TG_TABLE_NAME);IF TG_OP = 'INSERT' THENEXECUTE format('INSERT INTO %s (action, old_data, new_data) VALUES ($1, $2::jsonb, $3::jsonb)',journal_table)USING TG_OP, NULL, to_jsonb(NEW);ELSIF TG_OP = 'UPDATE' THENEXECUTE format('INSERT INTO %s (action, old_data, new_data) VALUES ($1, $2::jsonb, $3::jsonb)',journal_table)USING TG_OP, to_jsonb(OLD), to_jsonb(NEW);ELSIF TG_OP = 'DELETE' THENEXECUTE format('INSERT INTO %s (action, old_data, new_data) VALUES ($1, $2::jsonb, $3::jsonb)',journal_table)USING TG_OP, to_jsonb(OLD), NULL;END IF;RETURN NULL; -- AFTER triggerEND;$$;
Use JSON_TABLE() to transform JSON data into tabular format.
SELECT *FROM JSON_TABLE('[{"name":"Alice","age":30},{"name":"Bob","age":25}]','$[*]'COLUMNS(name TEXT PATH '$.name', age INT PATH '$.age')) AS jt;
You can now use it MERGE ... RETURNING to retrieve rows that were inserted, updated, or deleted—all in one go.
MERGE INTO employees AS eUSING new_data AS dON e.id = d.idWHEN MATCHED THENUPDATE SET salary = d.salaryWHEN NOT MATCHED THENINSERT (id, salary) VALUES (d.id, d.salary)RETURNING *;