sql >> Databáze >  >> RDS >> PostgreSQL

Návrh datové struktury pro podporu replikace databáze

No, první věc, kterou bych udělal, je vypustit všude analýzu icky řetězců a nahradit je nativními typy PostgreSQL. Chcete-li uložit stav replikace na každý záznam podobný vašemu aktuálnímu řešení:

CREATE TYPE replication_status AS ENUM (
  'no_action',
  'replicate_record',
  'record_replicated',
  'error_1',
  'error_2',
  'error_3'
  );
ALTER TABLE t ADD COLUMN rep_status_array replication_status[];

To vás stojí trochu více úložného prostoru -- hodnoty enum jsou 4 bajty místo 1 a pole mají určitou režii. Pokud však databázi naučíte své koncepty namísto jejich skrývání, můžete psát věci jako:

-- find all records that need to be replicated to host 4
SELECT * FROM t WHERE rep_status_array[4] = 'replicate_record';

-- find all records that contain any error status
SELECT * FROM t WHERE rep_status_array &&
  ARRAY['error_1', 'error_2', 'error_3']::replication_status[];

Index GIN můžete umístit přímo na rep_status_array pokud to pomůže vašemu případu použití, ale je lepší podívat se na své dotazy a vytvořit indexy konkrétně pro to, co používáte:

CREATE INDEX t_replication_host_4_key ON t ((rep_status_array[4]));
CREATE INDEX t_replication_error_key ON t (id)
  WHERE rep_status_array && ARRAY['error_1', 'error_2', 'error_3']::replication_status[];

To znamená, že vzhledem k 200 tabulkám bych byl v pokušení rozdělit to do jediné tabulky stavu replikace - buď jeden řádek s polem stavů, nebo jeden řádek na hostitele, v závislosti na tom, jak funguje zbytek logiky replikace. Stále bych použil tento výčet:

CREATE TABLE adhoc_replication (
  record_id bigint not null,
  table_oid oid not null,
  host_id integer not null,
  replication_status status not null default 'no_action',
  primary key (record_id,table_oid,host_id)
  );

PostgreSQL interně přiřadí každé tabulce OID (zkuste SELECT *, tableoid FROM t LIMIT 1 ), což je pohodlný stabilní číselný identifikátor v rámci jednoho databázového systému. Jinými slovy, změní se, pokud je tabulka zrušena a znovu vytvořena (což se může stát, pokud například vypíšete a obnovíte databázi), a ze stejného důvodu je velmi pravděpodobné, že se liší mezi vývojem a výrobou. Pokud byste raději, aby tyto situace fungovaly výměnou za porušení při přidání nebo přejmenování tabulky, použijte místo OID výčet.

Použití jediné tabulky pro veškerou replikaci by vám umožnilo snadno znovu použít spouštěče a dotazy a podobně, oddělit většinu logiky replikace od dat, která replikuje. Umožňuje vám také dotazovat se na základě stavu daného hostitele ve všech tabulkách původu odkazem na jediný index, což může být důležité.

Pokud jde o velikost tabulky, PostgreSQL určitě zvládne 10 milionů řádků ve stejné tabulce. Pokud použijete specializovanou tabulku související s replikací, můžete vždy oddíl na hostitele. (Rozdělení podle tabulky mi nedává smysl; zdá se mi to horší než ukládání stavu replikace na každý nadřazený řádek.) Jaký způsob rozdělení nebo zda je vůbec vhodný, závisí zcela na tom, jaké otázky chcete databázi položit a jaký druh činnosti se odehrává na základních tabulkách. (Rozdělení znamená udržování mnoha menších objektů BLOB namísto několika velkých a potenciální přístup k mnoha menším objektům BLOB za účelem provedení jediné operace.) Je to opravdu otázka výběru, kdy chcete, aby se váš disk měl stát.



  1. Jak mohu vybrat typ hromadné shromážděné tabulky záznamů

  2. Hodnoty oddělené čárkami v klauzuli MySQL IN

  3. Vyberte všechny sloupce větší než nějaká hodnota

  4. Jak vygeneruji sérii hodinových průměrů v MySQL?