Olá, sou Andrew Santos, tenho 23 anos e estou atualmente na fase final da minha graduação em Banco de Dados. Atuo como Desenvolvedor Full Stack, com foco em Node e React, dentro do contexto do SAP Business One. Anteriormente, desempenhei o papel de Analista Desenvolvedor, trabalhando com linguagens como NodeJS, C#, e tenho experiência sólida em bancos de dados SQL e SAP Hana.
Ao longo da minha carreira, pude aplicar meu conhecimento em modelagem, otimização e manipulação de dados usando SQL, contribuindo para a eficiência e integridade dos sistemas em que estive envolvido.
Em minha experiência profissional como Desenvolvedor, já obtive conquistas significativas e adquiri um conhecimento substancial. Sinto-me entusiasmado com a perspectiva de continuar aprimorando minhas habilidades em bancos de dados SQL e Hana, bem como crescendo de forma abrangente nessa área dinâmica. Acredito firmemente que a busca contínua por conhecimento e a dedicação à prática são pilares essenciais para se tornar um profissional de excelência. Sempre estou em busca de novos desafios e oportunidades que me permitam expandir meu potencial e aprofundar meu aprendizado.
Durante minha graduação, participei ativamente do desenvolvimento de projetos conhecidos como "API de Aprendizagem por Processos Integrados". Esses projetos integradores são cuidadosamente elaborados para abordar questões do mundo real e buscar soluções eficazes.
Mais Detalhes do Projeto I
A Fatec é uma instituição de ensino superior pública, mantida pelo estado, onde todos os cursos disponibilizados são de acesso gratuito. A formação de um Tecnólogo na Fatec vai além dos aspectos técnicos, incorporando também uma base sólida de valores sociais, éticos, filosóficos e ambientais. Essa abordagem visa transformar o indivíduo em um profissional consciente de seu papel e responsabilidades dentro da sociedade à qual pertence.
A assistente virtual Ibet foi desenvolvida com a finalidade de proporcionar aos usuários uma maneira eficiente de acessar informações relacionadas a esportes. Esta ferramenta oferece diversas funcionalidades que visam facilitar a experiência do usuário nesse contexto. Algumas das características que a Ibet oferece incluem:
Definição de Alarmes para Jogos: A assistente Ibet permite que os usuários configurem alarmes para serem notificados sobre jogos específicos. Isso garante que eles fiquem atualizados sobre as partidas de seu interesse. Placares de Jogos em Tempo Real: A Ibet fornece placares atualizados em tempo real para jogos em andamento. Isso permite que os usuários acompanhem os resultados instantaneamente, sem atrasos.
Acesso a Jogos Antigos: Além de informações sobre jogos atuais, a Ibet também disponibiliza detalhes sobre jogos antigos. Isso possibilita que os usuários revivam momentos marcantes no mundo esportivo.
Vídeos e Conteúdo Relacionado: A assistente oferece acesso a vídeos e conteúdo relacionado a esportes, permitindo que os usuários assistam a momentos emocionantes, entrevistas e análises.
Interação por Comando de Voz: O grande diferencial da aplicação é a interação por meio de comandos de voz. Os usuários podem obter todas as informações necessárias sem precisar digitar ou clicar em botões. Isso torna a experiência mais conveniente e intuitiva.
A Ibet foi projetada para entregar informações de forma interativa, proporcionando aos usuários uma experiência rica em conteúdo esportivo sem os incômodos de interações tradicionais. Com sua funcionalidade de comando de voz, a assistente busca tornar a busca por informações esportivas mais prática e acessível.
Link do repositório do projeto: Repositório
Desempenhei um papel crucial na implementação da tecnologia de reconhecimento de voz na API, onde criei um algoritmo que permitisse a execução do serviço em segundo plano, no modo Standby. Essa abordagem garante que a tecnologia seja ativada somente quando chamada, otimizando os recursos e proporcionando uma experiência eficiente aos usuários.
Informações sobre a Lógica do Sistema
- Algoritmo para reconhecimento de voz.
def ouvir_microfone():
microfone = SpeechRecognition.Recognizer()
with SpeechRecognition.Microphone() as source:
microfone.adjust_for_ambient_noise(source)
audio = microfone.listen(source)
try:
frase = microfone.recognize_google(audio, language='pt-BR')
return frase
except SpeechRecognition.UnknownValueError:
return "Não entendi!"
O ponto inicial foi criar uma instância do objeto Recognizer() da biblioteca SpeechRecognition. Em seguida, a função entra em um bloco "with" para configurar e usar o microfone como fonte de entrada de áudio. Dentro do bloco "with", o método "adjust_for_ambient_noise()" é chamado para ajustar automaticamente o nível de ruído de fundo para melhorar a precisão da transcrição. Em seguida, o método "listen()" é chamado para gravar o áudio da fonte (microfone) e armazená-lo na variável "audio". Depois disso, a função tenta transcrever o áudio em texto usando a API do Google Speech Recognition (recognize_google), especificando a linguagem de entrada como "pt-BR" (português do Brasil). Se a transcrição for bem-sucedida, o texto é armazenado na variável "frase" e retornado pela função. Caso contrário, se o reconhecimento de fala falhar ou não for compreendido, a função retornará a mensagem "Não entendi!".
Com certeza, ao desenvolver a assistente, priorizei a sua capacidade de ser executada em segundo plano e entrar em ação imediatamente quando chamada. Isso foi feito com o objetivo de reduzir ao máximo a necessidade de interação física por parte do usuário, como inserção manual de informações via teclado ou mouse. A minha abordagem visa proporcionar uma experiência mais fluida e prática, permitindo que os usuários interajam com a assistente por meio de comandos de voz, minimizando a barreira entre eles e as informações que estão buscando. Isso não apenas aumenta a eficiência, mas também torna a experiência mais intuitiva e acessível para um amplo público.
Informações código Front-End
- Trecho do código responsável de receber o retorno do back-end, da explicação citada acima.
this.total = this.noDiscount += (element.price * element.quantidade);
this.service.getDiscount(this.id, this.quantidade, this.total, this.categoria).subscribe(
response =>
{ const product : Product = new Product();
this.discount = response;
this.product.discount = this.discount
this.finalPrice = this.finalPrice += (element.price * element.quantidade)-(this.discount)
console.log("teste", this.categoria)
errorResponse => console.log(errorResponse)
})
});
...
return new ResponseEntity<>(desconto, HttpStatus.OK);
- Esse método é responsável por passar os parâmetros para o back-end, processar a informação e direcionar o retorno para a camada de visualização do usuário, sendo um trecho importante pois enviar dados, processa o retorno e já devolve os resultados para usuário.
Iniciei minha jornada com a linguagem de programação Python, abrindo portas para novas possibilidades.
Adquiri uma compreensão profunda da metodologia ágil Scrum, aplicando seus princípios de forma prática.
Optei por adotar o paradigma de programação imperativo para construir meu projeto, utilizando uma abordagem estruturada.
Desenvolvi uma base sólida em lógica de programação, capacitando-me para resolver desafios computacionais de maneira eficaz.
Introduzi e utilizei com sucesso as primeiras estruturas de dados em meu projeto, explorando as capacidades da linguagem Python.
Minhas habilidades de comunicação estão em constante evolução, contribuindo para uma melhor interação com colegas.
Desenvolvimento do backend com Python, criando aplicações robustas.
Criação de APIs para fornecer serviços e funcionalidades.
Domínio do versionamento de código com o uso do Git.
Capacidade de projetar a arquitetura de sistemas alinhada aos requisitos funcionais e não funcionais.
Experiência no desenvolvimento integrado com bancos de dados relacionais.
Clique aqui para mais detalhes do Projeto.
Mais Detalhes do Projeto II
Figura 01. Logo Necto System Fonte(Necto)
A empresa Necto System situada no Parque Tecnológico de São José dos Campos, propôs o seguinte desafio baseado na metodologia ágil Scrum.
Neste projeto foi proposto a construção de uma integração para a coleta de informações diretamente dos servidores, visando a criação de uma série histórica de dados. A concepção por trás disso era criar uma aplicação que pudesse realizar a coleta regular de métricas de um ou mais Sistemas Gerenciadores de Banco de Dados remotos. Essa ferramenta é projetada para fornecer informações valiosas ao usuário, permitindo que tomem decisões informadas em relação à manutenção, balanceamento, escalabilidade e melhorias necessárias nos seus SGBDs, bancos de dados e infraestrutura de servidores.
Ao realizar essa integração, o objetivo é capacitar os usuários a monitorar de perto o desempenho de seus sistemas, identificar tendências ao longo do tempo e agir de forma proativa para otimizar e manter a estabilidade de suas operações. Ao fornecer uma visão holística das métricas do sistema, essa aplicação permite que os usuários tomem decisões fundamentadas sobre ajustes necessários, sejam eles relacionados a melhorias na eficiência dos bancos de dados, balanceamento de carga ou mesmo escalonamento da infraestrutura para atender às demandas crescentes.
Essa iniciativa reflete um entendimento avançado das necessidades de gestão de banco de dados e infraestrutura, demonstrando a capacidade de criar soluções práticas para otimizar a operação dos sistemas e garantir sua confiabilidade e eficácia contínuas.
Link do repositório do projeto: Repositório
Assumi a responsabilidade crucial de implementar a lógica que permitiu a integração ao conectar ao banco de dados, a fim de realizar a coleta periódica de parametrizações. Além disso, fui encarregado de criar as consultas (queries) necessárias para recuperar os dados e desenvolver procedimentos armazenados (procedures) para a execução eficiente dessas operações.
Essa tarefa implicou em um profundo entendimento das estruturas de banco de dados e suas nuances, demonstrando habilidades sólidas em design de consultas, otimização de desempenho e conhecimento técnico na criação de procedimentos que automatizam processos complexos. Ao implementar essa lógica, fui capaz de fornecer à integração a capacidade de extrair informações relevantes de forma eficaz e precisa, garantindo que as parametrizações fossem coletadas de maneira confiável.
Minha contribuição na criação de consultas e procedures reforça minha habilidade de traduzir requisitos de negócios em ações concretas no ambiente de banco de dados. Além disso, demonstrou meu conhecimento sólido em SQL e meu compromisso em desenvolver soluções robustas que atendam às necessidades do projeto e da equipe.
Informações código Back-End
- Algoritmo para conexão com o Banco de Dados (Postgress).
public conexao(){
url = "jdbc:postgresql://localhost:5432/teste";
usuario = "postgres";
senha = "toto185100";
try {
Class.forName("org.postgresql.Driver");
con = DriverManager.getConnection(url,usuario,senha);
System.out.println("Conexão realizada com sucesso!!!");
} catch (Exception e) {
e.printStackTrace();
}
ExibirTamanhoTabelas(con);
};
public static void ExibirTamanhoTabelas(Connection con) {
String sql = "SELECT
esquema,
tabela,
pg_size_pretty(pg_relation_size(esq_tab)) AS tamanho,
pg_size_pretty(pg_total_relation_size(esq_tab)) AS tamanho_total,
FROM
(SELECT
tablename AS tabela,
schemaname AS esquema,
schemaname||'.'||tablename AS esq_tab
FROM
pg_catalog.pg_tables
WHERE
schemaname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') ) AS x
ORDER BY
pg_total_relation_size(esq_tab) DESC; ";
try {
PreparedStatement pesquisa = con.prepareStatement(sql);
ResultSet result = pesquisa.executeQuery();
while(result.next()) {
System.out.println("NOME: " + result.getString("tabela"));
System.out.println("TAMANHO: "+result.getString("tamanho"));
System.out.println("TAMANHO TOTAL: " + result.getString("tamanho_total"));
}
} catch(Exception e) {
e.printStackTrace();
}
}
No primeiro trecho deste código acima, foram definidas as informações necessárias para a conexão com o banco de dados local. A variável "url" contém a URL de conexão com o banco, a porta padrão do PostgreSQL e o nome do banco de dados.
Em seguida, dentro de um bloco try-catch, o código tenta estabelecer a conexão com o banco de dados. A linha Class.forName("org.postgresql.Driver") carrega dinamicamente o driver JDBC necessário para se comunicar com o PostgreSQL. Em seguida, DriverManager.getConnection(url,usuario,senha) estabelece a conexão com o banco de dados usando as informações fornecidas. Se a conexão for estabelecida com sucesso, a mensagem "Conexão realizada com sucesso!!!" é exibida. Caso ocorra algum erro durante a conexão, a exceção é capturada e o rastreamento de pilha do erro é impresso.
Após a conexão ser estabelecida, há uma chamadas de método chamando "ExibirTamanhoTabelas". Esse método exibe o tamanho das tabelas do banco de dados através de um retorno de uma query consultando através da conexão realizada.
-
Auxiliei também a integração completa das chamadas de todos os métodos do Back-End. Durante esse processo, além de criar alguns métodos, desempenhei um papel fundamental na realização de testes para validar as requisições.
Essa etapa é de extrema importância, pois envolve garantir que cada funcionalidade do Back-End esteja operando de maneira correta e coesa. Ao criar e implementar esses métodos, pude contribuir para a construção de uma aplicação robusta e funcional. Os testes que conduzi permitiram identificar possíveis problemas e assegurar que as requisições feitas à API estivessem fornecendo os resultados esperados.
A abordagem sistemática e a atenção aos detalhes nos testes ilustram o compromisso em oferecer um produto final de alta qualidade, além de evidenciar minhas habilidades em depuração e solução de problemas.
Detalhes da Interface do Usuário
- Trecho do algoritmo responsável por receber o retorno do back-end.
public class Principal { public static void main(String[] args) throws IOException { LoginModel loginModel = LoginController.PreencherLogin(); Menu menu = new Menu(loginModel); Properties prop = LoginController.getProp(); String openMenu = prop.getProperty("openMenu"); if (openMenu.equals("y")) { menu.startmenu(); } else { ImprimeMetricas imprimeMetricas = new ImprimeMetricas(loginModel); imprimeMetricas.tamanhobancos(); imprimeMetricas.tamanhoTabelas(); imprimeMetricas.selectsChamadas1000x(); imprimeMetricas.SelectMaisDemoradas(); imprimeMetricas.selectsMaisDemoradasMedia(); imprimeMetricas.conflicts(); } } }
O código é uma classe Java chamada "Principal". Na primeiro trecho do código, uma instância da classe "LoginModel" é criada chamada "loginModel", e o método estático "PreencherLogin()" da classe "LoginController" é chamado para preencher os dados do login. Em seguida, uma instância da classe "Menu" chamada "menu" é criada, passando o objeto "loginModel" como argumento para o construtor da classe "Menu". A próxima linha cria uma instância da classe "Properties" chamada "prop" e chama o método estático "getProp()" da classe "LoginController" para obter um objeto "Properties". Em seguida, a propriedade chamada "openMenu" é recuperada do objeto "Properties" e armazenada na variável "openMenu" como uma string. Em seguida, o código verifica se o valor da variável "openMenu" é igual a "y". Se for, o método "startmenu()" é chamado no objeto "menu". Caso contrário, uma instância da classe "ImprimeMetricas" chamada "imprimeMetricas" é criada, passando o objeto "loginModel" como argumento para o construtor. Em seguida, vários métodos são chamados nessa instância, como "tamanhobancos()", "tamanhoTabelas()", "selectsChamadas1000x()", "SelectMaisDemoradas()", "selectsMaisDemoradasMedia()" e "conflicts()". Esses métodos provavelmente realizam diferentes operações relacionadas a métricas e análises de um sistema.
Aproveitei a oportunidade durante o desenvolvimento do projeto para adquirir um profundo conhecimento em sistemas de gerenciamento de banco de dados (SGBDs).
Desenvolvi habilidades para coletar e manipular informações de maneira altamente eficiente, gerando séries históricas e métricas relevantes para os usuários.
A experiência enriqueceu minhas habilidades na manipulação de dados, aprimorando minha capacidade de criar consultas SQL e utilizar diversos comandos para extrair informações específicas e impactantes.
Explorei e me familiarizei profundamente com ferramentas de gerenciamento de banco de dados, como o PostgreSQL, aplicando-as de maneira excepcionalmente eficaz.
Criei consultas e rotinas que possibilitaram a coleta de métricas cruciais, como o dimensionamento das tabelas e do banco de dados, fornecendo insights inestimáveis aos usuários.
Aprofundei minha compreensão dos princípios fundamentais que regem um SGBD, destacando a importância de estruturar e organizar os dados adequadamente para facilitar operações futuras.
Reconheci a relevância de otimizar consultas e operações de banco de dados para contribuir para um desempenho mais eficiente e uma experiência geral mais satisfatória para os usuários.
Minha atuação no projeto não se limitou à coleta e manipulação de dados, envolvendo também a criação de um ambiente de banco de dados resiliente e otimizado.
Esse aspecto desempenhou um papel essencial no sucesso da aplicação como um todo, contribuindo para a eficácia operacional.
A experiência adquirida concedeu um conhecimento profundo e uma base sólida para futuros empreendimentos relacionados à gestão de dados e ao uso de SGBDs.
Clique aqui para mais detalhes do prijeto.
Mais Detalhes do Projeto III
Figura 01. Logo MidAll Fonte(MidAll)
A empresa MidAll situada no Parque Tecnológico de São José dos Campos, propôs o seguinte desafio baseado na metodologia ágil Scrum.
Neste projeto foi proposta a criação de promoções em um ambiente de E-commerce. Para abordar essa demanda, desenvolvemos um motor de regras acompanhado de uma interface intuitiva, que permitisse o cadastro simplificado das regras das promoções.
Essa solução teve como objetivo proporcionar uma abordagem eficiente e flexível para a gestão de promoções, permitindo que a equipe de marketing e vendas pudesse criar, ajustar e monitorar promoções de forma ágil e personalizada. O motor de regras, com sua lógica subjacente, permitiu a definição de critérios específicos para a ativação das promoções, como combinações de produtos, valores de compra e outros fatores relevantes.
A interface de cadastro simplificou o processo ao máximo, eliminando a necessidade de conhecimento técnico avançado. Os colaboradores da empresa puderam criar e ajustar regras de promoções de acordo com as metas de marketing e os objetivos comerciais.
Com essa solução, a MidAll conseguiu atender às suas necessidades de promoções de maneira eficiente e escalável, impulsionando as vendas e a satisfação do cliente. A abordagem de motor de regras e interface de cadastro trouxe mais flexibilidade e autonomia à equipe, garantindo a criação de promoções personalizadas e impactantes no cenário do E-commerce.
Link do repositório do projeto: Repositório
Assumi a responsabilidade crucial de implementar a lógica do motor de regras na API, desempenhando um papel central na criação de um algoritmo avançado. Esse algoritmo foi projetado para calcular os valores passados como parâmetros, em retorno, fornecer a melhor promoção a ser aplicada no carrinho de compras do usuário.
Essa tarefa exigiu um profundo entendimento das diferentes regras de promoção e de como elas interagem com os valores específicos de compra. Ao criar esse algoritmo, foi demonstrado um domínio sólido das lógicas de cálculo e das nuances das promoções, considerando diversos cenários para determinar qual promoção seria mais vantajosa para o cliente.
Além disso, minha contribuição na criação deste motor de regras demonstrou habilidades de programação avançadas, como o desenvolvimento de algoritmos complexos e a capacidade de traduzir requisitos de negócios em lógica computacional. A aplicação prática do algoritmo também demonstra seu compromisso em criar uma experiência de compra otimizada para os usuários, onde eles possam se beneficiar ao máximo das promoções disponíveis.
Seu papel na implementação da lógica do motor de regras foi essencial para a funcionalidade e sucesso da aplicação, oferecendo aos usuários a melhor promoção possível com base em suas compras. Isso destaca sua capacidade de resolver problemas complexos e criar soluções técnicas que têm um impacto direto nas operações comerciais.
Informações sobre a Lógica do Sistema
- Algoritmo de cálculo de valores das promoções.
public ResponseEntity<?> retornaProdutoPromocao(@RequestBody Integer id, Integer quantidade, Integer total, Integer categoria) {
List<ProductPromotion> promotios = productPromotionRepository.findAll();
List<ProductPromotion> productPromotion = new ArrayList<ProductPromotion>();
Product product = productService.findById(id);
productPromotion.addAll(product.getProductPromotions());
int new = productPromotion.size();
...
return new ResponseEntity<>(desconto, HttpStatus.OK);
Consumido na camada controller através de um método com uma anotação HTTP, no caso dessa requisição foi utilizado o verbo Post.
O algoritmo mostrado é responsável por receber os parâmetros vindos do front end, esses parâmetros são filtrados por algumas condições, verificando o melhor valor de retorno para uma determinado produto que esteja em uma promoção, esse retorno é devolvido para camada controller que por sua vez devolve o resultado para a interface.
Minha participação no projeto incluiu um papel ativo na integração entre o Front-End e o Back-End, onde interagi na criação de diversos métodos e na condução de testes para validar as requisições.
Ao participar da integração entre essas duas partes fundamentais do sistema, contribuí para assegurar que a comunicação entre elas ocorresse de maneira suave e confiável. A criação de métodos no Back-End permitiu que o Front-End pudesse acessar e manipular dados e funcionalidades, garantindo a funcionalidade harmoniosa da aplicação como um todo.
A condução de testes para validar as requisições é uma etapa crucial para verificar se todas as partes do sistema estão funcionando conforme o esperado. Seu papel na execução desses testes evidencia seu comprometimento em entregar um produto de alta qualidade, minimizando possíveis erros e garantindo uma experiência consistente para os usuários.
Essa contribuição demonstra suas habilidades técnicas na criação de métodos funcionais e na realização de testes rigorosos. Além disso, ressalta sua capacidade de trabalhar de forma colaborativa entre as equipes de Front-End e Back-End, garantindo que a aplicação final seja coesa e eficaz.
Seu envolvimento na integração entre o Front-End e o Back-End teve um impacto direto na funcionalidade e usabilidade da aplicação, assegurando que os usuários possam interagir com uma interface responsiva e que todas as suas ações sejam processadas com precisão nos bastidores.
Detalhes da Interface do Usuário
- Algoritmo responsável de receber o retorno do back-end.
this.total = this.noDiscount += (element.price * element.quantidade);
this.service.getDiscount(this.id, this.quantidade, this.total, this.categoria).subscribe(
response =>
{ const product : Product = new Product();
this.discount = response;
this.product.discount = this.discount
this.finalPrice = this.finalPrice += (element.price * element.quantidade)-(this.discount)
console.log("teste", this.categoria)
errorResponse => console.log(errorResponse)
})
});
...
return new ResponseEntity<>(desconto, HttpStatus.OK);
- Esse método é responsável por passar os parâmetros para o back-end, processar a informação e direcionar o retorno para a camada de visualização do usuário, sendo um trecho importante pois enviar dados, processa o retorno e já devolve os resultados para usuário.
- Participei de forma efetiva na implementação de DTO's.
Informações sobre a Lógica do Sistema
@AllArgsConstructor
@NoArgsConstructor
@Data
@EqualsAndHashCode(of={"id"})
public class ProductDTO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
@NotBlank(message = "Name is required")
private String name;
@PositiveOrZero(message = "Price must be a value higher or equal to 0")
private Double price;
private List<CategoryDTO> categories = new ArrayList<>();
public ProductDTO(Product product) {
this.id = product.getId();
this.name = product.getName();
this.price = product.getPrice();
}
}
O trecho acima define uma classe chamada ProductDTO no pacote com.backend.backend.dto. Essa classe representa um objeto de transferência de dados (DTO) para a entidade Product. A classe ProductDTO implementa a interface Serializable, o que permite que os objetos dessa classe sejam serializados e desserializados. A classe possui os seguintes campos:
- id: Um campo do tipo Integer que representa o identificador do produto.
- name: Um campo do tipo String que representa o nome do produto. É anotado com @NotBlank para garantir que não esteja em branco.
- price: Um campo do tipo Double que representa o preço do produto. É anotado com @PositiveOrZero para garantir que seja maior ou igual a zero.
- categories: Uma lista de objetos CategoryDTO, representando as categorias associadas ao produto. É inicializada como uma lista vazia.
A classe possui os seguintes construtores e anotações:
- @AllArgsConstructor e @NoArgsConstructor: anotações do Lombok que geram automaticamente construtores com e sem argumentos, respectivamente.
- @Data: anotação do Lombok que gera automaticamente getters, setters, toString, equals e hashCode para todos os campos da classe.
- @EqualsAndHashCode(of={"id"}): anotação do Lombok que gera automaticamente os métodos equals e hashCode, considerando apenas o campo id.
Além disso, a classe possui um construtor adicional que recebe um objeto Product. Esse construtor é usado para converter um objeto Product em um objeto ProductDTO, copiando os valores do Product para as variáveis correspondentes em ProductDTO.
Essa classe é usada para transferir informações específicas de um produto entre diferentes partes de uma aplicação, geralmente em operações de criação, leitura, atualização e exclusão (CRUD) ou em serviços de API.
Integração do projeto com a disciplina de Engenharia de Software, explorando padrões de projeto e organização em camadas.
Exploração de diversos padrões de projeto, organizando o programa em camadas e seguindo padrões de arquitetura.
Desenvolvimento de competências fundamentais para qualquer desenvolvedor de software, incluindo modularização e métodos de construção comumente utilizados.
Consideração central na otimização de desempenho do sistema, lidando com uma base de dados de tamanho modesto e implementando métodos de processamento eficientes.
Valorização da evolução dos algoritmos de análise de dados ao longo do projeto, contribuindo para a formação como profissionais desenvolvedores.
Desenvolvimento constante da habilidade, destacando apresentações para clientes e professores avaliadores, além da comunicação eficiente dentro da equipe.
Aplicação da habilidade em um projeto com prazos mais curtos, buscando otimizar a eficiência.
Tomada de decisões assertivas em situações onde o melhor caminho nem sempre era claro, demonstrando habilidades críticas de gerenciamento de projetos.
Clique aqui para mais detalhes do projeto.
Mais Detalhes do Projeto IV
Figura 01. Logo Subiter Fonte(Subiter)
Neste projeto foi proposto a demanda de otimizar a gestão por meio da implementação de um sistema abrangente que engloba os cadastros de usuários, equipamentos e horários. A diversidade de perfis de usuários é essencial, com categorias distintas como administrador, suporte e cliente, garantindo a segurança e eficiência nas operações. O cerne do projeto reside no registro de chamados, um elemento central para a melhoria do atendimento. A falta de um sistema integrado tem levado a atrasos e dificuldades na resolução das demandas, impactando diretamente na satisfação dos clientes. A proposta inclui um acompanhamento de chamados de ponta a ponta, visando não apenas a resolução rápida, mas também a análise detalhada de cada interação, proporcionando insights valiosos para aprimorar continuamente os processos.
Informações sobre a Lógica do Sistema
public Chamado updateChamadoById(Integer id, Chamado chamado) {
Chamado chamadoSelector = this.getChamadoById(id);
String Ns = chamadoSelector.getAgendamento().getNumerosSerie();
String Ns = "";
if(chamadoSelector.getAgendamento() != null) {
Ns = chamadoSelector.getAgendamento().getNumerosSerie();
}
EquipamentoSerie equipamentoSerie = this.equipamentoSerie.getById(Ns);
if (chamado.getSituacaoChamado().equals("F") || chamado.getSituacaoChamado().equals("f")) {
equipamentoSerie.setDisponibilidade(true);
chamadoSelector.setEncerramentoChamado(LocalDate.now());
this.equipamentoSerie.save(equipamentoSerie);
}
chamadoSelector.setCriticidadeChamado(chamado.getCriticidadeChamado());
chamadoSelector.setDataChamado(chamado.getDataChamado());
chamadoSelector.setDescricaoChamado(chamado.getDescricaoChamado());
chamadoSelector.setSituacaoChamado(chamado.getSituacaoChamado());
chamadoSelector.setSolucaoChamado(chamado.getSolucaoChamado());
return chamadoRepository.save(chamadoSelector);
}
Este trecho é um método de atualização de chamado em uma aplicação com cada parte descrita a seguir:
-
O método recebe dois parâmetros: um ID do chamado a ser atualizado (representado por um número inteiro) e um objeto Chamado contendo as novas informações para atualização. Chamado chamadoSelector = this.getChamadoById(id); - Esta linha obtém o chamado existente com o ID fornecido usando um método getChamadoById (que não está presente neste trecho de código). O chamado original é armazenado na variável chamadoSelector.
-
String Ns = chamadoSelector.getAgendamento().getNumerosSerie(); - Esta linha extrai o número de série (atributo numerosSerie) do objeto Agendamento dentro do chamado selecionado e o armazena na variável Ns.
-
String Ns = ""; - Parece haver um erro neste trecho, pois a variável Ns já foi declarada anteriormente.
-
if(chamadoSelector.getAgendamento() != null) { Ns = chamadoSelector.getAgendamento().getNumerosSerie(); } - Esta condição verifica se o objeto Agendamento dentro do chamado selecionado não é nulo. Se não for nulo, o número de série é atribuído à variável Ns.
-
EquipamentoSerie equipamentoSerie = this.equipamentoSerie.getById(Ns); - Aqui, é obtido um objeto EquipamentoSerie com base no número de série obtido. O método getById (que pertence a uma instância de equipamentoSerie, provavelmente uma classe) é usado para obter o objeto correspondente ao número de série.
-
if (chamado.getSituacaoChamado().equals("F") || chamado.getSituacaoChamado().equals("f")) { ... } - Esta condição verifica se a situação do chamado recebido é igual a "F" ou "f". Se for, o seguinte bloco de código será executado:
a. equipamentoSerie.setDisponibilidade(true); - Define a disponibilidade do objeto equipamentoSerie como verdadeira.
b. chamadoSelector.setEncerramentoChamado(LocalDate.now()); - Define a data de encerramento do chamado selecionado como a data atual (representada por LocalDate.now()).
c. this.equipamentoSerie.save(equipamentoSerie); - Salva as alterações feitas no objeto equipamentoSerie no banco de dados ou em algum outro local de armazenamento.
As linhas seguintes atualizam várias propriedades do chamado selecionado com os valores fornecidos no objeto chamado.
- return chamadoRepository.save(chamadoSelector); - Por fim, o chamado selecionado, com todas as atualizações realizadas, é salvo utilizando o método save de um repositório chamado chamadoRepository (que não está presente neste trecho de código), e o chamado atualizado é retornado.
- Tive uma participação ativa na integração entre o Front-End e Back-End, desempenhando um papel crucial na criação de vários métodos e na execução de testes para assegurar a validade das requisições.
Detalhes da Interface do Usuário
import {http} from './config'
export default{
listar:(token) =>{
return http.get('/chamados', {headers:{Authorization: `Bearer ${token}`}})
},
salvar:(suporte)=>{
return http.post('/chamados', suporte)
},
deletar:(id)=>{
return http.delete('/chamados/' + id)
},
atualizar:(chamado)=>{
return http.patch('/chamados/' + chamado.id , chamado)
atualizar:(chamado, id, token)=>{
return http.patch('/chamados/' + id , chamado, {headers:{Authorization: `Bearer ${token}`}})
},
listarEquipamentosDisponiveis:(token) =>{
return http.get('/equipamento-serie/disponivel', {headers:{Authorization: `Bearer ${token}`}})
} ,
salvarAgendamento:(agendamento, token)=>{
return http.post('/agendamento', agendamento, {headers:{Authorization: `Bearer ${token}`}})
}
}
-
listar:(token) => { ... } - Esta função faz uma solicitação GET para obter a lista de chamados. Recebe um parâmetro token que é utilizado para autenticar a requisição. A URL para a solicitação GET é '/chamados', e o token de autorização é passado no cabeçalho da requisição.
-
salvar:(suporte) => { ... } - Esta função faz uma solicitação POST para salvar um novo chamado. Recebe um objeto suporte contendo as informações do chamado a ser salvo. A URL para a solicitação POST é '/chamados', e o objeto suporte é passado como corpo da requisição.
-
deletar:(id) => { ... } - Esta função faz uma solicitação DELETE para excluir um chamado com base em seu ID. Recebe um parâmetro id que representa o ID do chamado a ser excluído. A URL para a solicitação DELETE é '/chamados/' + id, onde o ID é concatenado à URL.
-
atualizar:(chamado) => { ... } - Esta função faz uma solicitação PATCH para atualizar um chamado existente. Recebe um objeto chamado contendo as informações atualizadas do chamado. A URL para a solicitação PATCH é '/chamados/' + chamado.id, onde o ID do chamado é concatenado à URL, e o objeto chamado é passado como corpo da requisição.
-
atualizar:(chamado, id, token) => { ... } - Esta função é uma versão modificada da função atualizar, que inclui um parâmetro adicional token para autenticar a requisição. Recebe um objeto chamado contendo as informações atualizadas do chamado, um parâmetro id que representa o ID do chamado a ser atualizado e um parâmetro token para autenticação. A URL para a solicitação PATCH é '/chamados/' + id, onde o ID é concatenado à URL, o objeto chamado é passado como corpo da requisição, e o token de autorização é passado no cabeçalho da requisição.
-
listarEquipamentosDisponiveis:(token) => { ... } - Esta função faz uma solicitação GET para obter a lista de equipamentos disponíveis. Recebe um parâmetro token que é utilizado para autenticar a requisição. A URL para a solicitação GET é '/equipamento-serie/disponivel', e o token de autorização é passado no cabeçalho da requisição.
-
salvarAgendamento:(agendamento, token) => { ... } - Esta função faz uma solicitação POST para salvar um novo agendamento. Recebe um objeto agendamento contendo as informações do agendamento a ser salvo e um parâmetro token para autenticação. A URL para a solicitação POST é '/agendamento', o objeto agendamento é passado como corpo da requisição, e o
Adquiri habilidades no uso do VueJs, explorando suas funcionalidades e sintaxe.
Compreendi a importância de consultar a documentação oficial do VueJs para obter informações detalhadas e precisas sobre a tecnologia.
Reconheci a necessidade de dedicar tempo a um estudo aprofundado para construir uma base sólida e confiável de conhecimento em VueJs.
Percebi que, embora os tutoriais sejam úteis para noções básicas, o estudo da documentação permitiu a compreensão das complexidades da tecnologia.
Aprofundei meu conhecimento explorando recursos avançados do VueJs, além do que é geralmente abordado em tutoriais introdutórios.
Reforcei a importância de estar constantemente em busca de novos aprendizados para acompanhar as evoluções tecnológicas.
Compreendi a necessidade de manter-me atualizado sobre as últimas tecnologias e tendências do mercado para permanecer relevante no cenário profissional.
Utilizando o conhecimento adquirido, desenvolvi um projeto mais sofisticado e eficaz, incorporando práticas avançadas do VueJs.
Ao explorar a documentação e desenvolver um projeto mais complexo, adquiri habilidades valiosas que contribuíram significativamente para minha trajetória profissional.
Clique aqui para mais detalhes do projeto.
Mais Detalhes do Projeto V
TransferCloud - Solução de Automação de Downloads e Gerenciamento em Nuvem com Painel de Monitoramento de Desempenho
Figura 01. Logo Midall Fonte(MidAll)
O projeto consiste em criar uma solução para automatizar o processo de download de arquivos de uma plataforma de vídeo e transferi-los para a nuvem. Isso foi alcançado através do desenvolvimento de uma aplicação como serviço que simplificou o processo para o usuário, permitindo que eles configurassem o serviço com os parâmetros necessários para o download automático. Além disso, a aplicação foi projetada para gerar alertas em caso de erros durante o processamento.
Uma parte crucial do desafio era salvar os metadados dos arquivos, que seriam posteriormente usados para construir um dashboard. Esse painel serviria para monitorar a execução do serviço, analisar resultados e fornecer indicadores importantes para avaliar o desempenho do sistema.
Desempenhei um papel central na implementação do Banco de Dados, desenvolvendo um Modelo Lógico e Relacional para efetuar a organização e armazenamento eficiente dos metadados dos arquivos. Isso envolveu a criação de tabelas, definição de relacionamentos entre elas e a escolha de estratégias de indexação para otimizar o acesso aos dados. Além disso, trabalhei na implementação das consultas SQL necessárias para recuperar os metadados com rapidez e precisão, contribuindo assim para a construção do dashboard de monitoramento.
Minha contribuição na elaboração do Modelo Lógico e Relacional foi fundamental para garantir que os metadados fossem armazenados de forma coerente e organizada, permitindo uma análise eficaz dos resultados e indicadores do serviço. Isso também facilitou a integração dos dados do banco de dados com a aplicação de serviço, criando uma solução completa e eficiente para o desafio do projeto.
Informações sobre a lógica utilizada na modelagem do Banco de Dados
Entidades:
Usuários (Users)
{
UserID (Chave Primária)
Nome
Email
Senha
Papel de Acesso (por exemplo, administrador, usuário comum)
}
Downloads (Downloads)
{
DownloadID (Chave Primária)
Nome do Arquivo
Data de Início do Download
Data de Conclusão do Download
Status do Download (em andamento, concluído, falha, etc.)
ID do Usuário (Chave Estrangeira relacionando ao Usuário que iniciou o download)
Arquivos na Nuvem (CloudFiles)
}
FileID (Chave Primária)
{
Nome do Arquivo
Localização na Nuvem
Tamanho do Arquivo
Data de Upload
ID do Usuário (Chave Estrangeira relacionando ao Usuário que fez o upload)
Registros de Desempenho (PerformanceLogs)
}
LogID (Chave Primária)
{
Data e Hora do Log
Descrição do Evento (por exemplo, início de download, conclusão de download, erro de download, etc.)
Detalhes Adicionais (por exemplo, velocidade de download, tamanho do arquivo, etc.)
ID do Download (Chave Estrangeira relacionando ao Download ao qual o log está associado)
}
Relacionamentos:
Um Usuário pode iniciar vários Downloads, então há uma relação um-para-muitos entre Usuários e Downloads.
Um Usuário pode fazer upload de vários Arquivos na Nuvem, então há uma relação um-para-muitos entre Usuários e Arquivos na Nuvem.
Cada Log de Desempenho está associado a um Download específico, estabelecendo uma relação um-para-muitos entre Downloads e Registros de Desempenho.
Este é um modelo lógico básico que pode ser adaptado às necessidades específicas do seu projeto. Você pode considerar adicionar mais detalhes, como
informações sobre os servidores de download, categorias de arquivos na nuvem, histórico de downloads, entre outros, conforme necessário para o seu
aplicativo de automação de downloads e gerenciamento em nuvem com painel de monitoramento de desempenho. Além disso, você pode definir as chaves
primárias, índices e restrições de integridade referencial apropriados com base nos requisitos do seu sistema.
Este modelo lógico de banco de dados é projetado para um sistema de automação de downloads e gerenciamento em nuvem, com ênfase no monitoramento de desempenho.
As principais entidades incluem Usuários, Downloads, Arquivos na Nuvem e Registros de Desempenho, cada uma com atributos relevantes. Os relacionamentos definem que um usuário pode iniciar vários downloads e fazer upload de vários arquivos na nuvem. Além disso, cada log de desempenho está associado a um download específico.
Informações sobre Migração de DataBase
import os
import subprocess
# Configurações
source_server = "ninjasnovo.********************"
target_server = "ninjastech.********************"
# Clone o repositório Git
def clone_repository():
os.system("git clone https://github.com/TechNinjass/midall-backend.git")
# Execute as tarefas de migração usando Ansible
def run_migration():
command = f"ansible-playbook {ansible_playbook_path}"
os.system(command)
# Atualize o repositório Git após a migração
def update_repository():
os.chdir("midall-backend")
os.system("git pull origin main")
# Faça o push das alterações para o novo servidor
def push_to_target():
os.system(f"rsync -avzhe ssh ./* main")
# Limpeza
def cleanup():
os.system("rm -rf midall-backend")
# Fluxo principal
def main():
repo_url = input("https://github.com/TechNinjass/midall-backend.git")
clone_repository(repo_url)
run_migration()
update_repository()
push_to_target()
cleanup()
if __name__ == "__main__":
main()
Este é uma ideia de automação de migração foi desenvolvido para facilitar a transição de um aplicativo de um servidor de origem para um servidor de destino. A migração é realizada utilizando práticas comuns de DevOps, incluindo a automação de tarefas com o Ansible e o controle de versão com o Git.
Esse processo tinha a intenção de trazer algumas funcionalidades como:
O script começa clonando o repositório Git do aplicativo a ser migrado. O repositório original está hospedado no GitHub.
Em seguida, o Ansible é utilizado para executar tarefas de migração específicas. As tarefas podem incluir a configuração de servidores, instalação de dependências, entre outras ações necessárias para a migração.
Após a migração, o repositório local é atualizado para refletir as alterações feitas durante o processo de migração.
As alterações no repositório local são então sincronizadas e enviadas para o novo servidor usando o comando rsync via SSH.
Por fim, mas não menos importante, para manter a organização, o script realiza a limpeza, removendo o repositório local.
Clique aqui para mais detalhes do projeto de migração de Database.
Desenvolvi um script em Python para automatizar o processo de migração de um aplicativo entre servidores, facilitando a execução de tarefas complexas de DevOps.
Utilizei comandos Git no script para clonar um repositório remoto, atualizar o repositório local após a migração e realizar operações de limpeza.
Integrei o Ansible no fluxo de trabalho para realizar tarefas de migração específicas, permitindo uma automação eficiente e consistente.
Utilizei o Rsync para sincronizar eficientemente arquivos entre o repositório local e o novo servidor, garantindo consistência nas alterações.
Implementei a capacidade de receber entrada do usuário para a URL do repositório Git, tornando o script mais flexível e adaptável a diferentes cenários.
Projetei o script para ser facilmente adaptável, permitindo que o usuário ajuste as configurações, como URLs de repositório e servidores, de acordo com os requisitos específicos.
Segui boas práticas de desenvolvimento, como modularização do código em funções, uso de comentários para documentação e identação consistente para melhor legibilidade.
Clique aqui para mais detalhes do projeto.
Mais Detalhes do Projeto VI
TechVision - Organização de um banco de dados público do Proagro para consultas e análises rápidas em Sistema de Informação Geográfica.
Figura 01. Logo Visiona Espacial Fonte(Visiona)
Foi proposto uma solução abrangente que envolve a coleta e o tratamento dos dados do programa Federal ProAgro, a reestruturação eficiente dos dados e o desenvolvimento de um Sistema de Informação Geográfica (SIG) personalizado, fornecendo informações de forma mais simples e organizada para o usuário. Essa abordagem busca facilitar a compreensão e análise dos dados, contribuindo para melhorias nos processos internos da empresa.
Desempenhei um papel essencial ao liderar a iniciativa relacionada ao banco de dados no projeto, assumindo a responsabilidade pela elaboração e implementação de um Modelo Lógico e Relacional robusto. O foco principal foi organizar e armazenar de maneira eficiente os metadados dos arquivos, assegurando a integridade e acessibilidade dos dados.
No âmbito da minha participação, desenvolvi um Modelo Lógico detalhado, delineando cuidadosamente as entidades envolvidas, seus atributos e os relacionamentos entre elas. Essa estrutura proporcionou uma base sólida para a criação das tabelas no banco de dados, incorporando estratégias de indexação que otimizaram significativamente o acesso aos metadados. A definição precisa dos relacionamentos entre as entidades foi crucial para garantir a consistência das informações armazenadas.
Além da arquitetura do banco de dados, concentrei meus esforços na implementação de consultas SQL estratégicas. Essas consultas foram projetadas para recuperar os metadados de maneira rápida e precisa, contribuindo de maneira decisiva para a construção do dashboard de monitoramento do projeto. A capacidade de extrair informações relevantes de forma eficiente foi um fator-chave para o sucesso do projeto como um todo.
Minha participação não se limitou apenas à criação do banco de dados; trabalhei de perto com a equipe para garantir uma integração perfeita entre os dados armazenados e a aplicação de serviço. Essa abordagem holística resultou em uma solução completa e eficiente para o desafio proposto, proporcionando uma base sólida para a análise de resultados e indicadores do serviço.
Em resumo, meu comprometimento com o desenvolvimento do banco de dados, desde a concepção do Modelo Lógico até a implementação das consultas SQL, desempenhou um papel fundamental na construção de uma estrutura coesa e eficaz para o projeto.
Informações sobre a lógica utilizada na modelagem do Banco de Dados
Entidade: Gleba_SP
Atributos:
REF_BACEN (Chave Primária)
NU_ORDEM
NU_IDENTIFICADOR
NU_INDICE_GLEBA
NU_INDICE_PONTO
CGL_VL_ALTITUDE
VL_VERTICES (Tipo Geometry)
A tabela glebas_sp armazena informações relacionadas a glebas de terras, Brasil. Aqui estão algumas explicações para os atributos:
REF_BACEN: Referência relacionada ao Banco Central (Identificador único para cada registro).
NU_ORDEM: Número de ordem.
NU_IDENTIFICADOR: Número identificador.
NU_INDICE_GLEBA: Número de índice da gleba.
NU_INDICE_PONTO: Número de índice do ponto.
CGL_VL_ALTITUDE: Valor da altitude.
VL_VERTICES: Dados geométricos representando os vértices (pontos) da gleba.
No seu caso, a coluna VL_VERTICES é do tipo geometry e é utilizada para armazenar informações sobre a forma geográfica da gleba do terreno. Isso pode incluir coordenadas espaciais que definem os vértices da gleba,
permitindo representar a forma da área de terra no plano geográfico.
Este modelo lógico de banco de dados é projetado para um sistema de armazenamento de coordenadas de áreas de terrenos.
Informações sobre scripts utilizados para manipulção de dados
import pandas as pd
from shapely.geometry import Point
from sqlalchemy import create_engine, Column, Integer, Text, Float, Geometry
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# Definindo a classe da tabela
Base = declarative_base()
class Gleba(Base):
__tablename__ = 'glebas_sp'
REF_BACEN = Column(Integer, primary_key=True)
NU_ORDEM = Column(Text)
NU_IDENTIFICADOR = Column(Text)
NU_INDICE_GLEBA = Column(Text)
NU_INDICE_PONTO = Column(Integer)
VL_LATITUDE = Column(Text)
VL_LONGITUDE = Column(Text)
CGL_VL_ALTITUDE = Column(Text)
VL_VERTICES = Column(Geometry(geometry_type='POINT', srid=4326))
# Configurações do banco de dados
db_user = 'techninjas'
db_password = '**********'
db_host = 'techninjas.microsoft'
db_port = '3306'
db_name = 'techvision'
# Criando a conexão com o banco de dados
engine = create_engine(f"mysql+mysqlconnector://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}")
# Criando a tabela no banco de dados (caso não exista)
Base.metadata.create_all(engine)
# Lendo o arquivo CSV
csv_path = '/glebas.csv'
df = pd.read_csv(csv_path)
# Criando objetos geométricos e inserindo no banco de dados
Session = sessionmaker(bind=engine)
session = Session()
for _, row in df.iterrows():
latitude = float(row['VL_LATITUDE'])
longitude = float(row['VL_LONGITUDE'])
point = Point(longitude, latitude)
gleba = Gleba(
REF_BACEN=row['REF_BACEN'],
NU_ORDEM=row['NU_ORDEM'],
NU_IDENTIFICADOR=row['NU_IDENTIFICADOR'],
NU_INDICE_GLEBA=row['NU_INDICE_GLEBA'],
NU_INDICE_PONTO=row['NU_INDICE_PONTO'],
VL_LATITUDE=row['VL_LATITUDE'],
VL_LONGITUDE=row['VL_LONGITUDE'],
CGL_VL_ALTITUDE=row['CGL_VL_ALTITUDE'],
VL_VERTICES=point
)
session.add(gleba)
session.commit()
session.close()
1 - Importação de Bibliotecas: pandas: Usada para manipulação de dados, especialmente para ler e escrever dados em formato de DataFrame. shapely.geometry.Point: Usada para representar objetos geométricos do tipo ponto. sqlalchemy: Uma biblioteca SQL para Python, usada para interagir com o banco de dados. declarative_base: Usada para criar classes de mapeamento ORM. sessionmaker: Usada para criar instâncias de sessão para interação com o banco de dados.
2 - Definição da Classe de Tabela: declarative_base: Função que retorna uma classe base para declarar modelos ORM. Gleba: Classe que herda de Base e representa a tabela glebas_sp no banco de dados.
3 - Criação da Conexão com o Banco de Dados: Criação de uma instância de Engine do SQLAlchemy para interagir com o banco de dados MySQL.
4 - Criação da Tabela no Banco de Dados: Criação da tabela glebas_sp no banco de dados se ela não existir.
5 - Leitura do Arquivo CSV: Leitura do arquivo CSV usando o pandas e armazenamento dos dados em um DataFrame (df).
6 - Criação de Objetos Geométricos e Inserção no Banco de Dados: Um loop através do DataFrame, onde para cada linha, são criados objetos geométricos do tipo Point a partir das colunas VL_LATITUDE e VL_LONGITUDE. Um objeto Gleba é criado para cada linha do DataFrame, e a coluna VL_VERTICES é preenchida com o objeto geométrico correspondente. Os objetos são adicionados à sessão e, ao final do loop, as alterações são confirmadas no banco de dados.
Querys para retorno de informações
SELECT
Glebas.REF_BACEN,
Glebas.VL_VERTICES,
S5.DT_EMISSAO AS DATA_EMISSAO_REFBACEN,
CASE
WHEN S5.CD_ESTADO = 'SP' THEN 'São Paulo'
ELSE S5.CD_ESTADO
END AS ESTADO,
GARAN_EMPREEND.DESCRICAO AS TIPO_SEGURO,
S5.DT_FIM_PLANTIO AS DATA_PLANTIO,
GRAO_IRRIG.DESCRICAO AS TIPO_IRRIGACAO,
GRAO.DESCRICAO AS TIPO_GRAO,
S5.VL_ALIQ_PROAGRO AS VALOR_ALIQUOTA,
S5.VL_JUROS AS JUROS_INVESTIMENTO,
S5.VL_RECEITA_BRUTA_ESPERADA AS RECEITA_BRUTA_ESTIMADA,
S5.DT_FIM_COLHEITA AS DATA_FIM_COLHEITA
FROM (
SELECT
GLP.REF_BACEN,
GLP.VL_VERTICES
FROM
techdata.glebas_sp GLP
ORDER BY
GLP.NU_INDICE_PONTO
) AS Glebas
JOIN techdata.saida5 S5 ON S5.REF_BACEN = Glebas.REF_BACEN
JOIN techvision.grao_semente GRAO ON GRAO.CODIGO = S5.CD_TIPO_GRAO_SEMENTE
LEFT JOIN techvision.tipo_irrigacao GRAO_IRRIG ON GRAO_IRRIG.CODIGO = S5.CD_TIPO_IRRIGACAO
LEFT JOIN (
SELECT
CODIGO,
DESCRICAO
FROM
techvision.tipo_garantia_empreendimento
) AS GARAN_EMPREEND ON GARAN_EMPREEND.CODIGO = S5.CD_TIPO_SEGURO
GROUP BY
Glebas.REF_BACEN, S5.DT_EMISSAO,
S5.CD_ESTADO, GARAN_EMPREEND.DESCRICAO,
GRAO_IRRIG.DESCRICAO, GRAO.DESCRICAO,
S5.DT_FIM_PLANTIO, S5.CD_TIPO_IRRIGACAO,
S5.VL_ALIQ_PROAGRO, S5.CD_TIPO_CULTIVO,
S5.VL_JUROS, S5.VL_RECEITA_BRUTA_ESPERADA,
S5.DT_FIM_COLHEITA, S5.VL_PERC_CUSTO_EFET_TOTAL
A subconsulta interna (SELECT GLP.REF_BACEN, GLP.VL_VERTICES FROM techdata.glebas_sp GLP ORDER BY GLP.NU_INDICE_PONTO) seleciona os campos REF_BACEN e VL_VERTICES da tabela glebas_sp, ordenados pelo NU_INDICE_PONTO.
Essa subconsulta é renomeada como Glebas e serve como base para a junção posterior.
A consulta principal junta a subconsulta Glebas com a tabela techdata.saida5 usando a condição S5.REF_BACEN = Glebas.REF_BACEN.
Além disso, são realizadas junções adicionais com as tabelas techvision.grao_semente, techvision.tipo_irrigacao e techvision.tipo_garantia_empreendimento.
A consulta seleciona vários campos, incluindo REF_BACEN, VL_VERTICES, DT_EMISSAO, CD_ESTADO, e outros.
A cláusula CASE é usada para alterar o valor da coluna ESTADO dependendo do valor de CD_ESTADO, renomeando o estado "SP" para "São Paulo".
Os resultados são agrupados usando a cláusula GROUP BY com base em várias colunas, incluindo REF_BACEN, DT_EMISSAO, CD_ESTADO, e outros.
Funções de agregação, como SUM ou AVG, não estão presentes na consulta, mas poderiam ser adicionadas se necessário.
A consulta retorna informações sobre glebas agrícolas, suas safras associadas, tipos de grãos, informações sobre irrigação, seguro agrícola e outros detalhes relevantes.
Os resultados são organizados de acordo com as colunas especificadas na cláusula GROUP BY.
Ao longo do projeto aprendi bastante sobre bancos de dados e manipulação de dados, adquiri uma compreensão aprofundada dos conceitos fundamentais e das práticas essenciais associadas a tecnologia.
Ganhei proficiência na linguagem SQL, que serve como a espinha dorsal para interação com bancos de dados relacional.
A capacidade de criar consultas SQL eficientes para recuperar, inserir, atualizar e excluir dados proporcionou-me uma base
sólida para a manipulação eficaz de informações em um ambiente de banco de dados relacional.
Explorando a criação de procedimentos armazenados e funções no MySQL, ganhei a capacidade de encapsular lógica de negócios no banco de dados. Isso não apenas promove a modularidade, mas também contribui para a segurança e eficiência na execução de operações complexas.
Aprendi as práticas recomendadas para realizar backups regulares e garantir a recuperação eficiente de dados em situações de falha.
A segurança e a integridade dos dados são prioridades, e a capacidade de restaurar dados é essencial para a continuidade dos negócios.
Ganhei familiaridade com o armazenamento e manipulação de dados geoespaciais no MySQL, utilizando tipos de dados espaciais e consultas espaciais.
Isso é essencial para projetos relacionados a Sistemas de Informação Geográfica (SIG) e análise geográfica.
Clique aqui para mais detalhes do projeto.