我有一个视图,它从 TableA 中选择数据(TableA 将在我们全部迁移后停用)。我们正在创建一个名为 的新表,TABLEC
将来我们会将所有数据从 TableA 迁移到 TableC。
- 我们这样做的原因是因为
tableA
它非常陈旧且设计糟糕。 - 目前,
tableA
仅用于旧记录。所有要插入的新数据tableA
都已经tableC
通过应用程序传输。 - 我无法更改任何表的架构。
- 视图可以更改为 use
CTE
,如果它至少和现在一样快。 path
不是真正的路径,而是一个正则表达式。它会是这样的:/file/account/[0-9]+
<-- 在此之后有一些可能性,它可以是几个不同的词(例如:attach/assigned/等)。
虽然我们不会将所有数据从 迁移tableA
到tableC
,但我们需要视图与两个表兼容,因为已经有新数据要迁移到tableC
。
看法:
CREATE OR REPLACE VIEW path_view AS
SELECT split_part(n1.path::text, '/'::text, 18)::integer AS id,
split_part(n1.path::text, '/'::text, 14)::integer AS clientid,
lower(n1.md5::text)::character(32) AS md5, 0 AS cont,
'00000000-1000-1000-3000-600000000000'::uuid AS guid,
n1.bytes AS byte_count,
n1.last_modified AS last_modified
FROM tablea n1
JOIN tableb s2
ON s2.path = n1.path;
--tablea
几乎tableb
相同;如前所述,它设计得很糟糕。
我需要视图来做:
- 查看请求的数据是否在新表中
tableC
- 如果不是,则转到
tableA
并获取数据
问题:
我怎样才能做到这一点?我试过了,UNION ALL
但速度很慢。
\d tableC
:
Table "public.tablec"
--------------------+-----------------------------+-------------------------------------------------------------------
id | integer | not null default nextval('tablec_id_seq'::regclass)
e_type | integer | not null
e_id | bigint |
e_variation | character varying(16) | not null
path | character varying(255) | not null
name | character varying(255) | not null
size | bigint | not null
md5 | md5_hash | not null
modified_date | timestamp without time zone | default statement_timestamp()
created_date | timestamp without time zone | default statement_timestamp()
clientid | bigint | not null
f_id | bigint |
恕我直言,我认为这种情况下的快速方法是首先查看 TableC,如果 TableC 上不存在,则在 TableA/B 上搜索记录。
我建立了一个小例子:
至于您使用正则表达式
/file/account/[0-9]+
来过滤记录,您可以使用 operator~
。(POSIX 正则表达式)但是看看Erwin Brandstetter关于使用正则表达式的这个答案,以防万一你可以在你的表中添加一些额外的索引。
我使用了一个函数,因为它允许我使用 IF EXISTS ()。如果 TableC 上不存在,它只会搜索 TableA 上的记录。显然,您可以更改搜索顺序。
现在您可以通过这种方式搜索特定路径:
小提琴手在这里
您可以尝试在每列上使用带有合并的完整外部联接。
我还没有机会对此进行测试,但类似于: