PostgreSQL: рд╡рд┐рддрд░рд┐рдд рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдЕрджреНрд╡рд┐рддреАрдп рдХреБрдВрдЬрд┐рдпрд╛рдБред рдЕрднреНрдпрд╛рд╕

рд▓реЗрдЦ рдХреЗ рдирдХреНрд╢реЗрдХрджрдо рдкрд░ рдЪрд▓рддреЗ рд╣реБрдП "рдПрдХ рд╡рд┐рддрд░рд┐рдд рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рдХреБрдВрдЬреА ред "

рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЖрдзрд╛рд░ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЖрджрд░реНрд╢ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ рдПрдХ рдорд╛рд╕реНрдЯрд░-рдорд╛рд╕реНрдЯрд░ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рд╕рдмрд╕реЗ рдХрдард┐рди рдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╕рднреА рд╕рд░реНрд╡рд░реЛрдВ рдкрд░ рдЪрд╛рдмрд┐рдпреЛрдВ рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реИред рдФрд░ рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдЕрдЧрд░ рдореВрд▓ рд░реВрдк рд╕реЗ рдЖрдзрд╛рд░ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдХрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ ... рдлрд┐рд░, рдпрд╣ рдЖрджрд░реНрд╢ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдХреБрдЫ рд╣реИ рдЬреЛ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдРрд╕рд╛ рдХрд╣рддреЗ рд╣реИрдВ, рдЕрдХреНрд╕рд░ рдирд╣реАрдВред

рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реИ рдЬрд┐рд╕реЗ рдорд╛рд╕реНрдЯрд░-рдорд╛рд╕реНрдЯрд░ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рд╣рдо рдЕрдкрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рд╕рднреА рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рднреАрддрд░ рдЕрджреНрд╡рд┐рддреАрдп рдмрдирд╛ рджреЗрдВрдЧреЗред

рд▓реЗрдЦ рдореЗрдВ рдХрдИ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрдВрд╕реНрдЯрд╛рдЧреНрд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рд╕реБрдЭрд╛рдП рдЧрдП рдПрдХ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗ

рдЪрд░рдг 1 - рд╕рднреА рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рдмрд┐рдЧрд┐рдВрдЯ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ


рдпрд╣рд╛рдВ рдпрд╣ рд╕рдордЭрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реА рд╕рднреА рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рдЖрдИрдбреА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдЗрди рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝реАрд▓реНрдб рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдирд╛рдорд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ: рдСрд░реНрдбрд░_рдб, рдХреНрд▓рд╛рдЗрдВрдЯ_рдЖрдИрдбреА, рдЯреЗрдмрд▓_рдЖрдИрдбреА ...

рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдПрдВ рдЬреЛ рдкреВрд░реНрдгрд╛рдВрдХ рдлрд╝реАрд▓реНрдб рдХреЛ рдмрд┐рдЧрд┐рдВрдЯ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИ
DROP FUNCTION IF EXISTS "field_int2big" (field text, tablename text, table_schema text); CREATE OR REPLACE FUNCTION "field_int2big" (field text, tablename text, table_schema text) RETURNS bigint AS $body$ DECLARE BEGIN EXECUTE 'ALTER TABLE '|| table_schema || '."'|| tablename || '" ALTER COLUMN "'|| field || '" TYPE bigint;' ; return 1; END; $body$ LANGUAGE 'plpgsql'; 


рдЗрд╕рдХреЗ рдмрд╛рдж, рд╕рднреА рдкреВрд░реНрдгрд╛рдВрдХ рдлрд╝реАрд▓реНрдб рдЪреБрдиреЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░реЗрдВ:
 select *, field_int2big(column_name, table_name, table_schema) from (select table_catalog, table_schema, table_name, column_name, data_type from information_schema.columns where table_schema in ('public', 'myscheme') and data_type in ('integer', 'oid') and (position('id' in column_name)>0 OR column_name in ('key', 'myfield')) order by table_catalog, table_schema, table_name, column_name limit 10 offset 0) c 

