Е, първото нещо, което бих направил, е да премахна неприятния анализ на низове навсякъде и да го заменя с собствени типове на PostgreSQL. За да съхраните състоянието на репликация на всеки запис, подобно на вашето текущо решение:
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[];
Това ви струва малко повече място за съхранение - стойностите на enum са 4 байта вместо 1 и масивите имат някои допълнителни разходи. Въпреки това, като преподавате на базата данни вашите концепции, вместо да ги скривате, можете да пишете неща като:
-- 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[];
Можете да поставите GIN индекс точно в rep_status_array
ако това помага за вашия случай на употреба, но е по-добре да разгледате вашите заявки и да създадете индекси специално за това, което използвате:
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[];
Въпреки това, имайки предвид 200 таблици, бих се изкушил да разделя това в една таблица със състоянието на репликация - или един ред с масив от състояния, или един ред на хост, в зависимост от това как работи останалата част от логиката на репликация. Все още бих използвал това изброяване:
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 вътрешно присвоява на всяка таблица OID (опитайте SELECT *, tableoid FROM t LIMIT 1
), който е удобен стабилен цифров идентификатор в рамките на една система от бази данни. Казано по друг начин, той се променя, ако таблицата бъде премахната и пресъздадена (което може да се случи, ако например изхвърлите и възстановите базата данни) и поради същата причина е много вероятно да е различно между разработката и производството. Ако предпочитате тези ситуации да работят в замяна на прекъсване, когато добавяте или преименувате таблица, използвайте изброяване вместо OID.
Използването на една таблица за цялата репликация ще ви позволи лесно да използвате повторно тригери и заявки и други подобни, отделяйки повечето репликационни логики от данните, които репликира. Той също така ви позволява да правите заявки въз основа на състоянието на даден хост във всичките си таблици на произход, като се позовавате на един индекс, което може да е важно.
Що се отнася до размера на таблицата, PostgreSQL определено може да се справи с 10 милиона реда в една и съща таблица. Ако сте използвали специална таблица, свързана с репликация, винаги можете да дял на хост. (Разделянето по таблица няма голям смисъл за мен; изглежда по-лошо от съхраняването на състоянието на репликация на всеки ред нагоре по веригата.) Кой начин за разделяне или дали изобщо е подходящ или не, зависи изцяло от вида на въпросите, които възнамерявате да зададете на вашата база данни, и какъв вид дейност се случва на базовите маси. (Дяловете означава поддържане на много по-малки петна вместо няколко големи и потенциален достъп до много по-малки петна за извършване на една операция.) Всъщност е въпрос на избор кога искате вашият диск да се случи.