<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yuri Peixinho</title>
    <description>The latest articles on DEV Community by Yuri Peixinho (@yuripeixinho).</description>
    <link>https://dev.to/yuripeixinho</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1647416%2Fcb24132f-cdc1-4080-8977-0786f79ceb26.png</url>
      <title>DEV Community: Yuri Peixinho</title>
      <link>https://dev.to/yuripeixinho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yuripeixinho"/>
    <language>en</language>
    <item>
      <title>SQL: JOIN Queries</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Mon, 13 Jul 2026 01:12:49 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/sql-join-queries-2a5n</link>
      <guid>https://dev.to/yuripeixinho/sql-join-queries-2a5n</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Bancos de dados relacionais distribuem informações em múltiplas tabelas de propósito — para evitar redundância e garantir integridade. Mas na hora de consultar, frequentemente precisamos de dados que estão espalhados por duas ou mais tabelas. É aí que entram os&amp;nbsp;&lt;strong&gt;JOINs&lt;/strong&gt;: operações que combinam linhas de tabelas distintas com base em uma condição de correspondência.&lt;/p&gt;

&lt;p&gt;Para todos os exemplos, usaremos estas duas tabelas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;cidade&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="c1"&gt;----|-------------|----------------|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Ana&lt;/span&gt; &lt;span class="n"&gt;Lima&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;Paulo&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Bruno&lt;/span&gt; &lt;span class="n"&gt;Melo&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Curitiba&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Carla&lt;/span&gt; &lt;span class="n"&gt;Nunes&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Rio&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;Janeiro&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Diego&lt;/span&gt; &lt;span class="n"&gt;Costa&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Bras&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="n"&gt;lia&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;

&lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;cliente_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;produto&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="c1"&gt;----|------------|----------|---------|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Notebook&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3500&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Mouse&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Teclado&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Monitor&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dois detalhes importantes:&amp;nbsp;&lt;strong&gt;Diego (id=4) não tem nenhum pedido&lt;/strong&gt;. E o&amp;nbsp;&lt;strong&gt;pedido 4 referencia o cliente_id 99&lt;/strong&gt;, que não existe na tabela de clientes. Esses casos-limite vão revelar o comportamento de cada tipo de JOIN.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;INNER JOIN&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Retorna apenas as linhas que têm correspondência nos&amp;nbsp;&lt;strong&gt;dois lados&lt;/strong&gt;. Linhas sem par são descartadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cliente_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| nome       | produto  | valor   |
|------------|----------|---------|
| Ana Lima   | Notebook | 3500.00 |
| Ana Lima   | Mouse    |   80.00 |
| Bruno Melo | Teclado  |  150.00 |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Diego desapareceu — não tem pedidos. O pedido 4 (cliente_id=99) também desapareceu — não tem cliente correspondente. O&amp;nbsp;&lt;code&gt;INNER JOIN&lt;/code&gt;&amp;nbsp;é o mais restritivo: só retorna o que existe nos dois lados.&lt;/p&gt;

&lt;p&gt;É o tipo de JOIN mais comum, e a palavra&amp;nbsp;&lt;code&gt;INNER&lt;/code&gt;&amp;nbsp;é opcional —&amp;nbsp;&lt;code&gt;JOIN&lt;/code&gt;&amp;nbsp;sozinho já implica&amp;nbsp;&lt;code&gt;INNER JOIN&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;LEFT JOIN&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Retorna&amp;nbsp;&lt;strong&gt;todas as linhas da tabela da esquerda&lt;/strong&gt;, com os dados da tabela da direita onde houver correspondência. Onde não houver, os campos da direita vêm como&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cliente_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| nome        | produto  | valor   |
|-------------|----------|---------|
| Ana Lima    | Notebook | 3500.00 |
| Ana Lima    | Mouse    |   80.00 |
| Bruno Melo  | Teclado  |  150.00 |
| Carla Nunes | NULL     | NULL    |
| Diego Costa | NULL     | NULL    |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora Diego e Carla aparecem — sem pedidos, mas presentes. O&amp;nbsp;&lt;code&gt;LEFT JOIN&lt;/code&gt;&amp;nbsp;é ideal para perguntas do tipo:&amp;nbsp;&lt;em&gt;"quais clientes ainda não fizeram nenhum pedido?"&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cliente_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| nome        |
|-------------|
| Carla Nunes |
| Diego Costa |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Filtrar por&amp;nbsp;&lt;code&gt;IS NULL&lt;/code&gt;&amp;nbsp;no lado direito após um&amp;nbsp;&lt;code&gt;LEFT JOIN&lt;/code&gt;&amp;nbsp;é um padrão clássico para encontrar registros sem correspondência.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;RIGHT JOIN&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O espelho do&amp;nbsp;&lt;code&gt;LEFT JOIN&lt;/code&gt;: retorna&amp;nbsp;&lt;strong&gt;todas as linhas da tabela da direita&lt;/strong&gt;, com os dados da esquerda onde houver correspondência.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;RIGHT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cliente_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| nome       | produto  | valor   |
|------------|----------|---------|
| Ana Lima   | Notebook | 3500.00 |
| Ana Lima   | Mouse    |   80.00 |
| Bruno Melo | Teclado  |  150.00 |
| NULL       | Monitor  |  900.00 |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora o pedido 4 aparece — com&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;no nome do cliente, pois o&amp;nbsp;&lt;code&gt;cliente_id=99&lt;/code&gt;&amp;nbsp;não existe. Diego e Carla voltam a sumir.&lt;/p&gt;

&lt;p&gt;Na prática,&amp;nbsp;&lt;code&gt;RIGHT JOIN&lt;/code&gt;&amp;nbsp;é pouco usado — qualquer&amp;nbsp;&lt;code&gt;RIGHT JOIN&lt;/code&gt;&amp;nbsp;pode ser reescrito como&amp;nbsp;&lt;code&gt;LEFT JOIN&lt;/code&gt;&amp;nbsp;invertendo a ordem das tabelas, o que muitos consideram mais legível. Ele existe por simetria e completude da linguagem.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;FULL OUTER JOIN&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Combina&amp;nbsp;&lt;code&gt;LEFT&lt;/code&gt;&amp;nbsp;e&amp;nbsp;&lt;code&gt;RIGHT&lt;/code&gt;: retorna&amp;nbsp;&lt;strong&gt;todas as linhas dos dois lados&lt;/strong&gt;, com&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;onde não houver correspondência.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;FULL&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cliente_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| nome        | produto  | valor   |
|-------------|----------|---------|
| Ana Lima    | Notebook | 3500.00 |
| Ana Lima    | Mouse    |   80.00 |
| Bruno Melo  | Teclado  |  150.00 |
| Carla Nunes | NULL     | NULL    |
| Diego Costa | NULL     | NULL    |
| NULL        | Monitor  |  900.00 |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ninguém é descartado. Clientes sem pedidos aparecem, pedidos sem cliente aparecem. É útil para auditorias e para encontrar inconsistências nos dois lados de uma relação.&lt;/p&gt;

&lt;p&gt;Vale saber: o MySQL não suporta&amp;nbsp;&lt;code&gt;FULL OUTER JOIN&lt;/code&gt;&amp;nbsp;nativamente. O equivalente é unir um&amp;nbsp;&lt;code&gt;LEFT JOIN&lt;/code&gt;&amp;nbsp;com um&amp;nbsp;&lt;code&gt;RIGHT JOIN&lt;/code&gt;&amp;nbsp;usando&amp;nbsp;&lt;code&gt;UNION&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Self Join&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Um&amp;nbsp;&lt;strong&gt;Self Join&lt;/strong&gt;&amp;nbsp;é quando uma tabela é juntada com ela mesma. Não é um tipo de JOIN diferente — é uma aplicação de qualquer JOIN (geralmente&amp;nbsp;&lt;code&gt;INNER&lt;/code&gt;&amp;nbsp;ou&amp;nbsp;&lt;code&gt;LEFT&lt;/code&gt;) usando aliases para tratar a mesma tabela como se fossem duas.&lt;/p&gt;

&lt;p&gt;O caso de uso mais clássico: uma tabela de funcionários onde cada funcionário tem um&amp;nbsp;&lt;code&gt;gerente_id&lt;/code&gt;&amp;nbsp;que referencia outro funcionário na mesma tabela.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;funcionarios:
| id | nome       | gerente_id |
|----|------------|------------|
|  1 | Carlos     | NULL       |
|  2 | Ana        | 1          |
|  3 | Bruno      | 1          |
|  4 | Diego      | 2          |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;funcionario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;gerente&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;funcionarios&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;funcionarios&lt;/span&gt; &lt;span class="n"&gt;gON&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gerente_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| funcionario | gerente |
|-------------|---------|
| Carlos      | NULL    |
| Ana         | Carlos  |
| Bruno       | Carlos  |
| Diego       | Ana     |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O alias é obrigatório aqui:&amp;nbsp;&lt;code&gt;f&lt;/code&gt;&amp;nbsp;representa o funcionário e&amp;nbsp;&lt;code&gt;g&lt;/code&gt;&amp;nbsp;representa o gerente — ambos vindos da mesma tabela. Sem aliases, o banco não saberia a qual instância da tabela cada coluna pertence.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cross Join&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O&amp;nbsp;&lt;code&gt;CROSS JOIN&lt;/code&gt;&amp;nbsp;produz o&amp;nbsp;&lt;strong&gt;produto cartesiano&lt;/strong&gt;&amp;nbsp;das duas tabelas: cada linha de A é combinada com cada linha de B. Se A tem 4 linhas e B tem 3, o resultado tem 12 linhas. Não tem cláusula&amp;nbsp;&lt;code&gt;ON&lt;/code&gt;&amp;nbsp;— não há condição de correspondência.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso retornaria 4 × 4 = 16 combinações, incluindo Ana com Monitor e Diego com Notebook — independente de qualquer relação real entre eles.&lt;/p&gt;

