Neste artigo, mostrarei como pensei seriamente em uma alternativa ao Oracle. Mas e o Postgre, você diz? Sim, mas existem nuances. Primeiro, lidaremos com a pergunta "Por que Oracle?"
Lógica de negócios em nosso banco de dados. No livro da Oracle para profissionais, Tom Kite escreve
Ao desenvolver aplicativos de banco de dados, utilizo um mantra muito simples:
se possível, faça-o com uma única instrução SQL;
se isso não puder ser feito com uma única instrução SQL, faça-o em PL / SQL;
se isso não puder ser feito no PL / SQL, tente usar um procedimento armazenado Java;
se isso não puder ser feito em Java, faça-o como um procedimento externo em C;
se isso não puder ser implementado como um procedimento externo em C, você precisará pensar seriamente sobre o motivo de isso ser feito ...
e no design do sistema, sigo esta regra. Os tipos de objetos no Oracle são especialmente agradáveis: com a ajuda deles, uma lógica de negócios complexa é implementada de maneira conveniente e conveniente de acordo com todos os cânones do OOP.
Oracle é caro. Comprá-lo e não usar tudo o que está nele será um erro.
E, no entanto, sempre há um fator de equipe e competências. Se sua equipe desenvolve tudo na Oracle há dez anos, a liberação do Postgre pode ser dolorosa.
Oracle é caro. Tão caro que você pode escrever sobre isso várias vezes e não pensar na necessidade de Oracle em um novo projeto será um erro.
Várias vezes já me deparei com publicações sobre o produto coreano Tibero, supostamente criado para substituir o Oracle. E agora eles têm uma atração por generosidade sem precedentes - as licenças padrão são distribuídas para desenvolvedores quase de graça, por um dólar por soquete. Então, entendemos: o que os coreanos podem oferecer no momento. Com os carros, afinal, eles já (quase) conseguiram!
Descrição da experiência
Os representantes da TMaxSoft dizem que o Tibero é quase 100% compatível com o Oracle, e existe um utilitário para a migração de bancos de dados. Decidi pegar minha base de produtos, com lógica de negócios no Oracle, usando todo o charme do OOP em PL \ SQL e transferi-lo para o Tibero. Nesta publicação, não consideramos a migração dos dados em si, é menos interessante e ainda não tentei uma migração completa.
A tarefa é esta:
1. Transferir tabelas.
2. Transferência de índices, chaves, etc.
3. Transfira pacotes e gatilhos.
4. Transferência de tipos de objetos.
Mas primeiro, vamos lidar com as ferramentas.
As ferramentas
O Google conhece pouco sobre Tibero. Baixamos o próprio banco de dados na forma de uma máquina virtual na qual tudo já foi implantado. Existem apenas duas ferramentas: um utilitário para migrar o T-UP e um IDE para DBA e o desenvolvedor do tbAdmin. Tudo é feito em Java, roda em qualquer lugar, em teoria.
O T-UP se parece com isso:
Janela principal: conexões com o banco de dados.
Se você clicar em Opções, poderá configurar alguma coisa.
Mais importante, você pode selecionar os tipos de objetos a serem migrados.Não foram encontradas instruções, ajuda, dicas.
Faz a impressão de um utilitário caseiro. Às vezes, ela voava com execuções, mas basicamente trabalhava conforme necessário.
A segunda ferramenta é o Tibero Admin IDE. Pode ser baixado do site da TMaxSoft se você se registrar primeiro. Você também pode obter uma licença demo lá.
O Tibero Admin parece um IDE antigo típicoEstou acostumado à excelente ferramenta PL / SQL Developer da Allround Automations. No Tibero Admin, esqueça as instruções contextuais, nada aparecerá na tela depois de clicar no "ponto"; ele não anexará os nomes de tabelas e objetos a você. Basta digitar o código, vocês programadores. Ajuda, documentação? Não. Há documentação no DBMS no site do fabricante, tão interessante ... sem uma pesquisa. Nenhuma documentação foi encontrada para o IDE. No entanto, não há nada complicado. Houve problemas com a autorização - descobriu-se que o usuário precisa receber direitos de DBA para entrar no tbAdmin. E interessante com as portas
, 8630 é para SYS, para todos os outros 8629 .
Erros de IDE. De tempos em tempos, quando você cutuca em algum lugar, o
índice de mensagens
fora dos limites desaparece , uma mensagem como
java.lang.Exception: Compromisso com êxito é muito assustador. É necessário levar em consideração diferentes tipos de janelas SQL e PSM: na primeira, é improvável que você compile o código do programa; na segunda, você não executará a solicitação. Após PL / SQL Developer - uma aparência miserável da mão esquerda ...
Chegando ao experimento.
Migração de tabela
Selecionamos o esquema no T-UP, clique em Migrar, primeiro selecione as “tabelas” nas opções e o processo de transferência será iniciado. Eu tive dois problemas.
TABLESPACES. Decidi transferi-los para as tabelas, mas o Tibero parece ter tentado reservar tanto espaço para eles quanto eles ocupam no banco de dados de origem. E isso é muito, e ele não podia. Criei os espaços de tabela manualmente e tudo correu bem.
Além de tabelas com valores de data PADRÃO do tipo '31 .12.2019 '. Nas configurações do Oracle, temos este formato registrado, para o Tibero ajuda
alter session set nls_date_format='DD.MM.YYYY';
mas não há lugar para o T-UP fazer isso. Colegas da TMaxSoft recomendaram definir a variável TB_NLS_DATE_FORMAT = "DD.MM.YYYY", mas isso não me ajudou pessoalmente. Talvez eu tenha feito algo errado. Eu tive que criar tabelas com esses parâmetros manualmente, não há muitos deles.
Resultado do primeiro passo: mover a estrutura da tabela do Oracle para o Tibero funciona bem.
Chaves e índices.
Marcamos as caixas de seleção INDEX, CONSTRAINT em T-UP e encaminhamos.Os problemas surgiram com CHECK devido à mesma situação da data. Em geral, índices, chaves primárias, cheques - foram criados. Mas não consegui encontrar chaves estrangeiras no banco de dados recém-criado. E a migração de constantes termina no log do T-UP com a mensagem
"Falha na migração: java.lang.NullPointerException". Coincidência? Eu acho que não ...
Pacotes e gatilhos.
Nos gatilhos não tenho nada complicado, eles foram criados perfeitamente. É verdade que eu não verifiquei como eles funcionam, essa será uma história separada.
Vamos falar sobre procedimentos e funções que implementam parte da lógica. Aqui, infelizmente, nem tudo correu perfeitamente.
De um simples: no
exército de Tibero não há palavra
NOVA . A construção o: = NEW t_my_type () não será compilada. No Oracle, é verdade, não é obrigatório, mas eu sempre escrevi por algum motivo. Eu tive que excluir.
A função DBA permite que o SQL Window acesse todas as tabelas. No entanto, ao compilar um pacote ou procedimento em um esquema com essa função, ao usar tabelas e objetos de outro esquema, você precisa conceder a concessão correspondente ao objeto. A mágica do papel do DBA não ajuda aqui.
Do específico. Eu tenho um FORALL estranho no meu banco de dados, que, no entanto, funciona.
Tibero diz que
“a instrução dml deve ter o parâmetro de entrada em massa ia forall close” . E eu entendo isso no fundo, mas esse código teve que ser refeito em um ciclo regular.
A situação com tabelas contendo objetos é pior.
CREATE OR REPLACE TYPE S1.TYPE_PAY_HIST AS OBJECT ( pay_status_id NUMBER(1), stamp DATE ); CREATE OR REPLACE TYPE S1.TABLE_PAY_HIST AS VARRAY(10) OF type_pay_hist; create table S2.RECEIPT ( receipt_id NUMBER(8) not null, pay_sum NUMBER(12,2) not null, receipt_hist S1.TABLE_PAY_HIST ); FUNCTION receipt_status_change(p_cmr_receipt_id NUMBER, p_new_status NUMBER) RETURN NUMBER AS l_receipt_hist s1.table_pay_hist; l_type_pay_hist s1.type_pay_hist; l_status NUMBER; BEGIN BEGIN SELECT receipt_hist INTO l_receipt_hist FROM receipt p WHERE p.receipt_id = p_cmr_receipt_id FOR UPDATE; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN c_err_not_find_status; END; ... END;
Temos um erro de compilação, digite mistmatch.
Os caras da TMaxSoft propuseram esta versão do código:
create or replace FUNCTION .... AS l_receipt_hist table_pay_hist; l_type_pay_hist type_pay_hist; l_status NUMBER; cmr_receipt_row cmr_receipt%rowtype; BEGIN BEGIN SELECT * INTO cmr_receipt_row FROM cmr_receipt p WHERE p.cmr_receipt_id = p_cmr_receipt_id FOR UPDATE; SELECT TYPE_PAY_HIST(r.pay_status_id,r.stamp) bulk collect INTO l_receipt_hist FROM cmr_receipt p,table(p.receipt_hist) r WHERE p.cmr_receipt_id = p_cmr_receipt_id; EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('NO_DATA_FOUND'); RETURN null;
Trabalho, provavelmente funciona. Mas não é tão conveniente, e você precisa refazer o código.
O restante é compilado normalmente, exceto por coisas específicas como SDO_GEOM. E, a propósito, Tibero tem um análogo. Suas mãos ainda não haviam chegado ao escritório.
Tipos
Em um dos projetos, usamos o poder do OOP da Oracle hollow.
A pergunta mais emocionante para Tibero foi sobre isso.
Criamos um certo tipo, que é básico para um conjunto de outros tipos.
CREATE OR REPLACE TYPE t_tar_object AS OBJECT ( id NUMBER(12), smth NUMBER(12), CONSTRUCTOR FUNCTION t_tar_object RETURN SELF AS RESULT, MEMBER FUNCTION target(param IN NUMBER DEFAULT NULL) RETURN NUMBER, MEMBER FUNCTION inside(o t_tar_object) RETURN NUMBER, MEMBER FUNCTION clone RETURN t_tar_object ) NOT FINAL;
E agora estamos tentando criar um herdeiro digno para ele.
CREATE OR REPLACE TYPE t_tar_service UNDER t_tar_object ( is_virtual NUMBER(1), CONSTRUCTOR FUNCTION t_tar_service (p_serv_obj t_tar_object, p_main_id NUMBER, p_pack_id NUMBER) RETURN SELF AS RESULT, OVERRIDING MEMBER FUNCTION target(param IN NUMBER DEFAULT NULL) RETURN NUMBER, OVERRIDING MEMBER FUNCTION clone RETURN t_tar_object ) NOT FINAL;
O compilador se recusará a substituir a função de destino. Entretanto, não há perguntas sobre a função clone. Verificou-se que Tibero não gostou de OVERRIDING quando o método possui parâmetros. Ok, remova a palavra SUBSTITUIÇÃO. Mas isso é alarmante, e escrevemos scripts de teste. Até agora, com o tipo pai.
declare o1 t_tar_object; i1 number := 100; begin o1 := t_tar_object; o1.id := 1; i1 := o1.target;
Parece que não deixamos uma escolha para o programa, independentemente do valor que a variável i1 assume, algo deve aparecer na saída. Mas ... nada aparece!
Lembrei-me imediatamente de um ótimo filmeEssa estranheza não termina aí. Tornando o experimento pior
declare o1 t_tar_object; i1 number := 100; begin o1 := t_tar_object; o1.id := 1; i1 := o1.target;
Mesmo o fato de que, depois de todas as manipulações com os métodos do objeto, definimos rigidamente o valor da variável, não muda nada - a saída está vazia.
Controle o experimento, teste a si mesmo quanto à insanidade:
declare o1 t_tar_object; i1 number ; begin o1 := t_tar_object; o1.id := 1;
O estimado "grande" aparece na saída. Assustador, não é? Usando uma cutucada científica, os caras da TMaxSoft descobriram que, se você remover a nuance “NOT FINAL” da especificação t_tar_object, o objeto se comportará adequadamente. Mas por que então precisamos de tal ... sem herdeiros.
Não faz sentido falar mais sobre POO em Tibero. Como, de fato, o OOP em Tibero. Depois disso, surge outra pergunta: e o código de procedimentos e funções que compilou - funciona corretamente? Ainda não sei. Uma enorme quantidade de código imigrou e compilou. Para um projeto que não contém os tipos de exercícios acima, este é um sucesso definitivo. Mas testar a execução correta do código é uma tarefa séria. E para ser sincero, não esperava encontrá-la. Não estarei pronto para dizer se terei um projeto neste DBMS. Mas, se isso acontecer, o desenvolvimento ocorrerá no Oracle, usando ferramentas convenientes normais e com migração regular para o Tibero. Escrever código no IDE sem avisos contextuais e com erros periódicos da própria interface é um prazer abaixo da média.
Conclusões
Tibero tem um futuro em seu estado atual? Não tenho certeza. Afinal, se você observar o custo das licenças, excluindo a escala de mega escala, um soquete padrão custa cerca de 800.000, o que é mais barato que o Oracle, mas às vezes não. E como eu estava convencido de minha própria experiência, até agora isso não é nem perto da Oracle.
Faz sentido usar o Tibero quase gratuito que está sendo oferecido agora? Talvez sim. Eles dizem que, ao pagar pelo custo do suporte técnico (99.000 rublos por ano para um soquete), é permitido o uso dessa base em projetos comerciais. Se você tem uma equipe de oracleists disponível e precisa criar e colocar algo não muito complicado em seu servidor, mas mais barato e mais rápido - uma opção interessante. Você ainda pode jogar o cartão de sanções, dizendo aos clientes preocupados que a Coréia não é os Estados Unidos.
Devo traduzir projetos existentes do Oracle para o Tibero? De jeito nenhum. Não há razão para procurar essa aventura. É mais fácil desistir do suporte técnico da Oracle e não pagar nada a ninguém.
E se você precisar criar uma nova instância de um projeto antigo em execução no Oracle? E, como resultado, comprar novas licenças? Pense aqui. É possível que sua base migre e funcione qualitativamente. Mas pense imediatamente em apoiar duas áreas do projeto ou traduza tudo para o Tibero. Consideramos custos, riscos e benefícios trabalhistas de licenças mais baratas. Compare, decida.
Talvez na próxima versão do Tibero tudo seja diferente. Só é necessário finalizar os tipos, criar um IDE normal, talvez alterar a política de preços. E se o DBMS for o mesmo que com os carros, depois de cinco anos os coreanos poderão ocupar uma fatia significativa do mercado e suplantar a hegemonia. Vamos ver.
PS
Uma vantagem séria ao escolher um DBMS para um novo projeto pode ser o trabalho do suporte técnico da TMaxSoft. Eu nem comprei uma licença por um dólar e os caras me responderam prontamente, claramente interessados. Eles ajudaram com perguntas estúpidas e com as descritas aqui. O feedback é excelente.