рдХреБрдЫ рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╛рд╣рд░ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП:
  1. рдЖрдк рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рд╕реНрдХреАрдорд╛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ: table_schema рдЗрди ('рдкрдмреНрд▓рд┐рдХ', 'myscheme')
  2. рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдлрд╝реАрд▓реНрдб рдХреЛ "рдорд╛рдирдХ" рдирд╛рдо рд╕реЗ рднреА рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ: column_name рдЗрди ('рдХреБрдВрдЬреА', 'myfield')
  3. рдмрдбрд╝реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рд▓рд┐рдП 10 рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рдЖрдкрдХреЛ рдЗрд╕реЗ 1 рд╕реЗ рдХрдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдкреНрд░рдХрд╛рд░ рдмрджрд▓рдиреЗ рдореЗрдВ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рдЫреЛрдЯрд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ
  4. рдХреНрд╡реЗрд░реА рдХреЛ рдХрдИ рдмрд╛рд░ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд╣рд░ рдмрд╛рд░ рдпрд╣ рд╢реЗрд╖ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдирд╣реАрдВ рдвреВрдВрдвреЗрдЧрд╛


рдЪрд░рдг 2 - рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░рддреНрдпрдХреНрд╖ рд╕рдВрдХреЗрдд рд╣реЛрддрд╛ рд╣реИ


рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЕрдЧрд░ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ рд▓рд╛рдПрдЧрд╛, рдЙрдирдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдмреЗрд╣рдж рдореБрд╢реНрдХрд┐рд▓ рд╣реИ: рдпрд╣ рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдЕрдиреБрд░реЛрдз рдореЗрдВ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред

 DROP FUNCTION IF EXISTS "index_int2big" (idx text, declare_idx text); CREATE OR REPLACE FUNCTION "index_int2big" (idx text, declare_idx text) RETURNS text AS $body$ DECLARE new_idx text; BEGIN EXECUTE 'DROP INDEX IF EXISTS ' || idx; SELECT replace(declare_idx, 'integer', 'bigint') INTO new_idx; EXECUTE new_idx ; return new_idx; END; $body$ LANGUAGE 'plpgsql'; select *, index_int2big(indname, inddef) from (SELECT n.nspname as table_schema, c.relname as table_name, c2.relname AS indname, i.indisprimary, i.indisunique, i.indisclustered, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) AS inddef FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i, pg_namespace n WHERE n.oid=c.relnamespace and c.oid = i.indrelid AND i.indexrelid = c2.oid and n.nspname in ('bucardo', 'public') and position('integer' in pg_catalog.pg_get_indexdef(i.indexrelid, 0, true))>0 limit 10 offset 0) c 

рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореИрдВ bucardo рд╕рд░реНрдХрд┐рдЯ рдореЗрдВ рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реВрдБред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рддрдХрдиреАрдХ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд╣реИ, рддреЛ рдпрд╣ рдХрджрдо рдмреЗрд╣рдж рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдВрддрд┐рдо рдЪрд░рдг рд╕реЗ рдЯрд┐рдкреНрдкрдгреА рднреА рджреЗрдЦреЗрдВред

рдЪрд░рдг 3 - рд╕рднреА рдореБрдЦреНрдп рдлрд╝реАрд▓реНрдб рдХреЗ рд▓рд┐рдП рдирдП рдЕрдиреБрдХреНрд░рдо рдмрдирд╛рдирд╛


Instagram рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рддреНрдпреЗрдХ рдпреЛрдЬрдирд╛ / рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдпрд╛рдиреА рдкреНрд░рддреНрдпреЗрдХ рд╕рд░реНрдХрд┐рдЯ рдХреА рдЕрдкрдиреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдЕрдкрдирд╛ рдХрд╛рд░реНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдореИрдВрдиреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдереЛрдбрд╝рд╛ рдмрджрд▓ рджрд┐рдпрд╛ рдФрд░ рдЖрдИрдкреА рд╕рд░реНрд╡рд░ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рдХреБрдВрдЬреА рдЙрддреНрдкрдиреНрди рдХреАред

 CREATE OR REPLACE FUNCTION inet2num(inet) RETURNS numeric AS $$ DECLARE a text[] := string_to_array(host($1), '.'); BEGIN RETURN a[1]::numeric * 16777216 + a[2]::numeric * 65536 + a[3]::numeric * 256 + a[4]::numeric; END; $$ LANGUAGE plpgsql IMMUTABLE STRICT; DROP FUNCTION IF EXISTS next_id(tbl text, tableschema text); CREATE OR REPLACE FUNCTION next_id(tbl text, tableschema text = 'public') returns bigint AS $$ DECLARE our_epoch bigint := 1314220021721; seq_id bigint; now_millis bigint; shard_id bigint; result bigint; BEGIN SELECT nextval(tableschema||'."' || tbl || '_id_seq"') % 1024 INTO seq_id; /* select substring(regexp_replace(md5(current_database()||inet_server_addr()||version()), '[^\\\d]+', '', 'g')::text from 1 for 6)::int into shard_id;*/ SELECT inet2num(inet_server_addr()) into shard_id; SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis; result := (now_millis - our_epoch) << 23; result := result | (shard_id << 10); result := result | (seq_id); RETURN result; END; $$ LANGUAGE PLPGSQL; 


