当前位置: 首页 > news >正文

Postgres数据库自动化分区

一.创建自动化分区配置表并插入数据

-- Table: managerdb.par_info-- DROP TABLE IF EXISTS managerdb.par_info;CREATE TABLE IF NOT EXISTS managerdb.par_info
(table_schema character varying(255) COLLATE pg_catalog."default" NOT NULL,table_name character varying(255) COLLATE pg_catalog."default" NOT NULL,par_column character varying(255) COLLATE pg_catalog."default",keep_data_days bigint,step_length bigint,create_next_intervals bigint,update_time timestamp with time zone NOT NULL DEFAULT now(),min_partition_name character varying(300) COLLATE pg_catalog."default",max_partition_name character varying(300) COLLATE pg_catalog."default",CONSTRAINT par_info_pkey PRIMARY KEY (table_schema, table_name)
)TABLESPACE pg_default;ALTER TABLE IF EXISTS managerdb.par_infoOWNER to postgres;COMMENT ON COLUMN managerdb.par_info.table_schemaIS '模式名';COMMENT ON COLUMN managerdb.par_info.table_nameIS '表名';COMMENT ON COLUMN managerdb.par_info.par_columnIS '分区字段名';COMMENT ON COLUMN managerdb.par_info.keep_data_daysIS '分区保留时长';COMMENT ON COLUMN managerdb.par_info.step_lengthIS '步长';COMMENT ON COLUMN managerdb.par_info.create_next_intervalsIS '预分区时间';COMMENT ON COLUMN managerdb.par_info.update_timeIS '更新时间';COMMENT ON COLUMN managerdb.par_info.min_partition_nameIS '最小分区';COMMENT ON COLUMN managerdb.par_info.max_partition_nameIS '最大分区';
-- Index: par_info_table_name_idx-- DROP INDEX IF EXISTS managerdb.par_info_table_name_idx;CREATE INDEX IF NOT EXISTS par_info_table_name_idxON managerdb.par_info USING btree(table_name COLLATE pg_catalog."default" ASC NULLS LAST)TABLESPACE pg_default;

插入四张测试表,根据范围分区

INSERT INTO managerdb.par_info (table_schema,table_name,par_column,keep_data_days,
step_length,create_next_intervals,update_time,min_partition_name,max_partition_name) VALUES('public','t_01','ctime',7,1,15,'2024-12-02 17:30:39+08',null,null),('public','t_02','ctime',7,1,15,'2024-12-02 17:30:39+08',null,null),('public','t_03','cint',7,1,15,'2024-12-02 17:30:39+08',null,null),('public','t_04','cint',7,1,15,'2024-12-02 17:30:39+08',null,null);

二.创建需要分区的表

CREATE TABLE IF NOT EXISTS public.t_01
(id integer NOT NULL,name character varying(100) COLLATE pg_catalog."default",ctime timestamp without time zone NOT NULL,CONSTRAINT t_01_pkey PRIMARY KEY (ctime, id)
);CREATE TABLE IF NOT EXISTS public.t_02
(id integer NOT NULL,name character varying(100) COLLATE pg_catalog."default",ctime timestamp without time zone NOT NULL,CONSTRAINT t_02_pkey PRIMARY KEY (ctime, id)
);CREATE TABLE IF NOT EXISTS public.t_03
(id integer NOT NULL,name character varying(100) COLLATE pg_catalog."default",cint bigint NOT NULL,CONSTRAINT t_03_pkey PRIMARY KEY (ctime, id)
);CREATE TABLE IF NOT EXISTS public.t_04
(id integer NOT NULL,name character varying(100) COLLATE pg_catalog."default",cint bigint NOT NULL,CONSTRAINT t_04_pkey PRIMARY KEY (ctime, id)
);

三.创建数据库函数,查询表结构,用于普通表转分区表

查询表索引函数

-- FUNCTION: managerdb.get_index_ddl(character varying, character varying, character varying)-- DROP FUNCTION IF EXISTS managerdb.get_index_ddl(character varying, character varying, character varying);CREATE OR REPLACE FUNCTION managerdb.get_index_ddl(namespace character varying,tablename character varying,ctype character varying)RETURNS character varyingLANGUAGE 'plpgsql'COST 100VOLATILE PARALLEL UNSAFE
AS $BODY$declare
tt oid ;
aname character varying default '';begintt := oid from pg_class where relname= tablename and relnamespace =(select oid from pg_namespace  where nspname=namespace) ;aname:=  array_to_string(array(select a.attname  from pg_attribute  a where a.attrelid=tt and  a.attnum   in (		select unnest(conkey) from pg_constraint c where contype=ctype and conrelid=tt  and array_to_string(conkey,',') is not null  ) ),',');return aname;
end
$BODY$;ALTER FUNCTION managerdb.get_index_ddl(character varying, character varying, character varying)OWNER TO postgres;

查询创建表索引

-- FUNCTION: managerdb.get_table_ddl(character varying, character varying)-- DROP FUNCTION IF EXISTS managerdb.get_table_ddl(character varying, character varying);CREATE OR REPLACE FUNCTION managerdb.get_table_ddl(namespace character varying,tablename character varying)RETURNS character varyingLANGUAGE 'plpgsql'COST 100VOLATILE PARALLEL UNSAFE
AS $BODY$
declare 
tableScript character varying default '';
idx_text character varying default '';
table_flag oid;
begin
-- columns
tableScript:=tableScript || ' CREATE TABLE '|| namespace || '.' ||tablename|| ' ( '|| chr(13)||chr(10) || array_to_string(array(
select '   ' || concat_ws('  ',fieldName, fieldType, fieldLen, indexType, isNullStr,attdefault, fieldComment ) as column_line
from (select fieldName,case when attdefault like 'default nextval%' then null else fieldType end fieldType,
fieldLen,indexType,
case when attdefault like 'default nextval%' then null else isNullStr end isNullStr,
case when attdefault like 'default nextval%' then 'serial' else attdefault end attdefault,
fieldComment 
from (
select a.attname as fieldName,
pg_catalog.format_type(a.atttypid, a.atttypmod) as fieldType,
null as fieldLen,
null as indexType,
(case when a.attnotnull=true then 'not null' else 'null' end) as isNullStr,
(SELECT 'default '||substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) for 128) FROM pg_catalog.pg_attrdef dWHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef
) as attdefault,
null as fieldComment
FROM pg_catalog.pg_attribute aJOIN pg_catalog.pg_class c ON a.attrelid = c.oidJOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oidLEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)WHERE a.attrelid = (select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname =namespace and relname =tablename)AND a.attnum > 0 AND NOT a.attisdroppedORDER BY a.attnum
) t
) as string_columns
),','||chr(13)||chr(10));-- 约束
idx_text:=array_to_string(
array(select concat('   CONSTRAINT ',conname ,c ,u,p,f)   from (select conname,case when contype='c' then  ' CHECK('|| ( select managerdb.get_index_ddl(namespace,tablename,'c') ) ||')' end  as c  ,case when contype='u' then  ' UNIQUE('|| ( select managerdb.get_index_ddl(namespace,tablename,'u') ) ||')' end as u ,case when contype='p' then ' PRIMARY KEY ('|| ( select managerdb.get_index_ddl(namespace,tablename,'p') ) ||')' end  as p  ,case when contype='f' then ' FOREIGN KEY('|| ( select managerdb.get_index_ddl(namespace,tablename,'u') ) ||') REFERENCES '|| (select p.relname from pg_class p where p.oid=c.confrelid )  || '('|| ( select managerdb.get_index_ddl(namespace,tablename,'u') ) ||')' end as  ffrom pg_constraint cwhere contype in('u','c','f','p') and conrelid=( select oid  from pg_class  where relname=tablename and relnamespace =(select oid from pg_namespace where nspname = namespace))) as t  
),','||chr(13)||chr(10));if length(idx_text) > 0  then tableScript:= tableScript||','||chr(13)||chr(10)||idx_text||') --PARTITION' ||chr(13)||chr(10) ||';';elsetableScript:= tableScript||' ) --PARTITION' ||chr(13)||chr(10) ||';';end if;--- 获取非约束索引 column
-- CREATE UNIQUE INDEX pg_language_oid_index ON pg_language USING btree (oid); -- table pg_language
tableScript:= tableScript || chr(13)||chr(10) || chr(13)||chr(10) || array_to_string(array(select 'CREATE INDEX ' || indexrelname || ' ON ' ||namespace || '.' || tablename || ' USING btree '|| '(' || attname || ');' from (SELECT i.relname AS indexrelname ,  x.indkey, ( select array_to_string (array( select a.attname from pg_attribute a where attrelid=c.oid and a.attnum in ( select unnest(x.indkey) )) ,',' ) )as attnameFROM pg_class cJOIN pg_index x ON c.oid = x.indrelidJOIN pg_class i ON i.oid = x.indexrelidLEFT JOIN pg_namespace n ON n.oid = c.relnamespaceWHERE  c.relname=tablename and i.relname not in( select constraint_name from information_schema.key_column_usage  where  table_name=tablename  ))as t
) ,','|| chr(13)||chr(10));-- COMMENT COMMENT ON COLUMN sys_activity.id IS '主键';
tableScript:= tableScript || chr(13)||chr(10) || chr(13)||chr(10) || array_to_string(
array(
SELECT 'COMMENT ON COLUMN ' || namespace || '.' || tablename || '.' || a.attname ||' IS  '|| ''''|| d.description ||''''||';'
FROM pg_class c
JOIN pg_description d ON c.oid=d.objoid
JOIN pg_attribute a ON c.oid = a.attrelid
WHERE c.relname=tablename
AND a.attnum = d.objsubid), chr(13)||chr(10)) ;-- COMMENT COMMENT ON table sys_activity  IS '表名';
tableScript:= tableScript || chr(13)||chr(10) || chr(13)||chr(10) || array_to_string(
array(
SELECT 'COMMENT ON table ' || namespace || '.' || tablename ||' IS  '|| ''''|| d.description ||''''||';'
FROM pg_class c
inner join pg_description d on c.oid=d.objoid
where d.objsubid=0 and c.oid=(select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname =namespace and relname =tablename)
), chr(13)||chr(10)) ;return format(tableScript);end
$BODY$;ALTER FUNCTION managerdb.get_table_ddl(character varying, character varying)OWNER TO postgres;

四.创建存储过程自动分区

创建普通表转分区表存储过程