&lt;p&gt;Na maioria dos casos, um&amp;nbsp;&lt;code&gt;CROSS JOIN&lt;/code&gt;&amp;nbsp;acidental em tabelas grandes é catastrófico para a performance. 1.000 linhas × 1.000 linhas = 1 milhão de resultados. Mas há casos de uso legítimos: gerar combinações para testes, preencher uma grade de horários, ou calcular todas as possibilidades de configuração de um produto.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Resumo Visual&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tabela A    Tabela B

INNER JOIN  → apenas a intersecção (correspondência nos dois lados)
LEFT JOIN   → tudo de A + correspondências de B
RIGHT JOIN  → tudo de B + correspondências de A
FULL OUTER  → tudo de A + tudo de B
CROSS JOIN  → todas as combinações possíveis
SELF JOIN   → a tabela junta com ela mesma
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;JOINs em cadeia&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Na prática, consultas reais combinam múltiplos JOINs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nomeAS&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;idAS&lt;/span&gt; &lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nomeAS&lt;/span&gt; &lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;precoAS&lt;/span&gt; &lt;span class="n"&gt;subtotal&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="n"&gt;pON&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cliente_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;itens_pedido&lt;/span&gt; &lt;span class="n"&gt;ipON&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pedido_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt; &lt;span class="n"&gt;prON&lt;/span&gt; &lt;span class="n"&gt;pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;produto_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada&amp;nbsp;&lt;code&gt;JOIN&lt;/code&gt;&amp;nbsp;adiciona uma tabela ao contexto da consulta. A ordem importa para legibilidade, mas não para o resultado — o otimizador do banco decide a ordem de execução internamente, independente da ordem em que os JOINs foram escritos.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Modelagem ER (Entidade Relacionamento)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Mon, 13 Jul 2026 00:53:48 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/modelagem-er-entidade-relacionamento-326</link>
      <guid>https://dev.to/yuripeixinho/modelagem-er-entidade-relacionamento-326</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Antes de criar uma única tabela, um banco de dados bem projetado começa no papel. A&amp;nbsp;&lt;strong&gt;Modelagem ER&lt;/strong&gt;&amp;nbsp;é a técnica usada para representar visualmente a estrutura de um domínio — quais coisas existem, quais atributos elas têm, e como se relacionam entre si. É a planta baixa do banco de dados.&lt;/p&gt;

&lt;p&gt;O modelo foi proposto por Peter Chen em 1976, num artigo que se tornaria um dos mais citados na história da computação. A ideia central era simples: representar o mundo real através de&amp;nbsp;&lt;strong&gt;entidades&lt;/strong&gt;,&amp;nbsp;&lt;strong&gt;atributos&lt;/strong&gt;&amp;nbsp;e&amp;nbsp;&lt;strong&gt;relacionamentos,&lt;/strong&gt;  e fazer isso de forma independente de qualquer banco de dados específico. O diagrama ER é uma linguagem de comunicação entre analistas, desenvolvedores e clientes, antes de qualquer linha de SQL ser escrita.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Entidades&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Uma&amp;nbsp;&lt;strong&gt;entidade&lt;/strong&gt;&amp;nbsp;é qualquer coisa do mundo real que tem existência independente e sobre a qual queremos armazenar informações. No diagrama, entidades são representadas por&amp;nbsp;&lt;strong&gt;retângulos&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Exemplos de entidades:&amp;nbsp;&lt;code&gt;Cliente&lt;/code&gt;,&amp;nbsp;&lt;code&gt;Produto&lt;/code&gt;,&amp;nbsp;&lt;code&gt;Pedido&lt;/code&gt;,&amp;nbsp;&lt;code&gt;Funcionário&lt;/code&gt;,&amp;nbsp;&lt;code&gt;Departamento&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Existe uma distinção importante entre:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tipo de entidade&lt;/strong&gt;: a definição abstrata — o conceito de "Cliente"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instância de entidade&lt;/strong&gt;: um cliente específico — "Ana Lima, CPF 123.456.789-00"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando o modelo é convertido para o banco, o tipo de entidade vira uma tabela e cada instância vira uma linha.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Entidade Forte vs Entidade Fraca&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Uma&amp;nbsp;&lt;strong&gt;entidade forte&lt;/strong&gt;&amp;nbsp;tem existência própria — pode ser identificada por seus próprios atributos, independente de qualquer outra entidade.&amp;nbsp;&lt;code&gt;Cliente&lt;/code&gt;&amp;nbsp;é uma entidade forte: existe um cliente mesmo sem nenhum pedido.&lt;/p&gt;

&lt;p&gt;Uma&amp;nbsp;&lt;strong&gt;entidade fraca&lt;/strong&gt;&amp;nbsp;depende de outra entidade para existir e ser identificada. No diagrama, é representada por um&amp;nbsp;&lt;strong&gt;retângulo duplo&lt;/strong&gt;. Um exemplo clássico:&amp;nbsp;&lt;code&gt;Item de Pedido&lt;/code&gt;&amp;nbsp;não existe sem um&amp;nbsp;&lt;code&gt;Pedido&lt;/code&gt;&amp;nbsp;— e seu identificador só faz sentido dentro do contexto daquele pedido (item 1 do pedido 10, item 1 do pedido 11 são coisas diferentes, mas têm o mesmo número).&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Atributos&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Atributos descrevem as propriedades de uma entidade. No diagrama, são representados por&amp;nbsp;&lt;strong&gt;elipses&lt;/strong&gt;&amp;nbsp;conectadas à entidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Atributo Simples&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Valor único e indivisível.&amp;nbsp;&lt;code&gt;nome&lt;/code&gt;,&amp;nbsp;&lt;code&gt;preco&lt;/code&gt;,&amp;nbsp;&lt;code&gt;data_nascimento&lt;/code&gt;. É o tipo mais comum.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Atributo Composto&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Pode ser subdividido em partes menores com significado próprio.&amp;nbsp;&lt;code&gt;endereco&lt;/code&gt;&amp;nbsp;pode ser decomposto em&amp;nbsp;&lt;code&gt;rua&lt;/code&gt;,&amp;nbsp;&lt;code&gt;numero&lt;/code&gt;,&amp;nbsp;&lt;code&gt;cidade&lt;/code&gt;,&amp;nbsp;&lt;code&gt;cep&lt;/code&gt;. No diagrama, o atributo composto tem sub-elipses conectadas a ele.&lt;/p&gt;

&lt;p&gt;Na conversão para tabelas, há uma escolha: manter como coluna única (&lt;code&gt;endereco VARCHAR&lt;/code&gt;) ou expandir em colunas separadas (&lt;code&gt;rua&lt;/code&gt;,&amp;nbsp;&lt;code&gt;numero&lt;/code&gt;,&amp;nbsp;&lt;code&gt;cidade&lt;/code&gt;). A decisão depende de se será necessário filtrar ou ordenar por partes do endereço.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Atributo Multivalorado&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Pode ter mais de um valor para a mesma entidade. Uma&amp;nbsp;&lt;code&gt;Pessoa&lt;/code&gt;&amp;nbsp;pode ter vários&amp;nbsp;&lt;code&gt;telefones&lt;/code&gt;. No diagrama, é representado por uma&amp;nbsp;&lt;strong&gt;elipse dupla&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Na conversão para tabelas, atributos multivalorados viram tabelas separadas — pois uma coluna não pode guardar múltiplos valores (violaria a 1FN).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;telefones&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;pessoa_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;pessoas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Atributo Derivado&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Calculado a partir de outro atributo — não é armazenado, é computado.&amp;nbsp;&lt;code&gt;idade&lt;/code&gt;&amp;nbsp;é derivado de&amp;nbsp;&lt;code&gt;data_nascimento&lt;/code&gt;. No diagrama, é representado por uma&amp;nbsp;&lt;strong&gt;elipse tracejada&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Em SQL, atributos derivados podem ser implementados como colunas calculadas ou simplesmente computados na consulta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;EXTRACT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;YEAR&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;AGE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_nascimento&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;idade&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pessoas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Atributo-Chave&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O atributo que identifica unicamente cada instância da entidade. No diagrama, é sublinhado. Corresponde à chave primária na tabela.&lt;/p&gt;

&lt;h1&gt;
  
  
  Relacionamentos
&lt;/h1&gt;

