我可以想象按日期(特别是日志)进行表分区是一种广泛使用的方法,但我无法找到一个很好的答案来解决我的问题。
我想按周创建一个表分区(记录的数量太大,以至于无法按月创建)。按周创建的原因是我需要一个算法的数据,该算法将查找日期作为该过程的一部分。
我的问题是,我希望它创建分区考虑到一周,并使用“典型”的方法,我将不得不手动创建它。
CREATE TABLE measurement_y2013w01 (
CHECK ( logdate >= DATE '2013-01-07' AND logdate < DATE '2013-01-14' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006w02 (
CHECK ( logdate >= DATE '2013-01-14' AND logdate < DATE '2013-01-21' )
) INHERITS (measurement);
...
但我希望它是自动创建的,我不希望每周都要一个一个地创建分区。
我的命名规则是yyyyywWW,用于命名分区或启动数据YYYYMMDD。
我想在插入时检查分区使用这样的东西:
SELECT
nmsp_parent.nspname AS parent_schema,
parent.relname AS parent,
nmsp_child.nspname AS child,
child.relname AS child_schema
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace
JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace
如果分区不在那里,则在插入之前创建它,但是考虑到插入的记录的数量,这看起来效率很低。
我的另一个选择是让一个外部进程每周运行一次来创建这个分区,但我试图避免这种情况。
有没有一个更有效的解决方案,我错过了,这是用来,例如,每月检查?
4条答案
按热度按时间vqlkdk9b1#
好了,让我们创建一个函数来处理这个问题!
有了这个,你现在可以调用类似
并创建分区。自动化的第一步完成。
我在自己的数据库中使用以下测试表测试了所有这些:
使用上面的函数创建分区后,我能够:
应该够了吧=)
现在,关于自动化创建过程。我使用一个简单的cron脚本每个月为我调用这个函数,并使用几个监控脚本来确保一切正常工作。cron看起来像这样:
脚本将使用当前日期和当前日期+ 1个月运行命令。它看起来像这样:
如果您需要在表中包含索引、PK、FK,或者帮助使用触发器来使所有这些工作正常进行,请告诉我。
jbose2ul2#
您可以使用date_trunc函数将数据值四舍五入到一周的第一天,分区命名可以使用年份和年份中的星期号YYWW:
对于分区名称生成,使用
to_char( logdate::date, 'YYWW')
,如果您喜欢yyyyywWW:to_char( logdate::date, '"y"YYYY"w"WW')
要检查现有的分区,您可以使用非常简单的查询:
数据路由触发器插入到适当的分区中,如果给定周没有分区,则回退到默认值。
您需要预先创建所有分区,或者您可以使用默认分区,并不时地重新分区存储在那里的数据,创建新的分区并调整插入触发器。
PS你可以在这里找到基于触发器的分区解决方案的脚本http://hg.nowitworks.eu/postgresql-triggers-and-partitions
dxpyg8gm3#
如果有帮助的话,我写了一个postgres触发器来创建一个按天自动分区的表。创建继承的表是自动发生的。要按周分区,你必须更改day-〉stringMap,就是这样。
https://github.com/bitdivine/pg_day_partitions
js81xvg64#
您可以创建一个插入触发器,在分区不存在时创建该分区:
触发器执行以下任务:
1.检查表是否存在(查询
pg_catalog
非常快)。1.计算记录
logdate
的相应表的名称1.如果该名称的分区表不存在,则为相应的周创建一个新的分区表(
CREATE TABLE ... LIKE measurement INCLUDING INDEXES INHERITS (measurement)
)1.为上周的数据创建或更新一个名为v_measurement的视图。
答案假设存在一个空的
measurement
表作为模板,并且logdate
字段是timestamp
。在该表中,最好为logdate
字段创建一个索引,该字段的类型为:代码改编自另一个类似的stackoverflow响应。