-- PROCEDURE: managerdb.partition_verify(character varying, character varying, character varying, bigint, bigint, bigint)-- DROP PROCEDURE IF EXISTS managerdb.partition_verify(character varying, character varying, character varying, bigint, bigint, bigint);CREATE OR REPLACE PROCEDURE managerdb.partition_verify(IN p_schema_name character varying,IN p_table_name character varying,IN p_par_column character varying,IN p_keep_data_days bigint,IN p_step_length bigint,IN p_create_next_intervals bigint)
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE error_message text;i int :=1;is_par bigint;l_itera bigint :=p_keep_data_days+p_create_next_intervals;par_name varchar(100);par_table_name varchar(100);start_data varchar(100);end_data  varchar(100);sql_create varchar(4000);sql_text varchar(4000);sql_insert varchar(4000);l_partition_type varchar(100);max_par varchar(100);min_par varchar(100);
begin
select count(1) into is_par
from pg_partitioned_table a
inner join pg_class c on a.partrelid =c.oid
inner join pg_namespace n on c.relnamespace=n.oid
where c.relname=p_table_name and n.nspname=p_schema_name;-- 检查分区字段类型SELECT data_type INTO l_partition_typeFROM information_schema.columns WHERE table_schema = p_schema_nameAND table_name = p_table_nameAND column_name = p_par_column;raise notice '分区字段类型为:%',l_partition_type;if is_par=1 thenraise notice '该表是分区表';
elsepar_table_name:=p_table_name||'_par';raise notice '%.%该表不是分区表!!!',p_schema_name,p_table_name;select replace(managerdb.get_table_ddl(p_schema_name,p_table_name),'--PARTITION','PARTITION BY RANGE ('||p_par_column||')') into sql_create;select replace(sql_create,p_table_name,par_table_name) into sql_create;raise notice '创建中间分区表%.%!!!',p_schema_name,par_table_name;raise notice 'table_create_sql: %', sql_create;execute sql_create;for i in 1..l_itera looppar_name = p_schema_name||'.'||p_table_name||'_'||to_char(current_date+(interval '1 day' *(p_create_next_intervals-i)*p_step_length),'yyyymmdd');if l_partition_type = 'timestamp without time zone' thenstart_data = ''''||to_char(current_date+(interval '1 day' *(p_create_next_intervals-i)*p_step_length),'yyyy-mm-dd'||' 00:00:00')||'''';end_data = ''''||to_char(current_date+(interval '1 day' *(p_create_next_intervals+1-i)*p_step_length),'yyyy-mm-dd'||' 00:00:00')||'''';else -- if l_partition_type='integer' or l_partition_type='bigint' thenstart_data = (date_part('epoch',current_date+(interval '1 day' *(p_create_next_intervals-i)*p_step_length)))::int8;end_data = (date_part('epoch',current_date+(interval '1 day' *(p_create_next_intervals+1-i)*p_step_length)))::int8;end if;sql_text='CREATE TABLE '||par_name||' PARTITION OF '||p_schema_name||'.'||par_table_name||' FOR VALUES FROM ('||start_data||') TO ('||end_data||');';raise notice 'partition_create_sql: %', sql_text;execute sql_text;end loop;
end if;if l_partition_type = 'timestamp without time zone' thenmax_par:=''''||to_char(current_date+(interval '1 day' *(p_create_next_intervals)*p_step_length),'yyyy-mm-dd'||' 00:00:00')||'''';min_par:=''''||to_char(current_date-(interval '1 day' *(p_keep_data_days)*p_step_length),'yyyy-mm-dd'||' 00:00:00')||'''';
elsemax_par = (date_part('epoch',current_date+(interval '1 day' *(p_create_next_intervals)*p_step_length)))::int8;min_par = (date_part('epoch',current_date-(interval '1 day' *(p_keep_data_days)*p_step_length)))::int8;
end if;sql_insert:='insert into '||p_schema_name||'.'||par_table_name||chr(13)||chr(10)||'select * from '||p_schema_name||'.'||p_table_name||' where '||p_par_column||'>='||min_par||' and '||p_par_column||'<'||max_par||';';raise notice '将历史数据导入中间分区表sql:%',sql_insert;
execute sql_insert;sql_insert:='alter table '||p_schema_name||'.'||p_table_name||' rename to '||p_table_name||'_bak;';
raise notice '将原表重命名:%',sql_insert;
execute sql_insert;sql_insert:='alter table '||p_schema_name||'.'||par_table_name||' rename to '||p_table_name||';';
raise notice '将中间分区表重命名:%',sql_insert;
execute sql_insert;EXCEPTIONWHEN OTHERS THENGET STACKED DIAGNOSTICS error_message = MESSAGE_TEXT;RAISE NOTICE '捕获到异常信息*********************************ERROR************************************';RAISE NOTICE 'ERROR:%',error_message;RAISE NOTICE '捕获到异常信息*********************************ERROR************************************';end;
$BODY$;
ALTER PROCEDURE managerdb.partition_verify(character varying, character varying, character varying, bigint, bigint, bigint)OWNER TO postgres;

创建分区表定时增减分区存储过程