рдЕрдм рд╣рдореЗрдВ рдЗрд╕реЗ рдЕрдкрдиреЗ рд╕рднреА рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
 DROP FUNCTION IF EXISTS "reset_nextid" (tablename text, tableschema text); CREATE OR REPLACE FUNCTION "reset_nextid" (tablename text, tableschema text) RETURNS bigint AS $body$ DECLARE id_type text; BEGIN SELECT data_type from information_schema.columns c where "table_schema"=tableschema and "table_name"=tablename and column_name='id' INTO id_type; IF id_type <> 'bigint' THEN EXECUTE 'ALTER TABLE '|| tableschema || '."'|| tablename || '" ALTER COLUMN id TYPE bigint;' ; END IF; EXECUTE 'ALTER TABLE '|| tableschema || '."'|| tablename || '" ALTER COLUMN id SET DEFAULT next_id('''|| tablename || ''', '''|| tableschema || ''');'; return next_id(tablename, tableschema); END; $body$ LANGUAGE 'plpgsql'; select t.*, reset_nextid(table_name, table_schema) from ( select t.table_schema, t.table_name, sequence_name, c.column_name from information_schema.sequences s left join information_schema.tables t on split_part(sequence_name, '_id_seq',1)=table_name left join information_schema.columns c on (t.table_schema=c.table_schema and t.table_name=c.table_name and c.column_name='id') where c.column_name is not null and position('next_id' in c.column_default)<>1 and s.sequence_schema=t.table_schema and t.table_schema in ('public', 'acc') order by t.table_schema, t.table_name limit 50 offset 0 ) as t 


рдХреНрдпреЛрдВрдХрд┐ рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдмрд┐рдЧрд┐рдВрдЯ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рд╣реИ - рдЕрдиреБрд░реЛрдз рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╣рдордиреЗ рдпрд╣ рддреИрдпрд╛рд░реА рдкреВрд░реА рдХрд░ рд▓реА рд╣реИ, рд╣рдорд╛рд░рд╛ рдЖрдзрд╛рд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ рдФрд░ рд╕рдорд╛рдирд╛рдВрддрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред

рдмреЛрдирд╕ред

рдЕрдЧрд░ рдЕрдЧрд▓реЗ рдХреБрдЫ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдЖрдк рдорд╛рдирдХ рджреГрд╢реНрдпреЛрдВ рдкрд░ рд▓реМрдЯ рд╕рдХрддреЗ рд╣реИрдВ:
 CREATE OR REPLACE FUNCTION "restore_nextval" (tablename text, tableschema text = 'public') RETURNS bigint AS $body$ DECLARE BEGIN EXECUTE 'ALTER TABLE '|| tableschema || '."'|| tablename || '" ALTER COLUMN id SET DEFAULT nextval('''|| tablename || '_id_seq''::regclass);'; return nextval((tableschema || '."'|| tablename || '_id_seq"')::regclass); END; $body$ LANGUAGE 'plpgsql'; select t.*, restore_nextval(table_name, table_schema) from ( select t.table_schema, t.table_name, sequence_name, c.column_name from information_schema.sequences s left join information_schema.tables t on split_part(sequence_name, '_id_seq',1)=table_name left join information_schema.columns c on (t.table_schema=c.table_schema and t.table_name=c.table_name and c.column_name='id') where c.column_name is not null and position('next_id' in c.column_default)>0 and s.sequence_schema=t.table_schema and t.table_schema in ('public', 'acc') 


рдЖрдкрдХрд╛ рдзрдиреНрдпрд╡рд╛рдж рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдХреЛрдИ рдорджрджрдЧрд╛рд░ рдерд╛ред

PS 32 рдмрд┐рдЯ рд╕рд░реНрд╡рд░ рдкрд░ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рди рдХрд░реЗрдВред рдкрд╣рд▓реЗ рд╕рд░реНрд╡рд░ рдХреЛ рдЕрдкрдЧреНрд░реЗрдб рдХрд░реЗрдВред рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рд░реНрд╡рд░ рднреАред

Source: https://habr.com/ru/post/In136852/


All Articles