&lt;p&gt;Um&amp;nbsp;&lt;strong&gt;relacionamento&lt;/strong&gt;&amp;nbsp;representa uma associação entre duas ou mais entidades. No diagrama, é representado por um&amp;nbsp;&lt;strong&gt;losango&lt;/strong&gt;&amp;nbsp;conectado às entidades participantes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Cliente] ——— &amp;lt;faz&amp;gt; ——— [Pedido]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim como entidades, relacionamentos também podem ter atributos. Um relacionamento&amp;nbsp;&lt;code&gt;Matricula&lt;/code&gt;&amp;nbsp;entre&amp;nbsp;&lt;code&gt;Aluno&lt;/code&gt;&amp;nbsp;e&amp;nbsp;&lt;code&gt;Curso&lt;/code&gt;&amp;nbsp;pode ter o atributo&amp;nbsp;&lt;code&gt;data_matricula&lt;/code&gt;&amp;nbsp;e&amp;nbsp;&lt;code&gt;nota&lt;/code&gt;&amp;nbsp;— valores que pertencem à relação, não a nenhuma das entidades isoladamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Grau do Relacionamento&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O grau indica quantas entidades participam do relacionamento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Binário&lt;/strong&gt;&amp;nbsp;(grau 2): o mais comum. Dois tipos de entidade se relacionam.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Cliente] ——— &amp;lt;compra&amp;gt; ——— [Produto]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ternário&lt;/strong&gt;&amp;nbsp;(grau 3): três entidades participam simultaneamente. Um&amp;nbsp;&lt;code&gt;Médico&lt;/code&gt;&amp;nbsp;prescreve um&amp;nbsp;&lt;code&gt;Medicamento&lt;/code&gt;&amp;nbsp;para um&amp;nbsp;&lt;code&gt;Paciente&lt;/code&gt;&amp;nbsp;— e os três fazem parte do mesmo relacionamento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unário&lt;/strong&gt;&amp;nbsp;(grau 1 / auto-relacionamento): uma entidade se relaciona consigo mesma.&amp;nbsp;&lt;code&gt;Funcionário&lt;/code&gt;&amp;nbsp;pode ser gerenciado por outro&amp;nbsp;&lt;code&gt;Funcionário&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Funcionário] ——— &amp;lt;gerencia&amp;gt; ——— [Funcionário]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;strong&gt;Cardinalidade&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A cardinalidade define&amp;nbsp;&lt;strong&gt;quantas instâncias&lt;/strong&gt;&amp;nbsp;de uma entidade podem se associar a instâncias da outra. É a informação mais importante de um relacionamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1:1 — Um para Um&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cada instância de A se associa a no máximo uma instância de B, e vice-versa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;——&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;——&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;tem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;——&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;——&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Passaporte&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma pessoa tem um passaporte; um passaporte pertence a uma pessoa. Na conversão, a chave estrangeira pode ficar em qualquer um dos lados — por convenção, fica na entidade mais fraca ou mais dependente.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1:N — Um para Muitos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cada instância de A pode se associar a várias de B, mas cada instância de B se associa a apenas uma de A.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Cliente&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;——&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;——&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;faz&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;——&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="err"&gt;——&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Pedido&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um cliente faz vários pedidos; cada pedido pertence a um cliente. A chave estrangeira sempre fica no lado N —&amp;nbsp;&lt;code&gt;pedidos.cliente_id&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;N:N — Muitos para Muitos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cada instância de A pode se associar a várias de B, e vice-versa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Aluno&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;——&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="err"&gt;——&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;matricula&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;——&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="err"&gt;——&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Curso&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um aluno se matricula em vários cursos; um curso tem vários alunos. Na conversão, exige uma&amp;nbsp;&lt;strong&gt;tabela de junção&lt;/strong&gt;&amp;nbsp;— pois não há como representar isso com uma simples chave estrangeira.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;matriculas&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;aluno_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;alunos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;curso_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;cursos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;data_entrada&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;nota_final&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aluno_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curso_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Do Diagrama ER ao Esquema Relacional&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A conversão segue regras sistemáticas:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Elemento ER&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Resultado no banco&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Entidade forte&lt;/td&gt;
&lt;td&gt;Tabela&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atributo simples&lt;/td&gt;
&lt;td&gt;Coluna&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atributo composto&lt;/td&gt;
&lt;td&gt;Colunas para cada componente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atributo multivalorado&lt;/td&gt;
&lt;td&gt;Tabela separada com FK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atributo derivado&lt;/td&gt;
&lt;td&gt;Coluna calculada ou consulta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relacionamento 1:1&lt;/td&gt;
&lt;td&gt;FK em um dos lados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relacionamento 1:N&lt;/td&gt;
&lt;td&gt;FK no lado N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relacionamento N:N&lt;/td&gt;
&lt;td&gt;Tabela de junção&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entidade fraca&lt;/td&gt;
&lt;td&gt;Tabela com chave composta (PK parcial + FK da forte)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Especialização&lt;/td&gt;
&lt;td&gt;Tabela única, por subtipo, ou apenas subtipos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>architecture</category>
      <category>beginners</category>
      <category>computerscience</category>
      <category>database</category>
    </item>
    <item>
      <title>SQL: Data Constraints</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Mon, 13 Jul 2026 00:13:41 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/sql-data-constraints-4gdh</link>
      <guid>https://dev.to/yuripeixinho/sql-data-constraints-4gdh</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Validar dados é uma responsabilidade que pode ficar na aplicação, no banco de dados, ou em ambos. Deixar tudo na aplicação é arriscado: diferentes sistemas podem acessar o mesmo banco, migrações podem rodar diretamente, um bug pode deixar passar um valor inválido.&amp;nbsp;&lt;strong&gt;Constraints&lt;/strong&gt;&amp;nbsp;são regras definidas no próprio banco de dados — uma camada de proteção que age independente de quem está escrevendo os dados.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;PRIMARY KEY&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A chave primária identifica cada linha de forma única. Ela combina duas restrições implicitamente:&amp;nbsp;&lt;code&gt;NOT NULL&lt;/code&gt;&amp;nbsp;e&amp;nbsp;&lt;code&gt;UNIQUE&lt;/code&gt;. Nenhuma linha pode ter o mesmo valor de chave primária, e nenhuma pode tê-la nula.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando a chave primária envolve mais de uma coluna, ela é declarada separadamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;matriculas&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;aluno_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;curso_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aluno_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curso_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na maioria dos bancos, é comum usar uma chave primária auto-incremental para não precisar gerenciar os IDs manualmente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- PostgreSQL&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;

&lt;span class="c1"&gt;-- MySQL&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENTPRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;

&lt;span class="c1"&gt;-- SQL padrão (suportado por ambos)&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;GENERATED&lt;/span&gt; &lt;span class="n"&gt;ALWAYS&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;IDENTITY&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;FOREIGN KEY&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A chave estrangeira garante&amp;nbsp;&lt;strong&gt;integridade referencial&lt;/strong&gt;: um valor só pode existir numa coluna se ele existir como chave primária na tabela referenciada. É o que torna os relacionamentos entre tabelas confiáveis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;cliente_idINT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tentar inserir um pedido com&amp;nbsp;&lt;code&gt;cliente_id = 99&lt;/code&gt;&amp;nbsp;quando não existe cliente com esse id resulta em erro imediato. O banco rejeita a operação antes mesmo de ela chegar ao disco.&lt;/p&gt;

&lt;p&gt;O comportamento quando o registro referenciado é deletado pode ser configurado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;cliente_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;    &lt;span class="c1"&gt;-- deleta os pedidos junto com o cliente&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;    &lt;span class="c1"&gt;-- atualiza o cliente_id se o id do cliente mudar&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As opções disponíveis são:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Opção&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Comportamento&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RESTRICT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rejeita a operação se houver dependentes (padrão)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CASCADE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Propaga a operação para os dependentes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SET NULL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Define a FK como nula nos dependentes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SET DEFAULT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Define a FK com o valor padrão da coluna&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;UNIQUE&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Garante que todos os valores de uma coluna — ou combinação de colunas — sejam distintos. Diferente da chave primária, uma coluna&amp;nbsp;&lt;code&gt;UNIQUE&lt;/code&gt;&amp;nbsp;pode conter&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;(e em geral múltiplos&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;são permitidos, pois&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;não é igual a nada, nem a si mesmo).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;usuarios&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;UNIQUE&lt;/code&gt;&amp;nbsp;composto funciona da mesma forma que&amp;nbsp;&lt;code&gt;PRIMARY KEY&lt;/code&gt;&amp;nbsp;composto — a restrição se aplica à combinação, não às colunas individualmente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- O mesmo aluno pode ter notas em vários cursos,&lt;/span&gt;
&lt;span class="c1"&gt;-- mas não duas notas no mesmo curso&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;notas&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;aluno_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;curso_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;notaDECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aluno_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curso_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;NOT NULL&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Impede que uma coluna aceite ausência de valor. Simples e direto — mas uma das constraints mais importantes na prática, porque&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;se propaga de formas inesperadas em cálculos e comparações.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;nomeVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;precoDECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;descricao&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;          &lt;span class="c1"&gt;-- aceita NULL: campo opcional&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma coluna sem&amp;nbsp;&lt;code&gt;NOT NULL&lt;/code&gt;&amp;nbsp;aceita&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;por padrão. Definir quais campos são obrigatórios e quais são opcionais é uma decisão de modelagem — e&amp;nbsp;&lt;code&gt;NOT NULL&lt;/code&gt;&amp;nbsp;é a forma de documentar e enforçar isso no próprio esquema.&lt;/p&gt;

&lt;p&gt;Vale lembrar:&amp;nbsp;&lt;code&gt;AVG&lt;/code&gt;,&amp;nbsp;&lt;code&gt;SUM&lt;/code&gt;&amp;nbsp;e outras funções de agregação ignoram&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;automaticamente. E comparações com&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;usando&amp;nbsp;&lt;code&gt;=&lt;/code&gt;&amp;nbsp;sempre retornam falso —&amp;nbsp;&lt;code&gt;NULL = NULL&lt;/code&gt;&amp;nbsp;é falso em SQL; a verificação correta é&amp;nbsp;&lt;code&gt;IS NULL&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;CHECK&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Permite definir uma condição arbitrária que os valores de uma coluna precisam satisfazer. É a constraint mais flexível — qualquer expressão booleana válida pode ser usada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;preco&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;estoque&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;           &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;estoque&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;avaliacao&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avaliacaoBETWEEN&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tentar inserir um produto com&amp;nbsp;&lt;code&gt;preco = -50&lt;/code&gt;&amp;nbsp;vai gerar um erro de violação de constraint antes de qualquer dado ser gravado.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CHECK&lt;/code&gt;&amp;nbsp;também pode referenciar múltiplas colunas da mesma linha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;descontos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;preco_original&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;preco_final&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preco_final&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;preco_original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso garante que nenhum desconto resulte em preço final maior que o original — uma regra de negócio simples que, sem&amp;nbsp;&lt;code&gt;CHECK&lt;/code&gt;, dependeria inteiramente da aplicação para ser respeitada.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adicionando Constraints depois&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Constraints podem ser adicionadas a tabelas existentes com&amp;nbsp;&lt;code&gt;ALTER TABLE&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt;
  &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;chk_preco&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;
  &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;fk_cliente&lt;/span&gt;
  &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cliente_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E removidas quando necessário:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;chk_preco&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Por que usar Constraints&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A alternativa às constraints é validar tudo na aplicação. O problema é que a aplicação não é a única forma de os dados chegarem ao banco — migrações, scripts de manutenção, ferramentas de BI, outros serviços. Constraints garantem que&amp;nbsp;&lt;strong&gt;independente da origem&lt;/strong&gt;, os dados respeitem as regras. É a diferença entre confiar que ninguém vai errar e tornar o erro impossível.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>SQL: Aggregate Queries</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Mon, 13 Jul 2026 00:07:59 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/sql-aggregate-queries-59h9</link>
      <guid>https://dev.to/yuripeixinho/sql-aggregate-queries-59h9</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Consultas individuais respondem perguntas como "qual o email do cliente 42?". Mas as perguntas mais valiosas em qualquer sistema são de outro tipo: "qual o produto mais vendido?", "qual a receita média por pedido?", "quantos clientes se cadastraram esse mês?". Para responder isso, o SQL oferece as&amp;nbsp;&lt;strong&gt;funções de agregação&lt;/strong&gt;&amp;nbsp;— operações que recebem um conjunto de linhas e devolvem um único valor resumido.&lt;/p&gt;

&lt;p&gt;Para os exemplos a seguir, considere esta tabela:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pedidos:
| id | cliente    | produto     | categoria    | quantidade | valor  |
|----|------------|-------------|--------------|------------|--------|
|  1 | Ana Lima   | Notebook    | Eletrônicos  | 1          | 3500.00|
|  2 | Ana Lima   | Mouse       | Periféricos  | 2          |   80.00|
|  3 | Bruno Melo | Teclado     | Periféricos  | 1          |  150.00|
|  4 | Bruno Melo | Notebook    | Eletrônicos  | 1          | 3500.00|
|  5 | Carla Nunes| Monitor     | Eletrônicos  | 2          | 1200.00|
|  6 | Carla Nunes| Mouse       | Periféricos  | 1          |   80.00|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;strong&gt;As Funções de Agregação&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;COUNT&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Conta o número de linhas — ou de valores não nulos em uma coluna específica.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Total de pedidos&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_pedidosFROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Resultado: 6&lt;/span&gt;

&lt;span class="c1"&gt;-- Clientes distintos que fizeram pedidos&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;clientes_unicosFROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Resultado: 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;COUNT(*)&lt;/code&gt;&amp;nbsp;conta todas as linhas, incluindo as que têm nulos.&amp;nbsp;&lt;code&gt;COUNT(coluna)&lt;/code&gt;&amp;nbsp;conta apenas as linhas onde aquela coluna não é nula.&amp;nbsp;&lt;code&gt;COUNT(DISTINCT coluna)&lt;/code&gt;&amp;nbsp;conta valores únicos — útil para saber quantos clientes, produtos ou categorias distintos aparecem no resultado.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;SUM&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Soma os valores de uma coluna numérica.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Receita total&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;receita_total&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Resultado: 8510.00&lt;/span&gt;

&lt;span class="c1"&gt;-- Total de itens vendidos&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;itens_vendidos&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Resultado: 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;AVG&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Calcula a média aritmética dos valores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Valor médio por pedido&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;ticket_medio&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Resultado: 1418.33&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;AVG&lt;/code&gt;&amp;nbsp;ignora valores nulos automaticamente — calcula a média apenas sobre os registros que têm valor preenchido naquela coluna.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;MIN e MAX&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Retornam o menor e o maior valor de uma coluna, respectivamente. Funcionam com números, datas e texto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;pedido_minimo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;pedido_maximo&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Resultado: 80.00 | 3500.00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com datas,&amp;nbsp;&lt;code&gt;MIN&lt;/code&gt;&amp;nbsp;retorna a data mais antiga e&amp;nbsp;&lt;code&gt;MAX&lt;/code&gt;&amp;nbsp;a mais recente — útil para saber o primeiro e o último evento de um conjunto.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;GROUP BY&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Funções de agregação sem&amp;nbsp;&lt;code&gt;GROUP BY&lt;/code&gt;&amp;nbsp;resumem a tabela inteira em uma linha. Com&amp;nbsp;&lt;code&gt;GROUP BY&lt;/code&gt;, elas resumem&amp;nbsp;&lt;strong&gt;por grupo&lt;/strong&gt;&amp;nbsp;— calculando um resultado para cada valor distinto da coluna agrupada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Receita total por categoria&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;categoria&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;receita&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;categoria&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;categoria&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;receita&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="c1"&gt;-------------|---------|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Eletr&lt;/span&gt;&lt;span class="err"&gt;ô&lt;/span&gt;&lt;span class="n"&gt;nicos&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;8200&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Perif&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="n"&gt;ricos&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;310&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É possível agrupar por múltiplas colunas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Receita por cliente e categoria&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;categoria&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;receita&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;categoria&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receitaDESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| cliente     | categoria   | receita | pedidos |
|-------------|-------------|---------|---------|
| Ana Lima    | Eletrônicos | 3500.00 | 1       |
| Ana Lima    | Periféricos |  160.00 | 1       |
| Bruno Melo  | Eletrônicos | 3500.00 | 1       |
| Bruno Melo  | Periféricos |  150.00 | 1       |
| Carla Nunes | Eletrônicos | 2400.00 | 1       |
| Carla Nunes | Periféricos |   80.00 | 1       |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma regra importante:&amp;nbsp;&lt;strong&gt;toda coluna no&amp;nbsp;&lt;code&gt;SELECT&lt;/code&gt;&amp;nbsp;que não é uma função de agregação precisa estar no&amp;nbsp;&lt;code&gt;GROUP BY&lt;/code&gt;&lt;/strong&gt;. O banco precisa saber como agrupar — se você seleciona&amp;nbsp;&lt;code&gt;cliente&lt;/code&gt;&amp;nbsp;e&amp;nbsp;&lt;code&gt;categoria&lt;/code&gt;&amp;nbsp;mas agrega por apenas um, ele não sabe qual valor exibir para o outro.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;HAVING&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;WHERE&lt;/code&gt;&amp;nbsp;filtra linhas&amp;nbsp;&lt;strong&gt;antes&lt;/strong&gt;&amp;nbsp;da agregação.&amp;nbsp;&lt;code&gt;HAVING&lt;/code&gt;&amp;nbsp;filtra grupos&amp;nbsp;&lt;strong&gt;depois&lt;/strong&gt;&amp;nbsp;da agregação. São complementares, não concorrentes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Apenas clientes com receita total acima de 1000&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;receita_total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;receita_total&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="c1"&gt;-------------|---------------|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Ana&lt;/span&gt; &lt;span class="n"&gt;Lima&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3580&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Bruno&lt;/span&gt; &lt;span class="n"&gt;Melo&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3650&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Carla&lt;/span&gt; &lt;span class="n"&gt;Nunes&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2480&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A diferença entre&amp;nbsp;&lt;code&gt;WHERE&lt;/code&gt;&amp;nbsp;e&amp;nbsp;&lt;code&gt;HAVING&lt;/code&gt;&amp;nbsp;fica clara quando os dois aparecem juntos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Receita por cliente, considerando apenas pedidos de Eletrônicos,&lt;/span&gt;
&lt;span class="c1"&gt;-- e mostrando apenas quem passou de 2000&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;receita&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;categoria&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Eletrônicos'&lt;/span&gt;   &lt;span class="c1"&gt;-- filtra linhas antes de agrupar&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;cliente&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="c1"&gt;-- filtra grupos depois de agregar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| cliente     | receita |
|-------------|---------|
| Ana Lima    | 3500.00 |
| Bruno Melo  | 3500.00 |
| Carla Nunes | 2400.00 |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Carla passou porque seus R$ 2.400 em Eletrônicos superam o limite de R$ 2.000. Se o limite fosse R$ 3.000, apenas Ana e Bruno apareceriam.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A Ordem de Execução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Entender a ordem em que o SQL processa as cláusulas explica por que&amp;nbsp;&lt;code&gt;HAVING&lt;/code&gt;&amp;nbsp;existe como cláusula separada do&amp;nbsp;&lt;code&gt;WHERE&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. FROM       → identifica a tabela
2. WHERE      → filtra as linhas brutas
3. GROUP BY   → agrupa as linhas restantes
4. HAVING     → filtra os grupos formados
5. SELECT     → calcula as expressões e funções
6. ORDER BY   → ordena o resultado final
7. LIMIT      → recorta a quantidade retornada
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;WHERE&lt;/code&gt;&amp;nbsp;atua antes da agregação existir — por isso não é possível usar uma função de agregação dentro do&amp;nbsp;&lt;code&gt;WHERE&lt;/code&gt;. Tentar&amp;nbsp;&lt;code&gt;WHERE SUM(valor) &amp;gt; 1000&lt;/code&gt;&amp;nbsp;resulta em erro. Para filtrar por resultado de agregação, o lugar certo é sempre o&amp;nbsp;&lt;code&gt;HAVING&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>SQL: Normalização e Formas Normais</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 12 Jul 2026 23:15:52 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/sql-normalizacao-e-formas-normais-3e5j</link>
      <guid>https://dev.to/yuripeixinho/sql-normalizacao-e-formas-normais-3e5j</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Imagine uma planilha onde cada linha de um pedido guarda também o nome do cliente, o email, a cidade, o nome do produto e a categoria — tudo junto. Funciona no começo. Mas conforme o sistema cresce, começam a aparecer problemas silenciosos: dados duplicados, inconsistências difíceis de rastrear, operações que quebram coisas inesperadas. A normalização existe para eliminar esses problemas sistematicamente.&lt;/p&gt;

&lt;p&gt;Proposta por Codd nos anos 1970 e formalizada ao longo das décadas seguintes, a normalização é um processo de reorganização do esquema em&amp;nbsp;&lt;strong&gt;formas normais&lt;/strong&gt;&amp;nbsp;progressivas — cada uma corrigindo uma classe específica de problema.&lt;/p&gt;

&lt;h1&gt;
  
  
  O problema: Anomalias
&lt;/h1&gt;

&lt;p&gt;Antes de ver as soluções, vale entender o que está sendo resolvido. Um esquema mal estruturado produz três tipos de anomalia.&lt;/p&gt;

