Eu tenho uma visão, que seleciona dados da TableA (TableA será descomissionada assim que migrarmos tudo). Estamos criando uma nova tabela, chamada TABLEC
, onde migraremos todos os dados de TableA para TableC no futuro.
- A razão pela qual estamos fazendo isso, é porque
tableA
é muito antigo e mal projetado. - No momento,
tableA
está sendo usado apenas para registros antigos. Todos os novos dados que seriam inseridostableA
já estão indotableC
via aplicativo. - Não consigo alterar o esquema de nenhuma tabela.
- A visualização pode ser alterada para usar
CTE
, IF, é pelo menos tão rápido quanto agora. path
não é um caminho real, mas é uma expressão regular. Será algo como:/file/account/[0-9]+
<-- depois disso existem algumas possibilidades, podem ser várias palavras diferentes (como: attach/assigned/etc).
Apesar de não migrarmos todos os dados de tableA
para tableC
, precisamos que a view seja compatível com ambas as tabelas, pois já existem novos dados indo para tableC
.
Visão:
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
e tableb
são praticamente os mesmos; como disse antes, foi mal projetado.
Eu preciso da view para fazer:
- Veja se os dados solicitados estão na nova tabela
tableC
- SE NÃO , então vá para
tableA
e obtenha os dados
PERGUNTA:
Como eu posso fazer isso? Eu tentei com UNION ALL
mas é muito lento.
\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 |
IMHO Eu acho que o caminho mais rápido neste caso é olhar primeiro na TableC, e se não existir na TableC, procure o registro na TableA/B.
Montei um pequeno exemplo:
Desde que você esteja usando uma expressão regular
/file/account/[0-9]+
para filtrar registros, você pode usar o operador~
. ( Expressões Regulares POSIX )Mas dê uma olhada nesta resposta de Erwin Brandstetter sobre o uso de expressões regulares, caso você possa adicionar algum índice extra à sua tabela.
Eu usei uma função porque ela me permite usar IF EXISTS(). Ele só pesquisa o registro na TabelaA se não existir na TabelaC. Obviamente, você pode alterar a ordem de pesquisa.
Agora você pode procurar um caminho específico desta maneira:
dbfiddle aqui
Você pode tentar usar uma junção externa completa com coalescência em cada coluna.
Eu não tive a chance de testar isso, mas algo como: