Postgresql 具有不可变数据的数据库设计';s在初始插入后从未被引用 背景
目前只有一台具有32 GB内存的PostgreSQL计算机。插入的数据是不可变的 我试图建模的信息可以在三个表中描述,其中表1与表2有一对多关系,表2与表3有一对多关系 例如,如果表1是Postgresql 具有不可变数据的数据库设计';s在初始插入后从未被引用 背景,postgresql,database-design,postgresql-11,Postgresql,Database Design,Postgresql 11,目前只有一台具有32 GB内存的PostgreSQL计算机。插入的数据是不可变的 我试图建模的信息可以在三个表中描述,其中表1与表2有一对多关系,表2与表3有一对多关系 例如,如果表1是汽车表,表2可以是描述汽车车轮的表,表3可以是描述车轮螺钉的表 在JSON中: { "car" : { "id" : 1, "wheels" : [ { "id" : 1000, "dimension" : "17",
汽车
表,表2可以是描述汽车车轮
的表,表3可以是描述车轮螺钉
的表
在JSON中:
{
"car" : {
"id" : 1,
"wheels" : [
{
"id" : 1000,
"dimension" : "17",
"screws" : [
{
"id" : "sc1",
"rust" : false
}]
},
{
"id" : 1001,
"dimension" : "17",
"screws" : [
{
"id" : "sc2",
"rust" : true
}]
}
]
}
}
插入项填充汽车
、车轮
和螺钉
表格,以及时间戳
。插入后,这些行永远不会被修改,甚至不会被其他行引用。只读
当前DDL:
car
表(表1):
车轮
表(表2):
螺钉
表(表3):
最常见的查询在其WHERE
子句中使用表2中的列。它们使用表#3列进一步过滤。按照同样的例子,一个典型的查询是返回所有带有17英寸车轮和螺丝生锈的汽车
不需要使用超过一周的数据,因此能够轻松地清除数据是很好的
虽然表#1和表#2的大小相对较小,但表#3可以相当快地增长到1 TB以上。我想它就像一个轮子,每个轮子都有一百万个螺钉
当前解决方案
我正在使用表#2 id(例如,wheel_id
)上的散列对表#3进行分区,以便主机可以在内存中存储分区,以加快查询速度。分区大小将相等
问题
使用该解决方案,我无法根据表1中的时间戳
轻松删除数据。因为表2引用了表1,表3引用了表2,所以级联删除是可行的。但我希望避免使用真空
时间戳上的分区表#1将不起作用,因为PostgreSQL不允许表引用分区
问题:
我觉得我处理这个问题的方式不对,因为我没有利用数据是不可变的事实,而且插入的数据永远不会在特定汽车、车轮和螺钉之间的关系之外被引用。删除表#1中的一行也可以安全地删除表#2和#3中的引用行。I不明白“我想避免真空的需要”“与级联删除有关-这听起来是解决问题的完美方法。顺便说一句:最好显示表的实际DDL,而不是一些不反映表中数据存储方式的聚合JSON。@a_horse_与_no_name一起,如果完全分离分区,而不需要真空,会不会更好?我已经添加了一个DDL和JSON。我添加了JSON,以便在将数据馈送到我的服务时传达数据的外观。(我之所以使用示例而不是实际的字段名,是因为业务判断。)啊,对不起。我不明白你想通过分离分区来进行清除。顺便说一句:Postgres 12允许外键引用分区表,只要分区键是主键的一部分(因此外键也是主键的一部分),表#3中是否存在键入错误?应该是车轮id而不是汽车id吗?谢谢@TomC,你说得对。修正了。我不明白“我想避免真空”和级联删除有什么关系——这听起来是解决问题的完美方法。顺便说一句:最好显示表的实际DDL,而不是一些不反映表中数据存储方式的聚合JSON。@a_horse_与_no_name一起,如果完全分离分区,而不需要真空,会不会更好?我已经添加了一个DDL和JSON。我添加了JSON,以便在将数据馈送到我的服务时传达数据的外观。(我之所以使用示例而不是实际的字段名,是因为业务判断。)啊,对不起。我不明白你想通过分离分区来进行清除。顺便说一句:Postgres 12允许外键引用分区表,只要分区键是主键的一部分(因此外键也是主键的一部分),表#3中是否存在键入错误?应该是车轮id而不是汽车id吗?谢谢@TomC,你说得对。固定的。
id BIGSERIAL PRIMARY KEY
id BIGSERIAL PRIMARY KEY
car_id BIGINT REFERENCES car(id)
dimension INTEGER NOT NULL
id BIGSERIAL PRIMARY KEY
wheel_id BIGINT REFERENCES wheel(id)
rust BOOLEAN NOT NULL