&lt;p&gt;Considere esta tabela que mistura informações de pedidos, clientes e produtos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;| pedido_id | cliente    | cliente_cidade | produto     | categoria    | qtd | preco   |
|-----------|------------|----------------|-------------|--------------|-----|---------|
| 1         | Ana Lima   | São Paulo      | Notebook    | Eletrônicos  | 1   | 3500.00 |
| 1         | Ana Lima   | São Paulo      | Mouse       | Periféricos  | 2   |   80.00 |
| 2         | Bruno Melo | Curitiba       | Notebook    | Eletrônicos  | 1   | 3500.00 |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Anomalia de atualização&lt;/strong&gt;: se Ana Lima mudar de cidade, é preciso atualizar todas as linhas onde ela aparece. Esquecer uma cria inconsistência — o mesmo cliente com duas cidades diferentes no banco.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anomalia de inserção&lt;/strong&gt;: não é possível cadastrar um produto sem vinculá-lo a um pedido. O produto não existe de forma independente nesse esquema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anomalia de exclusão&lt;/strong&gt;: se o pedido 2 for deletado, os dados do Notebook somem junto — mesmo que o produto exista em outros contextos.&lt;/p&gt;

&lt;p&gt;Esses são os sintomas de um esquema não normalizado. As formas normais são o tratamento.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Primeira Forma Normal — 1FN&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Regra&lt;/strong&gt;: cada coluna deve conter um valor&amp;nbsp;&lt;strong&gt;atômico&lt;/strong&gt;&amp;nbsp;— indivisível. Não pode haver listas, conjuntos ou grupos repetidos dentro de uma célula.&lt;/p&gt;

&lt;p&gt;Um exemplo que viola 1FN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;| pedido_id | cliente  | produtos                    |
|-----------|----------|-----------------------------|
| 1         | Ana Lima | Notebook, Mouse, Teclado    |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A coluna&amp;nbsp;&lt;code&gt;produtos&lt;/code&gt;&amp;nbsp;guarda múltiplos valores numa célula só. Isso parece conveniente, mas impossibilita filtrar pedidos que contenham um produto específico sem recorrer a gambiarras com&amp;nbsp;&lt;code&gt;LIKE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A correção é expandir cada valor em sua própria linha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;| pedido_id | cliente  | produto  |
|-----------|----------|----------|
| 1         | Ana Lima | Notebook |
| 1         | Ana Lima | Mouse    |
| 1         | Ana Lima | Teclado  |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Além de valores atômicos, 1FN exige que cada linha seja única — o que leva naturalmente à definição de uma chave primária.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Segunda Forma Normal — 2FN&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Regra&lt;/strong&gt;: estar em 1FN e não ter&amp;nbsp;&lt;strong&gt;dependências parciais&lt;/strong&gt;&amp;nbsp;— todo atributo não-chave deve depender da chave primária&amp;nbsp;&lt;strong&gt;inteira&lt;/strong&gt;, não de apenas parte dela.&lt;/p&gt;

&lt;p&gt;Essa forma só é relevante quando a chave primária é composta. Considere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;| pedido_id | produto_id | produto_nome | cliente    | quantidade |
|-----------|------------|--------------|------------|------------|
| 1         | 10         | Notebook     | Ana Lima   | 1          |
| 1         | 11         | Mouse        | Ana Lima   | 2          |
| 2         | 10         | Notebook     | Bruno Melo | 1          |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A chave primária é&amp;nbsp;&lt;code&gt;(pedido_id, produto_id)&lt;/code&gt;. Mas&amp;nbsp;&lt;code&gt;produto_nome&lt;/code&gt;&amp;nbsp;depende apenas de&amp;nbsp;&lt;code&gt;produto_id&lt;/code&gt;&amp;nbsp;— não precisa do&amp;nbsp;&lt;code&gt;pedido_id&lt;/code&gt;&amp;nbsp;para ser determinado. E&amp;nbsp;&lt;code&gt;cliente&lt;/code&gt;&amp;nbsp;depende apenas de&amp;nbsp;&lt;code&gt;pedido_id&lt;/code&gt;. Essas são dependências parciais.&lt;/p&gt;

&lt;p&gt;A solução é separar em tabelas distintas, onde cada atributo depende da chave inteira da sua tabela:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Cada tabela tem sua própria identidade&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;idINT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;nomeVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;idINT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;cliente_idINT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;itens_pedido&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;pedido_idINT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;produto_idINT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;quantidadeINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;produto_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora&amp;nbsp;&lt;code&gt;produto_nome&lt;/code&gt;&amp;nbsp;vive em&amp;nbsp;&lt;code&gt;produtos&lt;/code&gt;,&amp;nbsp;&lt;code&gt;cliente&lt;/code&gt;&amp;nbsp;vive em&amp;nbsp;&lt;code&gt;pedidos&lt;/code&gt;, e&amp;nbsp;&lt;code&gt;itens_pedido&lt;/code&gt;&amp;nbsp;guarda apenas o que é realmente da relação entre pedido e produto.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Terceira Forma Normal — 3FN&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Regra&lt;/strong&gt;: estar em 2FN e não ter&amp;nbsp;&lt;strong&gt;dependências transitivas&lt;/strong&gt;&amp;nbsp;— nenhum atributo não-chave pode depender de outro atributo não-chave.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;produto_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;categoria_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;categoria_nome&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="c1"&gt;------------|----------|--------------|----------------|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Notebook&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Eletr&lt;/span&gt;&lt;span class="err"&gt;ô&lt;/span&gt;&lt;span class="n"&gt;nicos&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Mouse&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Perif&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="n"&gt;ricos&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui,&amp;nbsp;&lt;code&gt;categoria_nome&lt;/code&gt;&amp;nbsp;não depende de&amp;nbsp;&lt;code&gt;produto_id&lt;/code&gt;&amp;nbsp;diretamente — depende de&amp;nbsp;&lt;code&gt;categoria_id&lt;/code&gt;, que por sua vez depende de&amp;nbsp;&lt;code&gt;produto_id&lt;/code&gt;. Isso é uma dependência transitiva:&amp;nbsp;&lt;code&gt;produto_id → categoria_id → categoria_nome&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O problema: se o nome da categoria "Eletrônicos" precisar mudar, será necessário atualizar todos os produtos dessa categoria. E se não houver nenhum produto numa categoria, ela não pode ser armazenada.&lt;/p&gt;

&lt;p&gt;A solução, novamente, é separar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;categorias&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;idINT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;nomeVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;idINT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;nomeVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;categoria_idINT&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;categorias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora&amp;nbsp;&lt;code&gt;categoria_nome&lt;/code&gt;&amp;nbsp;vive onde pertence, e os produtos referenciam a categoria por chave estrangeira.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Forma Normal de Boyce-Codd — BCNF&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A BCNF é uma versão mais rigorosa da 3FN, proposta em 1974 por Raymond Boyce e o próprio Codd. A diferença é sutil mas importante: na 3FN, há exceções para dependências envolvendo chaves candidatas. A BCNF elimina essas exceções.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regra&lt;/strong&gt;: para cada dependência funcional&amp;nbsp;&lt;code&gt;X → Y&lt;/code&gt;, X deve ser uma chave candidata.&lt;/p&gt;

&lt;p&gt;Na prática, a maioria dos esquemas bem projetados que atingem 3FN já satisfaz a BCNF. Os casos que violam BCNF mas não 3FN são relativamente raros — envolvem tabelas com múltiplas chaves candidatas sobrepostas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4FN e 5FN&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Existem formas normais além da BCNF, que tratam de casos ainda mais específicos. A&amp;nbsp;&lt;strong&gt;4FN&lt;/strong&gt;&amp;nbsp;lida com dependências multivaloradas — quando um atributo determina múltiplos valores independentes de outro atributo. A&amp;nbsp;&lt;strong&gt;5FN&lt;/strong&gt;&amp;nbsp;trata de dependências de junção. Na prática do desenvolvimento cotidiano, chegar à 3FN ou BCNF já resolve a grande maioria dos problemas. A 4FN e 5FN aparecem em modelagens muito específicas ou acadêmicas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Desnormalização&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Normalizar é bom, mas normalizar demais pode ser um problema de desempenho. Uma consulta que precisa juntar seis tabelas para montar um relatório vai ser mais lenta do que uma que lê uma tabela única já consolidada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desnormalização&lt;/strong&gt;&amp;nbsp;é a decisão deliberada de violar uma forma normal em prol de desempenho. É comum em sistemas de analytics e data warehouses, onde leituras são muito mais frequentes que escritas, e a redundância de dados é um custo aceitável em troca de consultas mais rápidas.&lt;/p&gt;

