image

Acesse bootcamps ilimitados e +650 cursos

50
%OFF
Article image
Franklyn Sancho
Franklyn Sancho27/09/2023 17:16
Compartilhe

Resumão de SQL - Conceitos Básicos, Exemplos Práticos e Roteiro de estudos

    SUMÁRIO

    1. Introdução
    2. O que é SQL
    3. Os comandos SQL
    4. Subconsultas
    5. Primary Key e Foreign Key
    6. Relação entre tabelas
    7. Normalização do banco de dados;
    8. E sobre ORMS?
    9. Exemplos de SQL em códigos
    10. Conclusão

    INTRODUÇÃO 

     

    Muitos desenvolvedores perguntam qual linguagem se deveria aprender como segunda opção. Para responder essa pergunta, farei uma outra pergunta: qual linguagem está presente na maioria dos projetos? Sim, o SQL. Inclusive, eu acredito que todo desenvolvedor deveria estudá-la em conjunto com a linguagem escolhida, principalmente aqueles que pretendem se tornar desenvolvedores backend.  

    Se você é um novato no mundo da programação e já participou desses eventos das escolas de programação, onde se é desenvolvido um projeto real em uma semana, talvez tenha lidado com o SQL de uma forma diferente, por um ORM, e, por este motivo, pode não estar familiarizado. Mas não se preocupem, pois neste artigo falaremos sobre tudo isso.

    MAS O QUE É SQL? 

     

    Structured Query Language (SQL), lit. "linguagem de consulta estruturada", é uma linguagem de domínio específico desenvolvida para gerenciar dados relacionais em um sistema de gerenciamento de banco de dados, ou para processamento de fluxo de dados em um sistema de gerenciamento de fluxo de dados.” 


    Resumindo, é uma linguagem desenvolvida para lidar com banco de dados relacionais, ou seja, aqueles organizados por meio de tabelas, também chamadas de entidades, onde seus dados (das entidades ou tabelas) são definidos por meio de linhas e colunas. Vejam o exemplo abaixo: 


    image

    Imagem 1: Temos uma entidade (ou tabela) User, recebendo os seguintes campos: id, nome, email, password, emailConfirmToken, emailConfirmationExpires, emailConfirmed; uma outra entidade (ou tabela) Meetings, recebendo os seguintes campos: id, type, title, body, DateTime e image; e uma última tabela visitor, recebendo id e name

    OS COMANDOS SQL

     

    Antes da gente entrar nos assuntos mais práticos, precisamos falar sobre os bancos de dados relacionais mais usados:  

    • SQLServer: desenvolvido pela Microsoft;  
    • PostgreSQL: código aberto;  
    • Oracle Database: desenvolvido pela Oracle 
    • SQLite: software livre, onde seus dados são armazenados localmente; 
    • MySQL: código aberto;  

     

    Além dos contextos em que cada um deles tem suas vantagens e desvantagens, os comandos (que falaremos neste capítulo) também possuem algumas diferenças. Porém, assim como nas outras linguagens, dominando qualquer uma delas, não teremos qualquer dificuldade em entender as outras. 


    Neste capítulo, veremos apenas os comandos básicos (CRUD) individualmente, mas prometo trazer alguns modelos de aplicações reais nos capítulos posteriores.

    Quando eu falo em comandos individuais, é porque assim como o terminal dos sistemas operacionais (bash e shell), os bancos de dados nos permitem entrar com comandos numa interface CLI: 


    image

    Imagem 2: O CLI do banco de dados SQLite3.

    Duas observações antes de prosseguirmos:

    1. Estes comandos rodam no SQLite, mas pode haver algumas diferenças em outros bancos.
    2. Existem dois tipos de comandos: DDL e DML. O primeiro é um acrônimo de Data Definition Language, ou seja, os comandos responsáveis por definir e estruturar um banco de dados (CREATE e DROP, por exemplo). Já o DML é acrônimo de Data Manipulation Language, ou seja, os comandos responsáveis por manipular os dados (INSERT, UPDATE, SELECT E DELETE).


    Criando uma tabela (CREATE TABLE)

     

    Para criar uma tabela ou uma entidade no banco de dados, basta entrar com CREATE TABLE e os atributos:


    CREATE TABLE Usuarios ( 
      ID INTEGER PRIMARY KEY, 
      Nome TEXT NOT NULL, 
      Email TEXT NOT NULL UNIQUE, 
      Senha TEXT NOT NULL 
    );
    


    Com este comando nós criamos a tabela Usuarios no banco de dados com os seguintes atributos: id, nome, e-mail, senha.

    • id: receberá um valor inteiro e será chave primária da nossa tabela (falaremos disso em breve);
    • nome: receberá um valor de texto e não poderá ser nulo;
    • email: receberá um valor de texto, não poderá ser nulo e seu valor deve ser único, ou seja, não poderá existir outro usuário com o mesmo e-mail;
    • senha: receberá um valor de texto e não poderá ser nulo também.


    Adicionando Dados na Tabela (INSERT)

     

    Com a nossa tabela criada, podemos adicionar os dados por meio do comando INSERT:

     

    INSERT INTO Usuarios (ID, Nome, Email, Senha) VALUES (1, 'Anakin', 'darthvader@imperio.com', 'senha123'); 
    

     

    Será adicionado um usuário com os seguintes atributos:

    {

    • id: 1,
    • nome: Anakin,
    • email: darthvader@imperio.com,
    • senha: senha123

    }


    Selecionando/Resgatando Dados na Tabela (SELECT)

     

    Se quiser retornar todos os dados inseridos na tabela, basta entrar com o comando SELECT, a chave * e o nome da entidade:

     

    SELECT * FROM Usuarios; 
    

     

    Este comando retorna todos os dados contidos na tabela Usuarios, como só temos um dado, só será retornado um. Se a gente tivesse mais dados e quisesse filtrar um usuário em específico, por seu email, por exemplo, bastava: 

     

    SELECT * FROM Usuarios WHERE Email = 'darthvader@imperio.com'; 
    

     

    A cláusula WHERE nos permite filtrar os dados que serão manipulados. No comando acima, por exemplo, estamos dizendo para o banco que apenas os dados do usuário com o Email 'darthvader@email.com' deverão ser retornados. E se em vez de retornar todos os dados, a gente quisesse apenas o nome:

     

    SELECT Nome FROM Usuarios; 
    

     

    Obs. No lugar do Nome poderia ser Email ou qualquer outro dado contido no banco de dados. 

     

    Atualizando Dados na Tabela (UPDATE)

     

    Para atualizar os dados de uma entidade (ou tabela) no banco de dados, basta entrar com o comando UPDATE e a cláusula WHERE para filtrar o dado que se deseja atualizar:

     

    UPDATE Usuarios SET Nome = ‘Darth Vader’ WHERE Email = ‘darthvader@imperio.com’; 
    

     

    O nome do usuário que antes era Anakin, será atualizado para Darth Vader. Muito simples, né? Lembrando que no lugar do Nome poderia ser qualquer outro atributo.

     

    Deletando Dados na Tabela (DELETE)

     

    Para deletar um dado no banco de dados é muito fácil, basta entrar com o seguinte comando:  

     

    DELETE FROM Usuarios WHERE Email = ‘darthvader@imperio.com’ 
    

     

    Vocês perceberam que em todos os exemplos nós filtramos os dados pelo email, né? Isso acontece porque é muito importante que este filtro seja por meio de um dado único. Por exemplo, imagina que você quisesse apagar os dados de uma usuária chamada 'maria da silva', filtrando o comando delete pelo nome, todas as 'maria da silva' do seu banco de dados serão deletadas.


    Deletando Uma Tabela (DROP TABLE)

     

    Para deletar a tabela usuários do seu banco de dados, basta entrar com o comando DROP TABLE:

     

    DROP TABLE Usuarios 
    

     

    Para verificar se foi deletado mesmo, basta entrar com o comando .tables no SQLite - se nada for retornado, então foi deletado.


    SUBCONSULTAS  


    Agora que os comandos básicos do SQL já foram devidamente falados, podemos passar para o próximo tópico: subconsultas. Adianto que este já é um assunto mais intermediário do SQL e que requer um domínio dos conceitos básicos. Mas o que seria isso? Explicando de forma muito geral, seria como uma consulta dentro de outra consulta.

    Para este tópico, imagina que você está trabalhando num banco que tenha mil usuários cadastrados e você precisa retornar os dados de todos os usuários que tenham se cadastrados com um gmail. Como você poderia fazer isso? Se você respondeu com uma subconsulta, está errado! Apesar de ser uma busca um pouco mais sofisticada, uma consulta básica já resolve o problema:


    SELECT * FROM Usuarios WHERE Email LIKE ‘%@gmail.com';	 
    


    Para explicar as subconsultas, imagina que neste banco de dados com mil usuários, além de nome e email, haja também um atributo salário. Vamos supor que a gente queira saber qual o nome do usuário que tem o menor salário. Neste caso, precisaremos usar uma subconsulta, veja abaixo:

    SELECT Nome FROM Usuarios WHERE Salário = (SELECT MAX(Salário) FROM Usuarios) 
    

     

    Vejam que no comando acima o SELECT é chamado duas vezes, primeiro para consultar o maior salário e depois o nome do usuário encontrado na primeira consulta. Estes são os comandos separadamente:


      SELECT MAX(Salário) FROM Usuarios //retorna o maior salário 
      SELECT Nome FROM Usuarios WHERE Salário //retorna o nome do usuário 
    

     

    E se a gente quisesse descobrir qual é o usuário com o menor salário entre todos eles? O comando é muito parecido, mudando apenas o MAX para MIN:  


    SELECT Nome FROM Usuarios WHERE Salário = (SELECT MIN(Salário) FROM Usuarios) 
    

     

    Existe uma cláusula no SQL (EXISTS) que verifica se uma consulta é válida, ou seja, se existe algum dado que esteja dentro das condições de filtragens:  


    SELECT EXISTS (SELECT 1 FROM Usuarios WHERE Salario > 5000); 
    

     

    Este comando verifica se existe algum usuário com salário acima de 5000, caso verdadeiro, o banco retorna 1, caso falso, retorna 0. Se além de verificar se existe, você quiser buscar o nome dos usuários dentro dessa condição, basta fazer a seguinte subconsulta:

     

    SELECT Nome FROM Usuarios WHERE EXISTS (SELECT 1 FROM Usuarios 	WHERE Salário > 5000); 
    

     

    Para o artigo não ficar muito longo, vou deixar as outras cláusulas para um outro artigo. Mas se vocês quiserem aprender, basta pesquisar sobre o HAVING, ANY, SOME e etc.


    PRIMARY KEY E FOREIGN KEY 

     

    Também conhecidas como chave primária e chave estrangeira. Voltando lá no segundo tópico, onde explicamos o que é SQL, temos duas tabelas: Postagens e Usuarios.

    Pela estrutura das tabelas, sabemos que a aplicação tem a capacidade de armazenar os dados de usuários com id, nome, email e senha; e das postagens com id, assunto, título corpo. Se a gente quisesse inserir dados em ambas as tabelas, teríamos que chamar o comando INSERT:

     

    INSERT INTO Usuarios (ID, Nome, Email, Senha) VALUES (1, 'Anakin', 		'darthvader@imperio.com', 'senha123'); 
    

      

    INSERT INTO Postagens (ID, Assunto, Título, Corpo) VALUES (1, 'Teste', 'Titulo 	Teste', 'Corpo de Teste'); 
    

     

    Mas pensem comigo: qual seria o propósito de uma aplicação em que o usuário pode se registrar OU fazer uma postagem? em outras palavras, uma não depende da outra? Não seria mais viável que o usuário tivesse que se registrar primeiro para então poder adicionar uma postagem? E é neste momento que falaremos sobre chave primária e estrangeira.  

    Vocês lembram que eu falei da importância de o ID ser um número único para cada entidade do nosso banco de dados? Isso acontece porque geralmente é ele a chave primária das tabelas. Vamos recriar as nossas tabelas da seguinte forma:  


    CREATE TABLE Usuarios ( 
      ID INTEGER PRIMARY KEY, 
      Nome TEXT NOT NULL, 
      Email TEXT NOT NULL UNIQUE, 
      Senha TEXT NOT NULL 
    ); 
    

      

    CREATE TABLE Postagens ( 
      Id INTEGER PRIMARY KEY, 
      Assunto TEXT NOT NULL, 
      Título TEXT NOT NULL, 
      Corpo TEXT NOT NULL, 
      Autor INTEGER, 
      FOREIGN KEY(autor) REFERENCES usuarios(id) 
    ); 
    

     

    A única mudança que fizemos foi na tabela Postagens, onde adicionamos um campo autor, recebendo um inteiro, e o referenciamos com uma chave estrangeira. No exemplo acima, a chave estrangeira será referenciada com o ID do usuário, ou seja, a chave primária da tabela Usuarios.

    Explicando de forma didática, imagina que o usuário acesse essa aplicação por meio do seu login e faça uma postagem. O atributo autor será preenchido com o ID desse usuário logado, ou seja, há uma relação entre a chave primária da tabela Usuários e a referência feita na tabela Postagens

     

    INSERT INTO Postagens (ID, Assunto, Título, Corpo, Autor) VALUES (1, 'Teste', 'Titulo 	Teste', 'Corpo de Teste', 1); 
    

     

    Mais um exemplo: veja que no comando acima, onde inserimos um novo dado na tabela Postagens - agora com o campo autor. Repare que ele foi preenchido com o valor 1, ou seja, o ID do usuário Anakin. O ID do Anakin é a chave primária da tabela Usuarios e chave estrangeira da tabela Postagens.


    Duas observações importantes:

    1. todas as tabelas só poderão ter uma, e somente uma, chave primária (Porque seu propósito é ser como um valor de identificação, assim como o nosso CPF).
    2. A chaves primárias precisam ter um valor único para cada dado inserido na tabela.


    Clareando essa ideia da unicidade: O campo rua poderia ser a chave primária da tabela endereço? Não! Pois mais de uma pessoa mora na mesma rua; e o campo bairro? Menos ainda!


    RELACIONAMENTO ENTRE TABELAS

     

    Basicamente, existem 3 tipos de relacionamentos entre tabelas: um para muitos (1:N), um para um (1:1) e muitos para muitos (N:N).


    Um Para Muitos (1:N) 

    Este é um relacionamento em que cada elemento de uma tabela pode se relacionar com muitos elementos de uma outra tabela. Por exemplo, vamos supor que a gente tenha duas tabelas:

    • A primeira tabela Usuarios contendo o CPF como chave primária
    • A segunda tabela telefones, contendo idcliente como chave estrangeira e um campo telefone.

    Concordamos que cada usuário só pode ter um CPF, mas um único CPF pode ter vários telefones, correto? Ou seja, este é um exemplo de uma relação um para muitos, onde um CPF pode se relacionar com muitos telefones. Um outro exemplo seria de um curso, onde um único curso pode ter muitos alunos matriculados. 

     

    Um para Um (1:1) 

     

    Este é um relacionamento em que cada elemento só pode se relacionar com apenas um elemento de uma outra tabelas. Por exemplo, imagina duas tabelas:


    • A primeira Funcionários, contendo apenas as informações básicas: id, nome, idade.
    • A segunda Documentos, contendo CPF e PIS;


    Se cada funcionário só pode ter um CPF e PIS, então é um relação um por um


    Muitos Para Muitos (N:N) 

     

    Este é um relacionamento em que muitos elementos de uma tabela podem se relacionar com muitos elementos de outra tabela. Por exemplo, duas tabelas:


    • A primeira produtos, contendo os dados dos produtos
    • A segunda vendas, contendo os dados das vendas


    Se os produtos fossem livros, por exemplo, uma única venda pode ter muitos livros de autoajuda, assim como um mesmo livro de autoajuda, pode estar em muitas vendas.


    NORMALIZAÇÃO DO BANCO DE DADOS  

     

    Modelar um banco de dados não é algo simples, onde só basta criar uma tabela e jogar os dados que parecem fazer algum sentido, é necessário analisar e estudar as regras de negócio.

    Além disso, existem algumas normas que, se seguidas, garantem mais integridade e menos redundância de dados. Estas normas chamamos de normalização do banco de dados:


    Primeira Forma Normal (1FN)

     

    A primeira forma normal diz que os dados de um banco de dados devem ser atômicos, ou seja, mínimos, não podendo conter valores repetidos ou multi-valorados. Além disso, as tabelas devem conter uma chave primária, onde seus valores não podem ser nulos.

    Em relação aos valores que podem ser multi-valorados, um telefone, por exemplo, para normalizar, basta criar uma tabela telefone e referenciar esse valor por meio das chaves.

     

    Segunda Forma Normal (2FN) 

     

    Para estar na segunda forma normal, é necessário estar na primeira forma normal. Além disso, todos os dados não chave precisam ser dependentes da chave. Por exemplo, se você tem uma tabela Clientes, contendo o id (chave primária), nome, CPF e idconta, para estar dentro da segunda forma, seria necessário retirar o idconta e criar uma tabela Conta, referenciando os valores.

     

    Terceira Forma Normal (3FN)

     

    Para estar na terceira forma normal, é necessário estar na segunda forma normal, além disso, todos os atributos precisam ser dependentes da chave primária e independentes entre si. 


    “Por exemplo, se temos um atributo SALÁRIO e um atributo FGTS, lembrando que o cálculo do FGTS depende do Salário, então um depende do outro. Para resolver isso e deixar dentro da normalização, basta criar uma tabela com os direitos trabalhistas e referenciar por meio das chaves.”


    E SOBRE OS ORMS?  

     

    Vocês lembram que eu falei no início desse artigo que muitos podem não estar familiarizados com o SQL devido ao ORM? Esta é uma técnica usada por muitos cursos para levantar um banco de dados em alguma aplicação, onde o desenvolvedor não precisa se preocupar com os códigos em SQL. Veja essa descrição do Wikipedia em relação aos ORMS:  

     

    “Mapeamento objeto-relacional (ou ORM, do inglês: Object-relational mapping) é uma técnica de desenvolvimento utilizada para reduzir a impedância da programação orientada aos objetos utilizando bancos de dados relacionais.[1][2] As tabelas do banco de dados são representadas através de classes e os registros de cada tabela são representados como instâncias das classes correspondentes. Com esta técnica, o programador não precisa se preocupar com os comandos em linguagem SQL; ele irá usar uma interface de programação simples que faz todo o trabalho de persistência.” 

      

    Vejam o exemplo abaixo, onde criamos as duas tabelas numa aplicação Javascript por meio do Prisma. Repare que não precisamos chamar o comando CREATE e nem colocar os tipos do SQL (TEXT, INTEGER e etc), em vez disso, colocamos os tipos da linguagem (STRING, NUMBER, BOOLEAN e etc)


    image

    imagem 3: criação de tabela por meio do prisma (ORM)


    Pontos de Segurança Nessa Imagem


    O @default no atributo ID garante que todos os dados inseridos na tabela tenham um ID único no formato CUIDum número com 25 caracteres que, apesar de finito, garante mais segurança nos dados. Seu formato é semelhante a algo assim: cll6waiv9006vc0rjue1r8ml1 (sempre começando com a letra C).  

    Existem outros números que garantem essa segurança também, tal como o UUID, que tem 32 caracteres e um formato parecido com este aqui: 123e4567-e89b-12d3-a456-426655440000 – peguei essa informação do Wikipedia;


    EXEMPLOS DE SQL EM CÓDIGOS 

     

    Para finalizar o artigo, veremos algumas imagens onde o SQL está presente em algumas aplicações (RUST e JAVASCRIPT)


    image

    imagem 4: criação de tabelas numa aplicação em RUST


    image

    imagem 5: função em rust para inserir usuários na tabela USER


    image

    imagem 6: função em rust para atualizar a tabela accounts


    image

    imagem 7: função em javascript para criar uma tabela usuário, repare no if not exists, dizendo que a tabela só será criado, caso ela não exista.


    image

    imagem 8: função em javascript para consultar um produto pela marca


    Não detalhei muito sobre os códigos acima porque eles já são auto-explicativos, além do mais, existem comentários também, explicando o que cada função faz. Com tudo o que a gente viu até agora sobre os comandos SQL, já somos capazes de entender o que faz cada comando SQL dentro dessas funções RUST e JAVASCRIPT.

    CONCLUSÃO  

     

    Queria muito trazer os conceitos mais avançados da linguagem SQL, mas aí teria que escrever um livro, em vez de um artigo. Tentei trazer os conceitos básicos mais importantes, apesar de ter faltado muita coisa ainda. Se quiser se aprofundar, segue um roteiro de estudos:

     

    https://roadmap.sh/sql 

     

    Cursos gratuitos (Bônus) 

     

    Sim, é possível encontrar muitos cursos gratuitos de SQL por aí. Além da Própria DIO, podemos encontrar cursos gratuitos na UDEMY, YOUTUBE:


    https://www.udemy.com/courses/search/?price=price-free&q=sql&sort=relevance&src=ukw 

     

    https://www.udemy.com/courses/search/?price=price-free&q=banco+de+dados&sort=relevance&src=ukw 


    https://www.youtube.com/watch?v=Ofktsne-utM&list=PL4Sl6eAbMK7RU3OL2bbB_R--iwj3QFqLA

    Enfim, no próprio youtube a gente encontra diversos cursos gratuitos de SQL e banco de dados;


    FONTES

    https://pt.wikipedia.org/wiki/Mapeamento_objeto-relacional 

    https://blog.betrybe.com/sql/

    https://aws.amazon.com/pt/what-is/sql/

    https://pt.wikipedia.org/wiki/SQL

    https://www.oracle.com/br/database/what-is-a-relational-database/

    https://cloud.google.com/learn/what-is-a-relational-database?hl=pt-br

    https://azure.microsoft.com/pt-br/resources/cloud-computing-dictionary/what-is-a-relational-database/

    https://learn.microsoft.com/pt-br/sql/relational-databases/performance/subqueries?view=sql-server-ver16

    Compartilhe
    Comentários (1)

    GO

    Gustavo Oliveira - 27/09/2023 17:22

    Conteúdo muito bom pra que está se aventurando em SQL ou até pra quem tem curiosidade sobre a linguagem. Muito bom!