-- PROCEDURE: managerdb.partition_maintenance(character varying, character varying, character varying, bigint, bigint, bigint)-- DROP PROCEDURE IF EXISTS managerdb.partition_maintenance(character varying, character varying, character varying, bigint, bigint, bigint);CREATE OR REPLACE PROCEDURE managerdb.partition_maintenance(IN p_schema_name character varying,IN p_table_name character varying,IN p_par_column character varying,IN p_keep_data_days bigint,IN p_step_length bigint,IN p_create_next_intervals bigint)
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE error_message text;i int :=1;is_par bigint;par_cn bigint;l_itera bigint :=p_keep_data_days+p_create_next_intervals;par_name varchar(100);start_data varchar(100);end_data  varchar(100);sql_text varchar(4000);sql_del varchar(4000);sql_update varchar(4000);l_partition_type varchar(100);max_par varchar(100);min_par varchar(100);his_par varchar(100);csr_par cursor for select p.relnamefrom pg_class c inner join pg_inherits i on c.oid = i.inhparentinner join pg_class p on p.oid=i.inhrelidwhere c.oid =(select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname=p_schema_name and relname=p_table_name)order by p.relname;beginselect count(1) into is_par
from pg_partitioned_table a
inner join pg_class c on a.partrelid =c.oid
inner join pg_namespace n on c.relnamespace=n.oid
where c.relname=p_table_name and n.nspname=p_schema_name;if is_par=1 thenraise notice '该表是分区表。';
elseraise notice '该表为普通表,需要进行分区表重建。';call managerdb.partition_verify(p_schema_name,p_table_name,p_par_column,p_keep_data_days,p_step_length,p_create_next_intervals);
end if;-- 检查分区字段类型
SELECT data_type INTO l_partition_type
FROM information_schema.columns 
WHERE table_schema = p_schema_name
AND table_name = p_table_name
AND column_name = p_par_column;raise notice '该表分区字段类型为:%',l_partition_type;/* 查看分区表的分区情况
select pg_get_expr(p.relpartbound, p.oid),p.relnamefrom pg_class c inner join pg_inherits i on c.oid = i.inhparentinner join pg_class p on p.oid=i.inhrelidwhere c.oid =(select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname ='public' and relname ='t_01')order by pg_get_expr(p.relpartbound, p.oid)
*/select max(p.relname) INTO max_par
from pg_class c 
inner join pg_inherits i on c.oid = i.inhparent
inner join pg_class p on p.oid=i.inhrelid
where c.oid =(select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname=p_schema_name and relname=p_table_name);select min(p.relname) INTO min_par
from pg_class c 
inner join pg_inherits i on c.oid = i.inhparent
inner join pg_class p on p.oid=i.inhrelid
where c.oid =(select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname=p_schema_name and relname=p_table_name);select count(1) INTO par_cn
from pg_class c 
inner join pg_inherits i on c.oid = i.inhparent
inner join pg_class p on p.oid=i.inhrelid
where c.oid =(select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname=p_schema_name and relname=p_table_name);raise notice '该表的最大分区:%,最小分区:%,分区总数:%。',max_par,min_par,par_cn;-- 增加分区for i in 1..l_itera looppar_name = p_table_name||'_'||to_char(current_date+(interval '1 day' *(p_create_next_intervals-i)*p_step_length),'yyyymmdd');-- raise notice '分区%',par_name;if par_name>max_par then if l_partition_type = 'timestamp without time zone' thenstart_data = ''''||to_char(current_date+(interval '1 day' *(p_create_next_intervals-i)*p_step_length),'yyyy-mm-dd'||' 00:00:00')||'''';end_data = ''''||to_char(current_date+(interval '1 day' *(p_create_next_intervals+1-i)*p_step_length),'yyyy-mm-dd'||' 00:00:00')||'''';elsestart_data = (date_part('epoch',current_date+(interval '1 day' *(p_create_next_intervals-i)*p_step_length)))::int8;end_data = (date_part('epoch',current_date+(interval '1 day' *(p_create_next_intervals+1-i)*p_step_length)))::int8;end if;sql_text='CREATE TABLE '||p_schema_name||'.'||par_name||' PARTITION OF '||p_schema_name||'.'||p_table_name||' FOR VALUES FROM ('||start_data||') TO ('||end_data||');';raise notice 'partition_create_sql: %', sql_text;execute sql_text;else raise notice '该表分区增加完成。。。';exit;end if;end loop;-- 删除分区--应该最小分区和最大分区
if l_partition_type = 'timestamp without time zone' thenmax_par:=''''||to_char(current_date+(interval '1 day' *(p_create_next_intervals)*p_step_length),'yyyy-mm-dd'||' 00:00:00')||'''';min_par:=''''||to_char(current_date-(interval '1 day' *(p_keep_data_days)*p_step_length),'yyyy-mm-dd'||' 00:00:00')||'''';
elsemax_par = (date_part('epoch',current_date+(interval '1 day' *(p_create_next_intervals)*p_step_length)))::int8;min_par = (date_part('epoch',current_date-(interval '1 day' *(p_keep_data_days)*p_step_length)))::int8;
end if;raise notice '该表应该最大分区:%,最小分区:%。',max_par,min_par;--应该最小分区名称
par_name = p_table_name||'_'||to_char(current_date-(interval '1 day' *(p_keep_data_days)*p_step_length),'yyyymmdd');
raise notice '应该最小分区名称%',par_name;open csr_par;loopfetch csr_par into his_par;exit when not found;-- raise notice '历史分区。。。%',his_par;if his_par<par_name then sql_del='drop table '||p_schema_name||'.'||his_par||';';raise notice '删除分区: %', sql_del;execute sql_del;else raise notice '最小分区已删除到: %', p_schema_name||'.'||his_par;exit;end if; end loop;
close csr_par;-- 更新自动化分区配置文件
select max(p.relname) INTO max_par
from pg_class c 
inner join pg_inherits i on c.oid = i.inhparent
inner join pg_class p on p.oid=i.inhrelid
where c.oid =(select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname=p_schema_name and relname=p_table_name);select min(p.relname) INTO min_par
from pg_class c 
inner join pg_inherits i on c.oid = i.inhparent
inner join pg_class p on p.oid=i.inhrelid
where c.oid =(select c.oid from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname=p_schema_name and relname=p_table_name);sql_update='update managerdb.par_info set update_time='''||to_char(now(),'yyyy-mm-dd hh24:mi:ss')||''',min_partition_name='''||min_par||''',max_partition_name='''||max_par||''' where table_schema='''||p_schema_name||''' and table_name='''||p_table_name||''';';
raise notice '更新自动化分区配置文件sql:%',sql_update;
execute sql_update;raise notice '---------------------------------------------------------------------------------';
raise notice '----------------------分区表:%.%,自动化分区完成!!!------------------------',p_schema_name,p_table_name;
raise notice '---------------------------------------------------------------------------------';EXCEPTIONWHEN OTHERS THENGET STACKED DIAGNOSTICS error_message = MESSAGE_TEXT;RAISE NOTICE '捕获到异常信息*********************************ERROR************************************';RAISE NOTICE 'ERROR:%',error_message;RAISE NOTICE '捕获到异常信息*********************************ERROR************************************';end;
$BODY$;
ALTER PROCEDURE managerdb.partition_maintenance(character varying, character varying, character varying, bigint, bigint, bigint)OWNER TO postgres;

创建全局自动化分区存储过程

-- PROCEDURE: managerdb.partition_maintenance_all()-- DROP PROCEDURE IF EXISTS managerdb.partition_maintenance_all();CREATE OR REPLACE PROCEDURE managerdb.partition_maintenance_all()
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE error_message text;p_schema_name VARCHAR(255);p_table_name VARCHAR(255);p_par_column VARCHAR(255);p_keep_data_days INT8;p_step_length INT8;p_create_next_intervals INT8;csr cursor for SELECT table_schema,table_name,par_column,keep_data_days,step_length,create_next_intervals from managerdb.par_info;beginraise notice '自动化分区日志开始(%)。。。',to_char(now(),'yyyy-mm-dd hh24:mi:ss');open csr;loopfetch csr into p_schema_name,p_table_name,p_par_column,p_keep_data_days,p_step_length,p_create_next_intervals;exit when not found;raise notice '---------------------------------------------------------------------------------';raise notice '----------------------分区表:%.%,自动化分区开始!!!------------------------',p_schema_name,p_table_name;raise notice '---------------------------------------------------------------------------------';raise notice '分区表:%.%,保留时长%天,时间间隔%天,预分区时间%天。',p_schema_name,p_table_name,p_keep_data_days,p_step_length,p_create_next_intervals;call managerdb.partition_maintenance(p_schema_name,p_table_name,p_par_column,p_keep_data_days,p_step_length,p_create_next_intervals);end loop;close csr;raise notice '...自动化分区执行完成!!!';EXCEPTIONWHEN OTHERS THENGET STACKED DIAGNOSTICS error_message = MESSAGE_TEXT;RAISE NOTICE '捕获到异常信息*********************************ERROR************************************';RAISE NOTICE 'ERROR:%',error_message;RAISE NOTICE '捕获到异常信息*********************************ERROR************************************';
end; 
$BODY$;
ALTER PROCEDURE managerdb.partition_maintenance_all()OWNER TO postgres;COMMENT ON PROCEDURE managerdb.partition_maintenance_all()IS '自动化分区调度入口';

五.创建定时作业,每天定时执行

vim /home/postgres/script/crontab_job_auto_partition.sh/home/postgres/bin/psql -p 15432 -d postgres -c "call managerdb.partition_maintenance_all()" > /home/postgres/scripts/partition_his.log 2>&1
crontab -e0 2 * * * sh /home/postgres//scripts/crontab_job_auto_partition.sh

六.试运行结果查看

执行日志

[postgres@db scripts]$ cat partition_his.log 
NOTICE:  自动化分区日志开始(2024-12-02 17:30:39)。。。
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ----------------------分区表:public.t_01,自动化分区开始!!!------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  分区表:public.t_01,保留时长7天,时间间隔1天,预分区时间15天。
NOTICE:  该表是分区表。
NOTICE:  该表分区字段类型为:timestamp without time zone
NOTICE:  该表的最大分区:t_01_20241221,最小分区:t_01_20241127,分区总数:25。
NOTICE:  该表分区增加完成。。。
NOTICE:  该表应该最大分区:'2024-12-17 00:00:00',最小分区:'2024-11-25 00:00:00'。
NOTICE:  应该最小分区名称t_01_20241125
NOTICE:  最小分区已删除到: public.t_01_20241127
NOTICE:  更新自动化分区配置文件sql:update managerdb.par_info set update_time='2024-12-02 17:30:39',min_partition_name='t_01_20241127',max_partition_name='t_01_20241221' where table_schema='public' and table_name='t_01';
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ----------------------分区表:public.t_01,自动化分区完成!!!------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ----------------------分区表:public.t_02,自动化分区开始!!!------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  分区表:public.t_02,保留时长7天,时间间隔1天,预分区时间15天。
NOTICE:  该表是分区表。
NOTICE:  该表分区字段类型为:timestamp without time zone
NOTICE:  该表的最大分区:t_02_20241216,最小分区:t_02_20241125,分区总数:22。
NOTICE:  该表分区增加完成。。。
NOTICE:  该表应该最大分区:'2024-12-17 00:00:00',最小分区:'2024-11-25 00:00:00'。
NOTICE:  应该最小分区名称t_02_20241125
NOTICE:  最小分区已删除到: public.t_02_20241125
NOTICE:  更新自动化分区配置文件sql:update managerdb.par_info set update_time='2024-12-02 17:30:39',min_partition_name='t_02_20241125',max_partition_name='t_02_20241216' where table_schema='public' and table_name='t_02';
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ----------------------分区表:public.t_02,自动化分区完成!!!------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ----------------------分区表:public.t_03,自动化分区开始!!!------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  分区表:public.t_03,保留时长7天,时间间隔1天,预分区时间15天。
NOTICE:  该表是分区表。
NOTICE:  该表分区字段类型为:bigint
NOTICE:  该表的最大分区:t_03_20241216,最小分区:t_03_20241125,分区总数:22。
NOTICE:  该表分区增加完成。。。
NOTICE:  该表应该最大分区:1734393600,最小分区:1732492800。
NOTICE:  应该最小分区名称t_03_20241125
NOTICE:  最小分区已删除到: public.t_03_20241125
NOTICE:  更新自动化分区配置文件sql:update managerdb.par_info set update_time='2024-12-02 17:30:39',min_partition_name='t_03_20241125',max_partition_name='t_03_20241216' where table_schema='public' and table_name='t_03';
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ----------------------分区表:public.t_03,自动化分区完成!!!------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ----------------------分区表:public.t_04,自动化分区开始!!!------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  分区表:public.t_04,保留时长7天,时间间隔1天,预分区时间15天。
NOTICE:  该表是分区表。
NOTICE:  该表分区字段类型为:bigint
NOTICE:  该表的最大分区:t_04_20241216,最小分区:t_04_20241125,分区总数:22。
NOTICE:  该表分区增加完成。。。
NOTICE:  该表应该最大分区:1734393600,最小分区:1732492800。
NOTICE:  应该最小分区名称t_04_20241125
NOTICE:  最小分区已删除到: public.t_04_20241125
NOTICE:  更新自动化分区配置文件sql:update managerdb.par_info set update_time='2024-12-02 17:30:39',min_partition_name='t_04_20241125',max_partition_name='t_04_20241216' where table_schema='public' and table_name='t_04';
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ----------------------分区表:public.t_04,自动化分区完成!!!------------------------
NOTICE:  ---------------------------------------------------------------------------------
NOTICE:  ...自动化分区执行完成!!!
CALL

普通表自动化转换分区表成功

定期增加删除分区成功

相关文章:

Postgres数据库自动化分区

一.创建自动化分区配置表并插入数据 -- Table: managerdb.par_info-- DROP TABLE IF EXISTS managerdb.par_info;CREATE TABLE IF NOT EXISTS managerdb.par_info (table_schema character varying(255) COLLATE pg_catalog."default" NOT NULL,table_name characte…...

【技术介绍】C++编程语言中的瑰宝

C&#xff0c;这门源于C语言并在其基础上进行大幅增强的编程语言&#xff0c;自诞生以来便以其独特的魅力和强大的功能吸引了无数编程者的目光。它不仅是计算机科学领域的一颗璀璨明珠&#xff0c;更是现代软件开发中不可或缺的重要工具。 解析【前言】 C的命名&#xff0c;寓…...

nginx反向代理

目录 环境准备 启动HTTP服务 配置Nginx 访问 部署 1.配置nginx 2.自动化脚本 3.执行脚本 4.使用ansible 什么是反向代理呢&#xff0c;参考nginx反向代理&#xff0c;业务部署过长中&#xff0c;常遇到的场景如下&#xff0c;通过访问域名/ip地址&#xff0c;后面接入网…...

分层图最短路

常见情形&#xff1a; 对于边有k次操作的题。。 整体思想&#xff1a; 分层图最短路可以视作是dijkstra的一个扩展&#xff0c;通常用于处理N小于10000&#xff0c;或者是k不大的情形。整体有点类似于拆点。将一个点拆成k个点处理。层与层之间互不影响。 好了我就说这么多&…...

FRU文件

FRU&#xff08;Field Replaceable Unit&#xff09;源文件的格式通常遵循IPMI FRU Information Storage Definition标准。在实际应用中&#xff0c;FRU源文件可以是JSON格式的&#xff0c;这种格式允许用户指定所有的FRU信息字段。以下是FRU源文件的JSON格式的一些关键点&…...

兔子繁衍问题

7-2 兔子繁衍问题 分数 15 全屏浏览 切换布局 作者 徐镜春 单位 浙江大学 一对兔子&#xff0c;从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死&#xff0c;请问第1个月出生的一对兔子&#xff0c;至少需要繁衍到第几个月时兔…...

飞凌嵌入式受邀亮相OpenHarmony人才生态大会2024

2024年11月27日&#xff0c;OpenHarmony人才生态大会2024在武汉洲际酒店举行。在这场汇聚了行业精英、技术大咖及生态伙伴的年度盛会上&#xff0c;飞凌嵌入式作为OpenHarmony社区的重要成员受邀出席&#xff0c;并展示了其在OpenHarmony 4.1系统适配方面的最新成果。 在大会的…...

Resrful控制器

Linux Debian 包管理器 apt DebianUbuntuKali红帽子 包管理器dnf或者yum RHELFedroaCentos Stream RHEL上游版本&#xff0c;就是什么新的内容、特性会在这个上面进行测试 运行 运行页面--dotnet blog.dll配置管理 server{listen 80;server_name m.域名;location / {proxy_p…...

Python练习(2)

重复元素判定续。利用集合的无重复性来编写一个程序如果有一个元素出现了不止一次则返回true但不要改变原来列表的值&#xff1a; 一&#xff1a; def has_duplicates(lst): # 使用集合来存储已经见过的元素 seen set() for item in lst: if item in seen: # 如果元素已经在…...

Qt清空文件夹下的内容

Qt清空文件夹下的内容 你可以使用 QDir 类来清空文件夹下的所有内容。以下是一个示例&#xff0c;展示了如何删除指定文件夹中的所有文件和子文件夹&#xff1a; #include <QCoreApplication> #include <QDir> #include <QFileInfoList> #include <QDeb…...

如何手动设置ubuntu服务器的ip、子网掩码、网关、DNS

在 Ubuntu 服务器上手动设置 IP 地址、子网掩码、网关和 DNS&#xff0c;通常有两种方式&#xff1a;使用传统的 ifconfig 命令和配置文件&#xff0c;或者使用现代的 netplan 配置方式&#xff08;对于 Ubuntu 17.10 及以后版本&#xff0c;netplan 是默认的网络配置工具&…...

单片机状态机实现多个按键同时检测单击、多击、长按等操作

1.背景 在之前有个项目需要一个或多个按键检测&#xff1a;单击、双击、长按等操作 于是写了一份基于状态机的按键检测&#xff0c;分享一下思路 2.实现效果 单击翻转绿灯电平 双击翻转红灯电平 长按反转红绿灯电平 实现状态机检测按键单击&#xff0c;双击&#xff0c;长…...

graph rag都能做哪些事情

从提供的项目目录结构看&#xff0c;系统具备高复杂度和模块化的设计&#xff0c;可能用于大规模数据处理、知识图谱构建、自然语言处理等方面。以下是一些推理出的核心能力和应用场景&#xff1a; 1. 核心模块能力&#xff1a; API 层 (api) 主要用于对外接口的定义和服务调…...

Linux 用户和用户组管理

Linux 用户和用户组管理 Linux系统是一个多用户多任务的分时操作系统&#xff0c;任何一个要使用系统资源的用户&#xff0c;都必须首先向系统管理员申请一个账号&#xff0c;然后以这个账号的身份进入系统。 用户的账号一方面可以帮助系统管理员对使用系统的用户进行跟踪&…...

Python酷库之旅-第三方库Pandas(251)

目录 一、用法精讲 1186、pandas.tseries.offsets.BusinessMonthEnd.is_year_start方法 1186-1、语法 1186-2、参数 1186-3、功能 1186-4、返回值 1186-5、说明 1186-6、用法 1186-6-1、数据准备 1186-6-2、代码示例 1186-6-3、结果输出 1187、pandas.tseries.offs…...

利用Ubuntu批量下载modis图像(New)

由于最近modis原来批量下载的代码不再直接给出&#xff0c;因此&#xff0c;再次梳理如何利用Ubuntu下载modis数据。 之前的下载代码为十分长&#xff0c;现在只给出一部分&#xff0c;需要自己再补充另一部分。之前的为&#xff1a; 感谢郭师兄的指导&#xff08;https://blo…...

Redis分布式锁

一、全局ID生成器 1.1 概念 全局ID生成器&#xff0c;是一种在分布式系统下用来生成全局唯一ID的工具。具有以下特点&#xff1a; &#xff08;&#xff11;&#xff09;唯一性&#xff1b;&#xff08;&#xff12;&#xff09;高可用&#xff1b;&#xff08;&#xff13;&…...

【Maven】依赖管理

4. Maven的依赖管理 在 Java 开发中&#xff0c;项目的依赖管理是一项重要任务。通过合理管理项目的依赖关系&#xff0c;我们可以有效的管理第三方库&#xff0c;模块的引用及版本控制。而 Maven 作为一个强大的构建工具和依赖管理工具&#xff0c;为我们提供了便捷的方式来管…...

leetcode——移除数组

26.删除有序数组中的重复项 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素…...

vue项目部署到github pages后页面显示不出来??

问题&#xff1a; 当我们在命令行执行 npm run build 后&#xff0c;项目的目录下会生成一个 dist 文件夹&#xff0c;它里面又包含一个 static 文件夹和一个 index.html 文件&#xff0c;这是 webpack 最终打包好的文件 项目上传到仓库后发现页面为空&#xff0c;找不到文件路…...

为什么爱用低秩矩阵

目录 为什么爱用低秩矩阵 一、定义与性质 二、区别与例子 为什么爱用低秩矩阵 我们更多地提及低秩分解而非满秩分解,主要是因为低秩分解在数据压缩、噪声去除、模型简化和特征提取等方面具有显著的优势。而满秩分解虽然能够保持数据的完整性,但在实际应用中的场景较为有限…...

如何在MySQL中计算两个日期的间隔天数

目录 1. DATEDIFF函数2. TIMESTAMPDIFF函数3. PERIOD_DIFF函数4. 函数对比 在MySQL 5.7中&#xff0c;计算两个日期之间的间隔天数是一项常见的任务。 1. DATEDIFF函数 DATEDIFF函数可以直接计算两个日期之间的天数差异。 -- 计算2024年1月1日和2024年1月10日之间的天数差异 …...

SQL面试题——抖音SQL面试题 共同问题—共同使用ip用户检测问题

共同使用ip用户检测问题 现有用户登录日志表,记录了每个用户登录的IP地址,请查询共同使用过3个及以上IP的用户对; +---+--------------+-------------------+ | id| ip| etime| +---+--------------+-------------------+ | 2|223.104.41.101|20…...

python学习笔记2

下载安装PyCharm 打开pycharm官网&#xff1a; https://www.jetbrains.com.cn/en-us/pycharm/download/?sectionwindows 找到社区版&#xff08;免费&#xff09; 下载之后打开&#xff0c;不停下一步就行 打开pycharm软件后&#xff0c;新建py文件 基本输出&#xff1a;…...

IS-IS的原理

IS-IS的基本概念&#xff1a; 概述&#xff1a; IS-IS&#xff0c;中间系统到中间系统&#xff0c;是ISO国际标准化组织为它的无连接网络协议设计的一种动态路由协议 IS-IS支持CLNP网络和IP网络&#xff0c;采用数据链路层封装&#xff0c;区别于ospf只支持IP网络&#xff0…...

现代应用程序中基于 Cell 架构的安全防护之道

在飞速发展的软件开发领域&#xff0c;基于 Cell 的架构日益流行起来。其概念源自船舶舱壁的设计准则&#xff0c;即单独的水密舱室能允许故障孤立存在。通过将这个概念应用于软件&#xff0c;我们创建了一个架构&#xff0c;将应用程序划分为离散的、可管理的组件&#xff0c;…...

Rust : 生成日历管理markdown文件的小工具

需求&#xff1a; 拟生成以下markdown管理小工具&#xff0c;这也是我日常工作日程表。 可以输入任意时间段&#xff0c;运行后就可以生成以上的markdown文件。 一、toml [package] name "rust-workfile" version "0.1.0" edition "2021"[d…...

Burp Suite 全面解析:开启你的 Web 安全测试之旅

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…...

RocketMQ: 消息积压问题的解决

概述 1 &#xff09; 什么是消息积压 在分布式消息系统中&#xff0c;消息积压是指消息生产速度超过消息消费速度&#xff0c;导致未处理的消息在消息队列中累积的现象这种现象可能会导致系统性能下降、资源占用增加&#xff0c;甚至影响系统的正常运行 2 &#xff09;消息积…...

Qt的定时器应用案例 || Qt的图片添加显示

目录 1.ui界面 2.头文件 3.cpp源文件 4.main文件 5.关于ui_mytimerevent.h的代码编译错误 6.图片的添加展示方式 7.结果展示 8.参考文章 1.ui界面 2.头文件 #ifndef MYTIMEREVENT_H #define MYTIMEREVENT_H#include <QMainWindow> #include <QTime> //#in…...

24.12.02 Element

import { createApp } from vue // 引入elementPlus js库 css库 import ElementPlus from element-plus import element-plus/dist/index.css //中文语言包 import zhCn from element-plus/es/locale/lang/zh-cn //图标库 import * as ElementPlusIconsVue from element-plus/i…...

web安全攻防入门教程

Web安全攻防入门教程 Web安全攻防是指在Web应用程序的开发、部署和运行过程中&#xff0c;保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现&#xff0c;还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。 本教程将带你入门Web安全攻…...

Android——android相对布局(RelativeLayout)及各属性

参考:Android——android相对布局&#xff08;RelativeLayout&#xff09;及属性 - 艺言弈行 - 博客园 (cnblogs.com)...

初窥 HTTP 缓存

引言 对于前端来说, 你肯定听说过 HTTP 缓存。 当然不管你知不知道它, 对于提高网站性能和用户体验, 它都扮演着重要的角色! 它通过在客户端和服务器之间存储和重用先前获取的资源副本, 来减少网络流量和降低资源加载时间, 从而提升用户体验! 以下是 HTTP 缓存的重要性: 减少…...

【LeetCode】3. 哈希表: 字母异位词分组;有效的数独

题目 字母异位词分组 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出: [[“…...

设计模式之抽象工厂 C# 范例

在设计模式中&#xff0c;抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09; 是一种创建型模式&#xff0c;它提供一个接口&#xff0c;用于创建一组相关或相互依赖的对象&#xff0c;而无需指定具体类。这种模式的关键在于通过抽象工厂来封装产品的创建&#xff…...

基于Python的猎聘网招聘数据采集与可视化分析

1.1项目简介 在现代社会&#xff0c;招聘市场的竞争日趋激烈&#xff0c;企业和求职者都希望能够更有效地找到合适的机会与人才。猎聘网作为国内领先的人力资源服务平台&#xff0c;汇聚了大量的招聘信息和求职者数据&#xff0c;为研究招聘市场趋势提供了丰富的素材。基于Pyt…...

oracle数据库的启动与关闭

一.oracle数据库的启动过程 启动实例&#xff08;Start the Instance&#xff09; 启动实例&#xff1a;一个Oracle数据库实例由内存结构和后台进程组成&#xff0c;启动实例时会加载这些内存结构和启动进程。实例是数据库的一个运行时环境&#xff0c;它包含了数据库的控制文…...

openGauss开源数据库实战十六

文章目录 任务十六 openGauss逻辑结构:触发器管理任务目标实施步骤一、测试openGauss的触发器1.创建测试表2.创建触发器对应的函数3.创建触发器4.测试触发器 二、触发器的类型1.行级触发器2.语句级触发器3.AFTER触发器和 BEFORE触发器 任务十六 openGauss逻辑结构:触发器管理 …...

智能教育的关键之一是构建智能学习系统

教育部办公厅12月27日发布《关于加强中小学人工智能教育的通知》&#xff0c;提出人工智能教育六大主要任务和举措&#xff0c;包括构建系统化课程体系、实施常态化教学与评价、开发普适化教学资源、建设泛在化教学环境、推动规模化教师供给和组织多样化交流活动。《通知》提出…...

【Linux 篇】Docker 容器星河与镜像灯塔:Linux 系统下解锁应用部署奇幻征程

文章目录 【Linux 篇】Docker 容器星河与镜像灯塔&#xff1a;Linux 系统下解锁应用部署奇幻征程前言一 、docker上部署mysql1. 拉取mysql镜像2. 创建容器3. 远程登录mysql 二 、docker上部署nginx1. 拉取nginx镜像2. 在dockerTar目录下 上传nginx.tar rz命令3. 创建nginx容器4…...

十四(AJAX)、AJAX、axios、常用请求方法(GET POST...)、HTTP协议、接口文档、form-serialize

1. AJAX介绍及axios基本使用 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content&q…...

雪花算法生成ID

下面将简单介绍雪花算法的简单应用和在web应用中的使用。 雪花算法的组成&#xff1a;雪花算法是由64位组成&#xff1a;符号位(1)、时间戳(41)、机器码(5[数据中心]5[机器ID])、计数器(12) 对于雪花算法的源码可以在这里看&#xff1a;bwmarrin/snowflake: A simple to use …...

Java - JSR223规范解读_在JVM上实现多语言支持

文章目录 1. 概述2. 核心目标3. 支持的脚本语言4. 主要接口5. 脚本引擎的使用执行JavaScript脚本执行groovy脚本1. Groovy简介2. Groovy脚本示例3. 如何在Java中集成 Groovy4. 集成注意事项 6. 与Java集成7. 常见应用场景8. 优缺点9. 总结 1. 概述 JSR223&#xff08;Java Spe…...

vue3 基本使用

Vue 3 提供了多种方式来构建用户界面&#xff0c;包括选项式 API 和 Composition API。下面我将详细介绍 Vue 3 的基本使用和语法&#xff0c;主要集中在选项式 API 上&#xff0c;因为这对于初学者来说更容易上手。 1. 创建 Vue 项目 如果你还没有一个 Vue 项目&#xff0c;…...

Redis自学之路—高级特性(实现消息队列)(七)

目录 简介 Redis的Key和Value的数据结构组织 全局哈希表 渐进式rehash 发布和订阅 操作命令 publish 发布消息 subscribe 订阅消息 psubscribe订阅频道 unsubscribe 取消订阅一个或多个频道 punsubscribe 取消订阅一个或多个模式 查询订阅情况-查看活跃的频道 查询…...

ROS基本框架2——在ROS开发中创建并使用自定义消息(C++版本)

ROS基本框架2——在ROS开发中创建并使用自定义消息(C++版本) code review! 参考笔记 1.ROS基本框架1——编写简单的发布者和订阅者(C++和Python版本) 2.ROS基本框架2——在ROS开发中创建并使用自定义消息(C++版本) 文章目录 ROS基本框架2——在ROS开发中创建并使用自定义…...

计算机的错误计算(一百七十二)

摘要 探讨 MATLAB 对于算式 的计算误差。 例1. 在 MATLAB 中计算 的值。 直接贴图吧&#xff1a; 这样&#xff0c;MATLAB 的输出中只有3位正确数字&#xff0c;有效数字的错误率为 (16-3)/16 81.25% . 因为16位的正确输出为 0.2971242332737277e-18&#xff08;ISReals…...

贵州大学oj平台高级语言第九次作业(四)

题目&#xff1a;链表的基础操作 题目描述 链表是软件中一种最基本的数据结构&#xff0c;它是用链式存储结构实现数据存储的线性表。它较顺序表(如数组)而言在插入和删除数据时不必移动其后的大批量元素。现在给你一些整数&#xff0c;然后会频繁地插入和删除其中的某些元素&a…...

手机卡限速丨中国移动5G变3G,网速500kb

以下猜测错误&#xff0c;又有新的猜测&#xff1a;河南移动的卡出省限速。可能是因为流量结算。 “2024年7月1日起&#xff0c;中国移动集团内部将开启跨省流量结算” 在深圳四五年了&#xff0c;之前没有过&#xff0c;就从上个月开始。11月底解除限速&#xff0c;12月刚开…...