&lt;p&gt;A diferença entre um banco mal projetado e um banco desnormalizado intencionalmente é exatamente essa:&amp;nbsp;&lt;strong&gt;consciência&lt;/strong&gt;. Desnormalizar sem entender as formas normais é acidente. Desnormalizar conhecendo os trade-offs é arquitetura.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>computerscience</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Data Manipulation Language (DML)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 12 Jul 2026 23:15:17 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/data-manipulation-language-dml-2eh6</link>
      <guid>https://dev.to/yuripeixinho/data-manipulation-language-dml-2eh6</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;DML é o conjunto de comandos que os usuários e aplicações usam no dia a dia:&amp;nbsp;&lt;strong&gt;consultar, inserir, atualizar e deletar dados&lt;/strong&gt;. Se o DDL define o esquema, o DML é o que acontece dentro dele ao longo de toda a vida do sistema.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;SELECT&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O comando mais usado em SQL. Consulta dados de uma ou mais tabelas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;criado_em&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2024-01-01'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;nomeASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O&amp;nbsp;&lt;code&gt;SELECT&lt;/code&gt;&amp;nbsp;é composto por cláusulas que se encaixam numa ordem lógica:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Cláusula&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Função&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FROM&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Define de onde os dados vêm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WHERE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filtra as linhas antes de agrupar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Combina dados de outras tabelas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GROUP BY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Agrupa linhas por um critério&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HAVING&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filtra grupos (depois do&amp;nbsp;&lt;code&gt;GROUP BY&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ORDER BY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ordena o resultado final&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Um exemplo com mais cláusulas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_pedidos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;valor_total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt; &lt;span class="n"&gt;pON&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cliente_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;criado_em&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2024-01-01'&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;valor_totalDESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este SELECT retorna clientes que, desde 2024, acumularam mais de R$ 1.000 em pedidos — ordenados do maior para o menor.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;INSERT&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Adiciona novos registros a uma tabela.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Inserindo um registro&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Ana Lima'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'ana@email.com'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Inserindo vários de uma vez&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Bruno Melo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'bruno@email.com'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Carla Nunes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'carla@email.com'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;UPDATE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Altera registros já existentes.&amp;nbsp;&lt;strong&gt;Sempre use&amp;nbsp;&lt;code&gt;WHERE&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;— sem ele, o UPDATE afeta todas as linhas da tabela.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ana.lima@email.com'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;DELETE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Remove registros. Assim como o&amp;nbsp;&lt;code&gt;UPDATE&lt;/code&gt;, exige atenção ao&amp;nbsp;&lt;code&gt;WHERE&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Diferente do&amp;nbsp;&lt;code&gt;TRUNCATE&lt;/code&gt;, o&amp;nbsp;&lt;code&gt;DELETE&lt;/code&gt;&amp;nbsp;processa linha por linha, dispara triggers e pode ser revertido dentro de uma transação — o que o torna mais seguro, mas mais lento em volumes grandes.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Data Definition Language (DDL)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 12 Jul 2026 23:15:02 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/data-definition-language-ddl-o5g</link>
      <guid>https://dev.to/yuripeixinho/data-definition-language-ddl-o5g</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;DDL é o conjunto de comandos responsável por&amp;nbsp;&lt;strong&gt;definir e modificar a estrutura&lt;/strong&gt;&amp;nbsp;do banco de dados: criar tabelas, alterar colunas, remover objetos. Operações DDL geralmente são irreversíveis — um&amp;nbsp;&lt;code&gt;DROP TABLE&lt;/code&gt;&amp;nbsp;não pede confirmação, ele simplesmente executa.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;CREATE TABLE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cria uma nova tabela com suas colunas, tipos de dados e restrições.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;nomeVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;emailVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;criado_em&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_DATE&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo,&amp;nbsp;&lt;code&gt;id&lt;/code&gt;&amp;nbsp;é a chave primária,&amp;nbsp;&lt;code&gt;nome&lt;/code&gt;&amp;nbsp;não pode ser nulo,&amp;nbsp;&lt;code&gt;email&lt;/code&gt;&amp;nbsp;deve ser único em toda a tabela, e&amp;nbsp;&lt;code&gt;criado_em&lt;/code&gt;&amp;nbsp;recebe a data atual automaticamente se nenhum valor for informado.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;ALTER TABLE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Modifica uma tabela já existente — adiciona colunas, remove, renomeia, ou altera tipos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Adicionando uma coluna nova&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;telefoneVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Removendo uma coluna&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;telefone&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Renomeando uma coluna&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;nomeTO&lt;/span&gt; &lt;span class="n"&gt;nome_completo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ALTER TABLE&lt;/code&gt;&amp;nbsp;é o comando mais usado em migrações de banco de dados — toda vez que o sistema evolui e o esquema precisa acompanhar.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;DROP TABLE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Remove uma tabela completamente, junto com todos os seus dados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sem volta. Por isso, em ambientes de produção, é comum exigir backups antes de executar qualquer&amp;nbsp;&lt;code&gt;DROP&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;TRUNCATE TABLE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Remove&amp;nbsp;&lt;strong&gt;todos os registros&lt;/strong&gt;&amp;nbsp;de uma tabela, mas preserva a estrutura dela.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;TRUNCATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A diferença para um&amp;nbsp;&lt;code&gt;DELETE&lt;/code&gt;&amp;nbsp;sem cláusula&amp;nbsp;&lt;code&gt;WHERE&lt;/code&gt;&amp;nbsp;é de desempenho: o&amp;nbsp;&lt;code&gt;TRUNCATE&lt;/code&gt;&amp;nbsp;não processa linha por linha, ele simplesmente descarta o conteúdo inteiro de uma vez, sendo muito mais rápido em tabelas grandes. Em contrapartida, não dispara triggers e em vários bancos não pode ser revertido.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>SQL Keyword, Tipos de Dados &amp; Operators</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 12 Jul 2026 22:24:38 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/sql-keyword-tipos-de-dados-operators-2a1c</link>
      <guid>https://dev.to/yuripeixinho/sql-keyword-tipos-de-dados-operators-2a1c</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Keywords são as palavras reservadas da linguagem, termos com significado especial que o banco de dados reconhece e interpreta. Elas formam a espinha dorsal de qualquer instrução SQL.&lt;/p&gt;

&lt;p&gt;Por convenção, keywords são escritas em&amp;nbsp;&lt;strong&gt;maiúsculas&lt;/strong&gt;, embora o SQL seja case-insensitive.&amp;nbsp;&lt;code&gt;select&lt;/code&gt;&amp;nbsp;funciona igual a&amp;nbsp;&lt;code&gt;SELECT&lt;/code&gt;, mas o uso de maiúsculas é uma convenção amplamente adotada que melhora a legibilidade, deixando claro o que é comando e o que é nome de tabela ou coluna.&lt;/p&gt;

&lt;p&gt;As principais keywords se organizam por função:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Categoria&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Keywords&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Consulta&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;SELECT&lt;/code&gt;,&amp;nbsp;&lt;code&gt;FROM&lt;/code&gt;,&amp;nbsp;&lt;code&gt;WHERE&lt;/code&gt;,&amp;nbsp;&lt;code&gt;ORDER BY&lt;/code&gt;,&amp;nbsp;&lt;code&gt;GROUP BY&lt;/code&gt;,&amp;nbsp;&lt;code&gt;HAVING&lt;/code&gt;,&amp;nbsp;&lt;code&gt;LIMIT&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Junção&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;JOIN&lt;/code&gt;,&amp;nbsp;&lt;code&gt;INNER JOIN&lt;/code&gt;,&amp;nbsp;&lt;code&gt;LEFT JOIN&lt;/code&gt;,&amp;nbsp;&lt;code&gt;ON&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manipulação&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;INSERT&lt;/code&gt;,&amp;nbsp;&lt;code&gt;UPDATE&lt;/code&gt;,&amp;nbsp;&lt;code&gt;DELETE&lt;/code&gt;,&amp;nbsp;&lt;code&gt;INTO&lt;/code&gt;,&amp;nbsp;&lt;code&gt;VALUES&lt;/code&gt;,&amp;nbsp;&lt;code&gt;SET&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estrutura&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CREATE&lt;/code&gt;,&amp;nbsp;&lt;code&gt;ALTER&lt;/code&gt;,&amp;nbsp;&lt;code&gt;DROP&lt;/code&gt;,&amp;nbsp;&lt;code&gt;TABLE&lt;/code&gt;,&amp;nbsp;&lt;code&gt;INDEX&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auxiliares&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;AS&lt;/code&gt;,&amp;nbsp;&lt;code&gt;DISTINCT&lt;/code&gt;,&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;,&amp;nbsp;&lt;code&gt;NOT NULL&lt;/code&gt;,&amp;nbsp;&lt;code&gt;DEFAULT&lt;/code&gt;,&amp;nbsp;&lt;code&gt;AND&lt;/code&gt;,&amp;nbsp;&lt;code&gt;OR&lt;/code&gt;,&amp;nbsp;&lt;code&gt;IN&lt;/code&gt;,&amp;nbsp;&lt;code&gt;LIKE&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Nomes de tabelas e colunas&amp;nbsp;&lt;strong&gt;não podem ser keywords reservadas,&lt;/strong&gt; ou, se forem, precisam ser envolvidos em aspas ou colchetes dependendo do banco. Chamar uma coluna de&amp;nbsp;&lt;code&gt;order&lt;/code&gt;&amp;nbsp;ou&amp;nbsp;&lt;code&gt;select&lt;/code&gt;, por exemplo, vai causar um erro de sintaxe.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tipos de Dados
&lt;/h1&gt;

&lt;p&gt;Ao criar uma tabela, cada coluna precisa de um tipo de dado. Esse tipo define o que pode ser armazenado ali, e o banco de dados garante que nenhum valor inválido seja inserido. É a primeira camada de validação dos dados.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Numéricos&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;           &lt;span class="c1"&gt;-- inteiro, de -2 bilhões a 2 bilhões&lt;/span&gt;
&lt;span class="n"&gt;populacao&lt;/span&gt; &lt;span class="nb"&gt;BIGINT&lt;/span&gt;        &lt;span class="c1"&gt;-- inteiro grande, para números acima de 2 bilhões&lt;/span&gt;
&lt;span class="n"&gt;preco&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- número exato com 10 dígitos, 2 decimais (ideal para dinheiro)&lt;/span&gt;
&lt;span class="n"&gt;peso&lt;/span&gt; &lt;span class="nb"&gt;FLOAT&lt;/span&gt;         &lt;span class="c1"&gt;-- número de ponto flutuante (menos preciso, mais rápido)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;DECIMAL&lt;/code&gt;&amp;nbsp;é preferível para valores monetários porque não tem os erros de arredondamento do&amp;nbsp;&lt;code&gt;FLOAT&lt;/code&gt;.&amp;nbsp;&lt;code&gt;FLOAT(1.1) + FLOAT(2.2)&lt;/code&gt;&amp;nbsp;pode resultar em&amp;nbsp;&lt;code&gt;3.3000000000000003&lt;/code&gt;&amp;nbsp;— um problema clássico de ponto flutuante.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Texto&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;-- texto de tamanho variável, até 100 caracteres&lt;/span&gt;
&lt;span class="n"&gt;sigla&lt;/span&gt; &lt;span class="nb"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;-- texto de tamanho fixo, sempre 2 caracteres&lt;/span&gt;
&lt;span class="n"&gt;descricao&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;          &lt;span class="c1"&gt;-- texto longo sem limite definido&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;CHAR&lt;/code&gt;&amp;nbsp;ocupa espaço fixo independente do conteúdo —&amp;nbsp;&lt;code&gt;CHAR(2)&lt;/code&gt;&amp;nbsp;para&amp;nbsp;&lt;code&gt;'SP'&lt;/code&gt;&amp;nbsp;e para&amp;nbsp;&lt;code&gt;'A'&lt;/code&gt;&amp;nbsp;ocupa o mesmo espaço.&amp;nbsp;&lt;code&gt;VARCHAR&lt;/code&gt;&amp;nbsp;ocupa só o necessário, sendo mais eficiente para campos de tamanho variável.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Data e Hora&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;nascimento&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;        &lt;span class="c1"&gt;-- apenas data: 1990-04-15&lt;/span&gt;
&lt;span class="n"&gt;abertura&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt;        &lt;span class="c1"&gt;-- apenas hora: 09:30:00&lt;/span&gt;
&lt;span class="n"&gt;criado_em&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt;   &lt;span class="c1"&gt;-- data e hora: 2024-03-10 14:22:00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Booleano e Nulo&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;ativo&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt;       &lt;span class="c1"&gt;-- TRUE ou FALSE&lt;/span&gt;
&lt;span class="n"&gt;apelido&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;-- pode receber NULL (ausência de valor)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;não é um tipo, mas um estado — significa que o valor é&amp;nbsp;&lt;strong&gt;desconhecido ou ausente&lt;/strong&gt;. É diferente de zero ou de uma string vazia. Uma coluna sem&amp;nbsp;&lt;code&gt;NOT NULL&lt;/code&gt;&amp;nbsp;aceita&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;&amp;nbsp;por padrão.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Operators&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Operadores são os símbolos e palavras usados para comparar, combinar e filtrar valores dentro de uma consulta. Eles aparecem principalmente na cláusula&amp;nbsp;&lt;code&gt;WHERE&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Comparação&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;       &lt;span class="c1"&gt;-- igual&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;      &lt;span class="c1"&gt;-- diferente (também pode ser &amp;lt;&amp;gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;          &lt;span class="c1"&gt;-- maior que&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;        &lt;span class="c1"&gt;-- menor ou igual&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Lógicos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Combinam múltiplas condições:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;estoque&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;         &lt;span class="c1"&gt;-- ambas verdadeiras&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;cidade&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SP'&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;cidade&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'RJ'&lt;/span&gt;     &lt;span class="c1"&gt;-- pelo menos uma verdadeira&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;ativo&lt;/span&gt;&lt;span class="c1"&gt;-- inverte a condição&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;BETWEEN, IN e LIKE&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- BETWEEN: intervalo inclusivo&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;precoBETWEEN&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="c1"&gt;-- IN: pertence a uma lista&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;cidadeIN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'RJ'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'BH'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- LIKE: correspondência de padrão&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;nomeLIKE&lt;/span&gt; &lt;span class="s1"&gt;'Ana%'&lt;/span&gt;     &lt;span class="c1"&gt;-- começa com "Ana"&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;emailLIKE&lt;/span&gt; &lt;span class="s1"&gt;'%@gmail%'&lt;/span&gt; &lt;span class="c1"&gt;-- contém "@gmail"&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;codigoLIKE&lt;/span&gt; &lt;span class="s1"&gt;'BR_'&lt;/span&gt;    &lt;span class="c1"&gt;-- "BR" seguido de exatamente um caractere&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No&amp;nbsp;&lt;code&gt;LIKE&lt;/code&gt;,&amp;nbsp;&lt;code&gt;%&lt;/code&gt;&amp;nbsp;substitui qualquer sequência de caracteres e&amp;nbsp;&lt;code&gt;_&lt;/code&gt;&amp;nbsp;substitui exatamente um caractere.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;IS NULL / IS NOT NULL&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;telefoneIS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;       &lt;span class="c1"&gt;-- campo sem valor&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;telefoneIS&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;   &lt;span class="c1"&gt;-- campo preenchido&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nunca use&amp;nbsp;&lt;code&gt;= NULL&lt;/code&gt;&amp;nbsp;— isso não funciona em SQL. O operador de igualdade não consegue comparar com&amp;nbsp;&lt;code&gt;NULL&lt;/code&gt;; use sempre&amp;nbsp;&lt;code&gt;IS NULL&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Introduzindo SQL</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 12 Jul 2026 21:45:30 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/introduzindo-sql-923</link>
      <guid>https://dev.to/yuripeixinho/introduzindo-sql-923</guid>
      <description>&lt;h1&gt;
  
  
  O que é SQL?
&lt;/h1&gt;

&lt;p&gt;SQL (Structured Query Language) é uma linguagem de programação utilizada para gerenciar e manipular dados armazenados em sistemas de gerenciamento de bancos de dados relacionais (RDBMS). Ela permite recuperar, inserir, atualizar e excluir dados, bem como definir esquemas de banco de dados e controlar o acesso aos dados. A compreensão básica de SQL é fundamental para interagir com praticamente qualquer banco de dados.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bancos de dados Relacionais
&lt;/h1&gt;

&lt;p&gt;Em 1970, o cientista da computação Edgar F. Codd publicou um artigo que mudaria para sempre a forma como armazenamos e consultamos dados. Nele, propunha organizar informações em estruturas tabulares — linhas e colunas — conectadas entre si por meio de relacionamentos lógicos. Nascia ali o modelo relacional, base de praticamente todo sistema de software corporativo que conhecemos hoje.&lt;/p&gt;

&lt;p&gt;Um banco de dados relacional armazena dados em&amp;nbsp;&lt;strong&gt;tabelas&lt;/strong&gt;. Cada tabela representa uma entidade do mundo real: clientes, pedidos, produtos. Cada linha é um registro individual, e cada coluna descreve um atributo desse registro. O que torna o modelo poderoso não é apenas a organização em tabelas, mas a capacidade de&amp;nbsp;&lt;strong&gt;relacioná-las&lt;/strong&gt;&amp;nbsp;— uma tabela de pedidos pode referenciar a tabela de clientes por meio de uma chave estrangeira, evitando duplicação e garantindo que os dados permaneçam consistentes.&lt;/p&gt;

&lt;p&gt;Essa consistência é garantida por um conjunto de propriedades conhecido pela sigla&amp;nbsp;&lt;strong&gt;ACID&lt;/strong&gt;: as operações são atômicas (ou tudo acontece, ou nada acontece), o banco sempre transita entre estados válidos, transações concorrentes não interferem entre si, e dados confirmados persistem mesmo diante de falhas. São essas garantias que tornam os SGBDRs a escolha natural para sistemas financeiros, hospitalares e qualquer domínio onde a integridade dos dados não é negociável.&lt;/p&gt;

&lt;p&gt;PostgreSQL, MySQL, Oracle Database e SQL Server são os representantes mais conhecidos dessa família. Cada um com suas particularidades, mas todos falando a mesma língua: o SQL.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Benefícios e Limitações dos SGBDRs&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Por décadas, o modelo relacional foi sinônimo de banco de dados. E com razão: ele resolve de forma elegante um problema difícil, que é manter grandes volumes de dados organizados, íntegros e acessíveis de forma eficiente.&lt;/p&gt;

&lt;p&gt;A linguagem SQL, padronizada e amplamente dominada pela indústria, permite expressar consultas complexas com poucas linhas. Um JOIN entre três tabelas que retorna exatamente os dados necessários, filtrados e ordenados, é algo que o modelo relacional faz com naturalidade. Somado a décadas de otimização dos engines, ferramentas maduras de administração e uma comunidade enorme, o SGBDR é uma das tecnologias mais confiáveis que existem.&lt;/p&gt;

&lt;p&gt;Mas toda escolha tem um custo. O modelo relacional exige que o esquema seja definido antes de armazenar os dados — e alterar esse esquema em produção pode ser uma operação delicada e cara. Em sistemas que evoluem rápido, ou cujos dados não têm forma bem definida, essa rigidez vira um obstáculo.&lt;/p&gt;

&lt;p&gt;Há também uma questão de escala. SGBDRs foram projetados para crescer verticalmente: quando o banco fica lento, você coloca mais memória, mais CPU, um disco mais rápido. Essa estratégia tem um limite físico e financeiro. Distribuir um banco relacional entre dezenas de servidores — escala horizontal — é tecnicamente possível, mas complexo, e vai contra a natureza do modelo. Para aplicações que precisam atender centenas de milhões de usuários com latência mínima, essa limitação se torna crítica.&lt;/p&gt;

&lt;h1&gt;
  
  
  SQL vs. NoSQL
&lt;/h1&gt;

&lt;p&gt;À medida que a internet cresceu, ficou evidente que o modelo relacional não era a resposta para todos os problemas. O ponto de virada aconteceu nos anos 2000, quando empresas como Google e Amazon começaram a enfrentar volumes de dados que nenhum SGBDR tradicional suportava adequadamente. Em 2006, o Google publicou o paper do Bigtable. Em 2007, a Amazon publicou o paper do Dynamo. Em 2008, o Facebook abriu o código do Cassandra, desenvolvido internamente para gerenciar a caixa de entrada de seus usuários. O termo "NoSQL" foi popularizado em uma meetup em San Francisco, em junho de 2009 — e a partir daí o movimento tomou forma.&lt;/p&gt;

&lt;p&gt;A motivação era clara: estima-se que cerca de 80% de todos os dados gerados hoje são não estruturados — mensagens, imagens, logs, dados de sensores, eventos de clique. Esse tipo de dado não cabe naturalmente em linhas e colunas de uma tabela relacional. Surgiu então o NoSQL, que mais do que uma negação do SQL, significa&amp;nbsp;&lt;em&gt;"Not Only SQL"&lt;/em&gt;: uma expansão do repertório de soluções disponíveis.&lt;/p&gt;

&lt;p&gt;NoSQL não é um único tipo de banco de dados, mas uma família de abordagens. Os&amp;nbsp;&lt;strong&gt;bancos de documentos&lt;/strong&gt;, como MongoDB, armazenam dados em formato JSON sem esquema fixo — ideais para catálogos e perfis de usuário. Os&amp;nbsp;&lt;strong&gt;bancos de chave-valor&lt;/strong&gt;, como Redis, operam como dicionários extremamente rápidos, perfeitos para cache e sessões. Os&amp;nbsp;&lt;strong&gt;bancos de coluna larga&lt;/strong&gt;, como Cassandra, foram construídos para escalar horizontalmente: o Netflix, por exemplo, usa Cassandra para processar mais de 1 trilhão de operações por dia. E os&amp;nbsp;&lt;strong&gt;bancos de grafo&lt;/strong&gt;, como Neo4j, modelam entidades e relacionamentos de forma nativa — a base de qualquer sistema de recomendação ou rede social.&lt;/p&gt;

&lt;p&gt;A grande concessão do NoSQL está na consistência. O teorema CAP, formulado por Eric Brewer em 2000, estabelece que um sistema distribuído não pode garantir simultaneamente consistência, disponibilidade e tolerância a partições de rede — é preciso abrir mão de um. A maioria dos sistemas NoSQL escolhe disponibilidade e tolerância a partições, adotando o modelo&amp;nbsp;&lt;strong&gt;BASE&lt;/strong&gt;: a consistência é eventual, podendo levar alguns milissegundos até que todos os nós do cluster reflitam o novo valor. Para uma rede social, isso é aceitável. Para um sistema bancário, não.&lt;/p&gt;

&lt;p&gt;A escolha entre SQL e NoSQL, portanto, não é uma questão de qual é melhor — é de qual serve melhor ao problema. O Stack Overflow Developer Survey de 2023 mostra PostgreSQL como banco de dados mais utilizado no mundo, com 45% dos desenvolvedores, enquanto MongoDB lidera entre os NoSQL com 28%. Esses números dizem algo importante: os dois modelos coexistem, e cada um domina onde faz sentido dominar.&lt;/p&gt;

&lt;p&gt;Na prática, sistemas modernos raramente escolhem apenas um lado. É comum usar PostgreSQL para os dados transacionais do negócio, Redis para cache de sessões e MongoDB para conteúdo dinâmico. A Amazon, que concluiu em 2019 a migração completa de seus sistemas internos para fora do Oracle — economizando cerca de US$ 1 bilhão por ano —, hoje oferece mais de quinze tipos diferentes de banco de dados na AWS. Cada ferramenta, no lugar onde ela brilha.&lt;/p&gt;

&lt;h1&gt;
  
  
  Aprendendo os Fundamentos Técnicos
&lt;/h1&gt;

&lt;p&gt;Antes de escrever consultas complexas, é preciso dominar o vocabulário básico do SQL. Esses quatro elementos: palavras-chave, tipos de dados, operadores e sintaxe, são a gramática da linguagem. Entendê-los bem é o que separa quem decora comandos de quem realmente entende o que está escrevendo.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>computerscience</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Descomplicando o Vite</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 20 Jun 2026 21:36:30 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/descomplicando-o-vite-1p62</link>
      <guid>https://dev.to/yuripeixinho/descomplicando-o-vite-1p62</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Antes do Vite, ferramentas como Webpack/CRA funcionavam assim: pra você ver qualquer coisa no navegador, a ferramenta precisava primeiro &lt;strong&gt;empacotar (bundlar) todo o seu projeto&lt;/strong&gt; — ler cada arquivo, resolver cada import, transformar tudo num (ou poucos) arquivo gigante de JS. Em projetos pequenos isso é rápido. Em projetos com milhares de módulos, esse "bundle inicial" podia levar dezenas de segundos, e &lt;strong&gt;toda vez&lt;/strong&gt; que você salvava um arquivo, boa parte disso precisava ser refeito.&lt;/p&gt;

&lt;p&gt;A sacada do Vite: &lt;strong&gt;navegadores modernos já sabem importar módulos ES nativamente&lt;/strong&gt; (&lt;code&gt;&amp;lt;script type="module"&amp;gt;&lt;/code&gt;, &lt;code&gt;import&lt;/code&gt;/&lt;code&gt;export&lt;/code&gt; direto no browser). Então, em desenvolvimento, por que bundlar nada? O Vite simplesmente serve cada arquivo como um módulo separado, sob demanda, só quando o navegador pede.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparação com restaurante
&lt;/h2&gt;

&lt;p&gt;Imagina um restaurante de buffet self-service. Antes de abrir as portas pro primeiro cliente, o chef precisa &lt;strong&gt;cozinhar o cardápio inteiro&lt;/strong&gt; — todos os pratos, todas as guarnições, tudo, mesmo que você só queira um cafezinho. Só depois que &lt;em&gt;tudo&lt;/em&gt; está pronto na bandeja é que a porta abre.&lt;/p&gt;

&lt;p&gt;Agora imagina que você é cliente fiel, vai lá todo dia, e pede pra trocar uma pitada de sal num prato. O que o chef faz? Ele não troca só o sal — ele &lt;strong&gt;manda o prato inteiro de volta pra cozinha, refaz boa parte do buffet de novo&lt;/strong&gt;, porque os pratos dependem uns dos outros (o molho usa o tempero, a guarnição usa o molho...). E você, sentado na mesa, fica esperando o buffet inteiro reabrir.&lt;/p&gt;

&lt;p&gt;Isso é literalmente o Webpack clássico/CRA: antes de você ver qualquer coisa no navegador, ele precisa &lt;strong&gt;empacotar (bundlar) o projeto inteiro&lt;/strong&gt;. E cada vez que você salva um arquivo, ele recalcula um bundle gigante de novo — quanto maior o projeto, mais demorado fica reabrir as portas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solução
&lt;/h3&gt;

&lt;p&gt;Agora o Vite. É um restaurante à la carte. A porta abre &lt;strong&gt;na hora&lt;/strong&gt;, sem ninguém cozinhar nada antes. Você senta, olha o cardápio (o &lt;code&gt;index.html&lt;/code&gt;), e pede só o que quer — "garçom, me traz o &lt;code&gt;main.tsx&lt;/code&gt;". O garçom vai até a cozinha, o chef prepara &lt;strong&gt;só esse prato&lt;/strong&gt;, na hora, e te entrega. Você come e pede a sobremesa (&lt;code&gt;App.tsx&lt;/code&gt;)? Aí sim ele prepara a sobremesa — só ela, não o cardápio inteiro de novo.&lt;/p&gt;

&lt;h1&gt;
  
  
  As duas fases do Vite
&lt;/h1&gt;

&lt;p&gt;Isso é a ideia central: o Vite usa estratégias diferentes pra cada momento porque os dois momentos têm necessidades opostas.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Desenvolvimento (&lt;code&gt;vite&lt;/code&gt;/&lt;code&gt;vite dev&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;Produção (&lt;code&gt;vite build&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Estratégia&lt;/td&gt;
&lt;td&gt;Serve módulos ESM nativos, sem bundlar&lt;/td&gt;
&lt;td&gt;Empacota tudo via &lt;strong&gt;Rolldown&lt;/strong&gt; (bundler em Rust)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Velocidade de start&lt;/td&gt;
&lt;td&gt;Instantânea, não depende do tamanho do projeto&lt;/td&gt;
&lt;td&gt;Leva o tempo proporcional ao projeto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Por quê essa diferença&lt;/td&gt;
&lt;td&gt;Em dev, poucas requisições HTTP locais não importam — rede é instantânea&lt;/td&gt;
&lt;td&gt;Em produção, centenas de arquivos separados = centenas de requisições HTTP reais pro usuário final, isso é ruim. Bundlar reduz isso&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>tooling</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CLI Tools</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 20 Jun 2026 21:36:11 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/cli-tools-4lo2</link>
      <guid>https://dev.to/yuripeixinho/cli-tools-4lo2</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;CLI = &lt;strong&gt;Command Line Interface&lt;/strong&gt;. É um jeito de controlar um programa digitando texto, em vez de clicar em ícones e janelas (isso seria uma GUI — Graphical User Interface). Você digita um comando, aperta Enter, o programa executa e devolve uma resposta em texto. Não é algo específico de JavaScript ou web — &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;cd&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;docker&lt;/code&gt; são todas CLIs, e existem desde muito antes da internet existir.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A anatomia de um comando&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Quase todo comando de terminal segue essa estrutura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;comando&lt;/span&gt; &lt;span class="nx"&gt;subcomando&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;argumento&lt;/span&gt;
   &lt;span class="err"&gt;│&lt;/span&gt;        &lt;span class="err"&gt;│&lt;/span&gt;          &lt;span class="err"&gt;│&lt;/span&gt;      &lt;span class="err"&gt;│&lt;/span&gt;      &lt;span class="err"&gt;│&lt;/span&gt;
  &lt;span class="nx"&gt;git&lt;/span&gt;     &lt;span class="nx"&gt;commit&lt;/span&gt;      &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;msg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;   &lt;span class="nx"&gt;arquivo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Por que isso importa tanto no desenvolvimento&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;GUIs são ótimas pra explorar visualmente, mas CLIs ganham em três frentes que importam muito pra programação:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automação&lt;/strong&gt; — você pode colocar um comando dentro de um script e rodar mil vezes sem clicar em nada&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composição&lt;/strong&gt; — como vimos com os pipes, você combina ferramentas pequenas em fluxos complexos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Funciona sem interface gráfica&lt;/strong&gt; — servidores, containers Docker, pipelines de CI/CD geralmente não têm tela nenhuma; só dá pra interagir via terminal&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;É por isso que praticamente toda ferramenta séria do ecossistema JS (Vite, ESLint, TypeScript, Git, Docker) é, no fundo, uma CLI: ela precisa rodar igualzinho na sua máquina e num servidor remoto sem interface nenhuma, de forma automatizável.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cli</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Typescript: Sobrecarga de Construtor</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 13 Jun 2026 21:53:26 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/sobrecarga-de-construtor-hkh</link>
      <guid>https://dev.to/yuripeixinho/sobrecarga-de-construtor-hkh</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Assim como funções, construtores podem ter múltiplas assinaturas:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;O problema&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Evento&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tipo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;competencia&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// como aceitar também só id e tipo, sem competencia?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Solução — overload signatures&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Evento&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;tipo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;competencia&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// assinaturas&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tipo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tipo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;competencia&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// implementação&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tipo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;competencia&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nao-definida&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tipo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tipo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;competencia&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;competencia&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Evento&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;R-2010&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;              &lt;span class="c1"&gt;// ✅ primeira assinatura&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Evento&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;R-2010&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// ✅ segunda assinatura&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
