Voltar para Home

Do zero ao Avançado com MariaDB

Consultas Poderosas

Projeto Lanchonete

📋 Conteúdo Completo

Módulos e Aulas

Do zero ao avançado: consultas, junções, funções agregadas, criação de bancos e tabelas, constraints e um projeto prático completo: Sistema de Gestão para Lanchonete (MariaDB).. Clique nas aulas para ver os conteúdos.


01

Módulo 01 – Introdução ao SQL

Fundamentos da linguagem, sintaxe, SELECT, WHERE, ORDER BY, operadores lógicos, INSERT, UPDATE, DELETE e LIMIT.

12 aulas
SQL Introdução

O que é SQL e como instalar

15min
Resumo: SQL (Structured Query Language) é o padrão mundial para consultar, manipular e definir bancos de dados relacionais. Permite gerenciar grandes volumes de dados garantindo integridade e consistência transacional (ACID).
-- Boas-vindas ao SQL! Teste de conexão e versão SELECT VERSION() AS versao_sgbd, NOW() AS data_hora_atual;
SQL Sintaxe

Indentação e função SELECT

15min
Resumo: Comandos SQL não diferenciam maiúsculas de minúsculas por padrão, mas é boa prática escrever palavras-chave em MAIÚSCULAS e nomes de tabelas em minúsculas. Toda instrução termina com ponto e vírgula (;).
-- Estrutura clássica de leitura SELECT id_aluno, nome, email FROM alunos WHERE ativo = 1;
SQL Select

Selecionando colunas específicas

15min
Resumo: O comando SELECT especifica quais colunas da tabela você deseja retornar. Use o asterisco (*) para retornar todas as colunas ou liste os nomes separados por vírgula para otimizar desempenho de rede.
-- Selecionando todas as colunas e colunas específicas SELECT * FROM alunos; SELECT nome, telefone FROM alunos;
SQL Select Distinct

Eliminando linhas duplicadas

15min
Resumo: DISTINCT elimina linhas duplicadas do conjunto retornado. É essencial quando uma coluna possui valores repetidos e você quer saber apenas os itens únicos existentes.
-- Cidades únicas de onde vêm os alunos SELECT DISTINCT cidade FROM alunos ORDER BY cidade ASC;
SQL Where

Filtrando registros

15min
Resumo: A cláusula WHERE filtra registros que satisfazem uma condição lógica. Apenas as linhas avaliadas como VERDADEIRAS (TRUE) são retornadas pelo SGBD.
-- Alunos cadastrados a partir de 2024 com nota superior ou igual a 7.0 SELECT nome, nota_final FROM matriculas WHERE nota_final >= 7.0;
SQL Order By

Ordenando resultados

15min
Resumo: ORDER BY ordena os resultados por uma ou mais colunas de forma ascendente (ASC, padrão) ou descendente (DESC). Pode-se encadear múltiplos critérios de desempate.
-- Ordenar por nota mais alta, desempatando pelo nome do aluno SELECT nome, nota FROM alunos ORDER BY nota DESC, nome ASC;
SQL And, Or e Not

Operadores lógicos

15min
Resumo: Operadores lógicos combinam condições. AND exige que todas sejam verdadeiras; OR exige que pelo menos uma seja satisfeita; NOT inverte o valor de verdade da condição.
-- Alunos de SP ou RJ que NÃO estão inativos SELECT nome, uf, status FROM alunos WHERE (uf = 'SP' OR uf = 'RJ') AND NOT (status = 'INATIVO');
SQL Insert Into

Inserindo novos registros

15min
Resumo: INSERT INTO grava uma ou mais novas linhas na tabela. É recomendável explicitar a lista de colunas antes da cláusula VALUES para garantir estabilidade caso a estrutura mude.
-- Inserção de registro individual e múltiplo INSERT INTO alunos (nome, email, data_nascimento) VALUES ('Mariana Lima', 'mariana@email.com', '2001-05-14'), ('Carlos Eduardo', 'carlos@email.com', '1998-11-20');
SQL Null Values

Trabalhando com valores nulos

15min
Resumo: NULL representa dado ausente ou desconhecido, não é igual a zero nem texto vazio. Comparações com '= NULL' falham sempre; deve-se usar IS NULL ou IS NOT NULL.
-- Alunos sem número de telefone informado SELECT id_aluno, nome FROM alunos WHERE telefone IS NULL;
SQL Update

Atualizando registros existentes

15min
Resumo: UPDATE modifica valores em colunas existentes. ATENÇÃO: sempre inclua a cláusula WHERE, caso contrário todas as linhas da tabela serão alteradas indiscriminadamente.
-- Atualiza o e-mail e status de um aluno específico UPDATE alunos SET email = 'mariana.novo@email.com', status = 'ATIVO' WHERE id_aluno = 101;
SQL Delete

Removendo registros

15min
Resumo: DELETE remove linhas de uma tabela com base na condição WHERE. Omitir o WHERE apaga todos os dados da tabela, mantendo sua estrutura e integridade relacional.
-- Excluir matrículas canceladas antes de 2020 DELETE FROM matriculas WHERE status = 'CANCELADA' AND data_matricula < '2020-01-01';
SQL Select Top (LIMIT / TOP)

Limitando resultados e paginação

15min
Resumo: Limita o número de registros retornados. No MySQL e MariaDB utiliza-se a cláusula LIMIT (com suporte a OFFSET para paginação), equivalente ao TOP do SQL Server.
-- 5 alunos mais bem classificados (Paginação: LIMIT qtd OFFSET deslocamento) SELECT nome, nota_geral FROM alunos ORDER BY nota_geral DESC LIMIT 5 OFFSET 0;
02

Módulo 02 – Funções Agregadas

MIN, MAX, COUNT, SUM, AVG, LIKE, Wildcards, IN, BETWEEN e Aliases.

10 aulas
SQL Min()

Encontrando o menor valor

15min
Resumo: Retorna o menor valor de uma coluna numérica, data ou textual após processar todas as linhas que atendem aos filtros estabelecidos.
SELECT MIN(preco) AS menor_mensalidade FROM cursos WHERE ativo = 1;
SQL Max()

Encontrando o maior valor

15min
Resumo: Retorna o maior valor de uma coluna especificada, sendo muito usada para localizar maiores notas, tetos de faturamento ou registros mais recentes.
SELECT MAX(nota_final) AS melhor_nota FROM matriculas;
SQL Count()

Contando linhas

15min
Resumo: COUNT(*) conta o número total de linhas encontradas, enquanto COUNT(coluna) conta apenas valores não nulos presentes nessa coluna específica.
SELECT COUNT(*) AS total_alunos, COUNT(telefone) AS total_com_telefone FROM alunos;
SQL Sum()

Somando valores

15min
Resumo: SUM() calcula a soma total acumulada de uma coluna numérica ignorando valores NULL. Muito utilizada em relatórios contábeis e financeiros.
SELECT SUM(valor_pago) AS receita_total FROM pagamentos WHERE status = 'CONFIRMADO';
SQL Avg()

Calculando a média

15min
Resumo: AVG() retorna a média aritmética simples dos valores numéricos não nulos de uma coluna. Útil para métricas de desempenho e tickets médios.
SELECT ROUND(AVG(nota_final), 2) AS media_geral_turma FROM matriculas;
SQL Like

Busca por padrões em texto

15min
Resumo: O operador LIKE realiza buscas por padrões em textos, sendo indispensável para pesquisas fonéticas parciais em cadastros de clientes e produtos.
-- Nomes que começam com 'Ana' e e-mails do domínio gmail SELECT nome, email FROM alunos WHERE nome LIKE 'Ana%'; SELECT nome, email FROM alunos WHERE email LIKE '%@gmail.com';
SQL Wildcards

Curingas % e _

15min
Resumo: Curingas usados com LIKE: '%' representa zero ou múltiplos caracteres; '_' representa exatamente um caractere único na posição indicada.
-- Nomes com exatamente 4 letras iniciando por 'L' e terminando por 'z' SELECT nome FROM alunos WHERE nome LIKE 'L__z';
SQL In

Verificando pertencimento a lista

15min
Resumo: O operador IN verifica se um valor pertence a uma lista finita pré-determinada ou ao resultado de uma subconsulta, substituindo múltiplos encadeamentos de OR.
SELECT nome, uf FROM alunos WHERE uf IN ('SP', 'RJ', 'MG', 'PR');
SQL Between

Filtrando por intervalo

15min
Resumo: BETWEEN filtra valores dentro de um intervalo fechado inclusivo (inclui os limites inicial e final). Funciona com números, textos e datas.
SELECT nome, data_matricula FROM matriculas WHERE data_matricula BETWEEN '2024-01-01' AND '2024-06-30';
SQL Aliases

Apelidos para colunas e tabelas

15min
Resumo: Aliases (AS) renomeiam temporariamente colunas ou tabelas na consulta para melhorar a clareza e facilitar a escrita de junções complexas.
SELECT a.nome AS aluno_nome, c.nome AS curso_nome FROM alunos AS a JOIN matriculas AS m ON a.id_aluno = m.id_aluno JOIN cursos AS c ON m.id_curso = c.id_curso;
03

Módulo 03 – Junções (Joins)

Inner Join, Left Join, Right Join, Full Join, Self Join, Union e Union All.

8 aulas
SQL Joins

Conceito de junções relacionais

15min
Resumo: Junções combinam linhas de duas ou mais tabelas relacionais com base em uma coluna comum correspondente (normalmente Chave Primária e Chave Estrangeira).
-- Combinação relacional básica SELECT alunos.nome, matriculas.data_matricula FROM alunos JOIN matriculas ON alunos.id_aluno = matriculas.id_aluno;
SQL Inner Join

Retornando apenas correspondências

15min
Resumo: Retorna apenas os registros que possuem correspondência exata em ambas as tabelas envolvidas na cláusula de junção ON.
SELECT a.nome, c.nome AS curso, m.nota_final FROM alunos a INNER JOIN matriculas m ON a.id_aluno = m.id_aluno INNER JOIN cursos c ON m.id_curso = c.id_curso;
SQL Left Join

Preservando a tabela da esquerda

15min
Resumo: Retorna todas as linhas da tabela à esquerda (primeira mencionada) e as linhas correspondentes da direita. Se não houver correspondência, preenche com NULL.
-- Lista TODOS os alunos, inclusive os que ainda não se matricularam em nada SELECT a.id_aluno, a.nome, m.id_matricula FROM alunos a LEFT JOIN matriculas m ON a.id_aluno = m.id_aluno;
SQL Right Join

Preservando a tabela da direita

15min
Resumo: Retorna todas as linhas da tabela à direita e os dados da esquerda quando houver. Raramente obrigatório, pois pode ser reescrito com LEFT JOIN invertendo a ordem.
-- Garante que todos os cursos apareçam, mesmo sem alunos matriculados SELECT c.nome AS curso, m.id_aluno FROM matriculas m RIGHT JOIN cursos c ON m.id_curso = c.id_curso;
SQL Full Join

União completa de tabelas

15min
Resumo: Retorna registros quando há correspondência em qualquer uma das tabelas. No MySQL/MariaDB, emula-se FULL OUTER JOIN combinando LEFT JOIN e RIGHT JOIN com UNION.
-- Emulação de FULL JOIN no MySQL/MariaDB SELECT a.nome, m.id_curso FROM alunos a LEFT JOIN matriculas m ON a.id_aluno = m.id_aluno UNION SELECT a.nome, m.id_curso FROM alunos a RIGHT JOIN matriculas m ON a.id_aluno = m.id_aluno;
SQL Self Join

Junção da tabela consigo mesma

15min
Resumo: É uma junção regular de uma tabela com ela mesma. Útil para estruturas hierárquicas, como funcionários e seus respectivos supervisores na mesma tabela.
-- Tabela de funcionários com id_gerente apontando para a mesma tabela SELECT f.nome AS colaborador, g.nome AS gerente FROM funcionarios f LEFT JOIN funcionarios g ON f.id_gerente = g.id_funcionario;
SQL Union

Combinando resultados sem duplicatas

15min
Resumo: Combina o resultado de duas consultas SELECT em um único conjunto de linhas, eliminando duplicatas automaticamente. Ambas as consultas devem ter mesmo número e tipo de colunas.
-- Cidades de alunos e professores em lista única unificada SELECT cidade FROM alunos UNION SELECT cidade FROM professores ORDER BY cidade;
SQL Union All

Combinando resultados com duplicatas

15min
Resumo: UNION ALL combina duas consultas mantendo todas as linhas, inclusive as duplicadas. Por não executar a rotina de desduplicação (DISTINCT), é significativamente mais rápido.
SELECT id_aluno, 'Aluno' AS tipo FROM alunos UNION ALL SELECT id_funcionario, 'Funcionario' AS tipo FROM funcionarios;
04

Módulo 04 – Agrupamento e Subconsultas

Group By, Having, Exists, Any, All, Select Into, Insert Into Select, Case e Null Functions.

9 aulas
SQL Group By

Agrupando linhas para agregação

15min
Resumo: Agrupa linhas que compartilham valores comuns em linhas de resumo. Sempre utilizado em conjunto com funções agregadas como SUM, COUNT e AVG.
SELECT c.nome AS curso, COUNT(m.id_matricula) AS total_matriculados FROM cursos c JOIN matriculas m ON c.id_curso = m.id_curso GROUP BY c.id_curso, c.nome;
SQL Having

Filtrando grupos agregados

15min
Resumo: HAVING filtra grupos após a agregação, ao passo que WHERE filtra linhas individuais antes do agrupamento. Permite condições em funções agregadas.
-- Apenas cursos com mais de 50 alunos cadastrados SELECT c.nome, COUNT(m.id_matricula) AS qtd FROM cursos c JOIN matriculas m ON c.id_curso = m.id_curso GROUP BY c.id_curso, c.nome HAVING COUNT(m.id_matricula) > 50;
SQL Exists

Testando existência de subconsulta

15min
Resumo: Testa a existência de linhas retornadas por uma subconsulta. Retorna TRUE assim que o primeiro registro coincidente é encontrado, sendo altamente otimizado.
-- Alunos que possuem pelo menos uma matrícula registrada SELECT a.nome, a.email FROM alunos a WHERE EXISTS ( SELECT 1 FROM matriculas m WHERE m.id_aluno = a.id_aluno );
SQL Any

Comparação com qualquer valor

15min
Resumo: Retorna TRUE se a comparação for verdadeira para qualquer um dos valores retornados pela subconsulta. Opera com =, <>, >, <, >=, <=.
-- Cursos com carga horária maior do que qualquer curso básico SELECT nome, duracao_horas FROM cursos WHERE duracao_horas > ANY ( SELECT duracao_horas FROM cursos WHERE nivel = 'BASICO' );
SQL All

Comparação com todos os valores

15min
Resumo: Retorna TRUE somente se a condição for satisfeita para TODOS os valores retornados pela subconsulta.
-- Alunos com nota superior a todas as notas dos alunos reprovados SELECT nome, nota_final FROM matriculas WHERE nota_final > ALL ( SELECT nota_final FROM matriculas WHERE status = 'REPROVADO' );
SQL Select Into

Criando tabelas a partir de consultas

15min
Resumo: Cria uma nova tabela e insere nela os dados selecionados. No MySQL/MariaDB utiliza-se a sintaxe padrão 'CREATE TABLE nova_tabela AS SELECT ...'.
-- Criando tabela de backup com dados históricos CREATE TABLE alunos_backup AS SELECT * FROM alunos WHERE ativo = 1;
SQL Insert Into Select

Copiando dados entre tabelas

15min
Resumo: Copia linhas de uma ou mais tabelas existentes e as insere diretamente em uma tabela destino já previamente criada.
INSERT INTO arquivo_morto_alunos (id_aluno, nome, motivo) SELECT id_aluno, nome, 'Inatividade superior a 5 anos' FROM alunos WHERE ultimo_acesso < '2019-01-01';
SQL Case

Condições if-then-else no SQL

15min
Resumo: Instrução condicional (if-then-else) no SQL. Avalia condições e retorna o primeiro valor verdadeiro correspondente ou o valor da cláusula ELSE.
SELECT nome, nota_final, CASE WHEN nota_final >= 7.0 THEN 'Aprovado' WHEN nota_final >= 5.0 THEN 'Recuperação' ELSE 'Reprovado' END AS situacao_aluno FROM matriculas;
SQL Null Functions

COALESCE e IFNULL

15min
Resumo: Funções como COALESCE() e IFNULL() substituem valores nulos por um substituto legível padrão durante a exibição de resultados.
-- Se telefone for NULL, exibe 'Não Informado' SELECT nome, COALESCE(telefone, 'Não Informado') AS contato FROM alunos;
05

Módulo 05 – Avançado e Operadores

Stored Procedures, Comments, Operators e conceitos avançados de lógica.

3 aulas
SQL Stored Procedures

Criando procedimentos armazenados

20min
Resumo: Procedimentos armazenados são blocos de código SQL compilados no servidor que podem receber parâmetros de entrada e executar lógicas completas repetitivas.
DELIMITER // CREATE PROCEDURE sp_MatricularAluno( IN p_aluno_id BIGINT, IN p_curso_id BIGINT ) BEGIN INSERT INTO matriculas (id_aluno, id_curso, data_matricula, status) VALUES (p_aluno_id, p_curso_id, NOW(), 'ATIVA'); END // DELIMITER ; -- Chamada: CALL sp_MatricularAluno(10, 2);
SQL Comments

Documentando o código SQL

10min
Resumo: Comentários documentam e explicam o código. Em SQL usam-se duas barras com espaço ('-- ') para linhas únicas ou '/* ... */' para blocos multi-linhas.
-- Consulta para auditoria de pagamentos com estorno /* Regra de negócio: estornos feitos em menos de 7 dias possuem reembolso integral autorizado pelo financeiro. */ SELECT * FROM pagamentos WHERE status = 'ESTORNADO';
SQL Operators

Operadores aritméticos e de comparação

15min
Resumo: Compreende operadores aritméticos (+, -, *, /, %), de comparação (=, <>, !=, <, >, <=, >=) e de bits. Essenciais para cálculos no próprio banco.
-- Cálculo de valor com juros e resto da divisão SELECT valor_original, valor_original * 1.05 AS valor_com_juros, id_aluno % 2 AS turma_par_ou_impar FROM faturas;
06

Módulo 06 – Banco de Dados

Criação, exclusão e backup de bancos de dados (Schemas).

4 aulas
SQL Database

Conceito de banco de dados

10min
Resumo: Um banco de dados (database ou schema) é o repositório lógico onde residem tabelas, views, triggers e procedimentos armazenados de um mesmo sistema.
SHOW DATABASES; SELECT DATABASE();
SQL Create DB

Criando um novo banco de dados

10min
Resumo: Cria um novo banco de dados no servidor. Sempre defina o conjunto de caracteres utf8mb4 e a collation correspondente para aceitar acentos e emojis perfeitamente.
CREATE DATABASE IF NOT EXISTS escola_tech CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE escola_tech;
SQL Drop DB

Excluindo bancos de dados

10min
Resumo: Exclui permanentemente um banco de dados e todos os seus objetos internos (tabelas, índices, dados). Use IF EXISTS para prevenir erros de execução.
-- CUIDADO: Operação irreversível! DROP DATABASE IF EXISTS laboratorio_sql;
SQL Backup DB

Exportação e restauração via mysqldump

15min
Resumo: Cópias de segurança previnem perda de dados catastrófica. No MariaDB/MySQL a ferramenta padrão de linha de comando é o 'mysqldump' ou 'mariadb-dump'.
# Terminal do Sistema Operacional (dump do banco de dados): mysqldump -u root -p --routines --triggers lanchonete_gestao > backup_lanchonete.sql # Restaurar backup: mysql -u root -p lanchonete_gestao < backup_lanchonete.sql
07

Módulo 07 – Tabelas

Create Table, Drop Table e Alter Table (DDL).

3 aulas
SQL Create Table

Definindo estrutura de tabelas

20min
Resumo: Instrução DDL que define o nome da tabela, seus campos, tipos de dados, valores padrão e constraints fundamentais como chaves primárias e estrangeiras.
CREATE TABLE IF NOT EXISTS cursos ( id_curso BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(100) NOT NULL, duracao_horas SMALLINT UNSIGNED NOT NULL DEFAULT 20, preco DECIMAL(10,2) NOT NULL DEFAULT 0.00, ativo TINYINT(1) NOT NULL DEFAULT 1, criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB;
SQL Drop Table

Removendo tabelas

10min
Resumo: Elimina por completo a tabela e todos os seus registros do disco. Tabelas referenciadas por Foreign Keys de outras tabelas exigem exclusão ordenada ou drop prévio da FK.
DROP TABLE IF EXISTS matriculas_temporarias;
SQL Alter Table

Modificando estrutura existente

15min
Resumo: Modifica a estrutura de uma tabela existente sem recriá-la, permitindo adicionar, alterar ou remover colunas, índices e restrições de integridade.
-- Adicionar coluna e modificar tipo de dado ALTER TABLE cursos ADD COLUMN nivel ENUM('INICIANTE','INTERMEDIARIO','AVANCADO') DEFAULT 'INICIANTE'; ALTER TABLE cursos MODIFY COLUMN nome VARCHAR(150) NOT NULL;
08

Módulo 08 – Constraints e Índices

Not Null, Unique, Primary Key, Foreign Key, Check, Default, Auto Increment e Create Index.

9 aulas
SQL Constraints

Visão geral de restrições

15min
Resumo: Regras de negócio aplicadas no nível da tabela que impedem a inserção de dados inconsistentes, garantindo a integridade relacional do banco de dados.
-- Exemplo de criação com constraints nomeadas CREATE TABLE matriculas_validas ( id BIGINT PRIMARY KEY, nota DECIMAL(4,2), CONSTRAINT chk_nota_valida CHECK (nota BETWEEN 0 AND 10) );
SQL Not Null

Impedindo valores nulos

10min
Resumo: Impede que uma coluna aceite valores nulos (NULL). A inserção ou atualização falhará caso o campo não receba um valor válido ou não possua DEFAULT.
ALTER TABLE alunos MODIFY COLUMN email VARCHAR(190) NOT NULL;
SQL Unique

Garantindo valores distintos

10min
Resumo: Garante que todos os valores presentes naquela coluna (ou combinação de colunas) sejam distintos entre si em toda a tabela.
ALTER TABLE alunos ADD CONSTRAINT uk_aluno_email UNIQUE (email);
SQL Primary Key

Identificador exclusivo

10min
Resumo: Identificador exclusivo de cada linha em uma tabela. Combina implicitamente NOT NULL e UNIQUE. Cada tabela relacional bem projetada deve ter exatamente uma Primary Key.
CREATE TABLE turmas ( id_turma BIGINT UNSIGNED AUTO_INCREMENT, codigo VARCHAR(20) NOT NULL, PRIMARY KEY (id_turma) );
SQL Foreign Key

Integridade referencial

15min
Resumo: Chave estrangeira que conecta uma coluna de uma tabela à chave primária de outra tabela, impedindo links quebrados e garantindo integridade referencial.
ALTER TABLE matriculas ADD CONSTRAINT fk_matr_aluno FOREIGN KEY (id_aluno) REFERENCES alunos(id_aluno) ON DELETE CASCADE;
SQL Check

Validando intervalo de valores

10min
Resumo: Limita o intervalo de valores que podem ser armazenados em uma coluna. No MariaDB 10.2+ e MySQL 8.0+ a constraint CHECK é rigidamente validada em INSERT e UPDATE.
ALTER TABLE cursos ADD CONSTRAINT chk_preco_positivo CHECK (preco >= 0);
SQL Default

Valores padrão

10min
Resumo: Especifica um valor padrão que será gravado automaticamente caso a cláusula INSERT não forneça valor para a referida coluna.
ALTER TABLE alunos ALTER COLUMN ativo SET DEFAULT 1;
SQL Create Index

Otimizando consultas

15min
Resumo: Estruturas em árvore B-Tree que aceleram drasticamente a recuperação de dados em consultas com WHERE e ORDER BY, com custo de escrita em INSERT/UPDATE.
-- Índice comum e índice composto CREATE INDEX idx_alunos_email ON alunos(email); CREATE INDEX idx_matr_aluno_curso ON matriculas(id_aluno, id_curso);
SQL Auto Increment

Geração automática de IDs

10min
Resumo: Gera automaticamente números sequenciais exclusivos sempre que uma nova linha é inserida, sendo o padrão para identificadores substitutos (Surrogate Keys).
CREATE TABLE salas ( id_sala INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, bloco CHAR(1) NOT NULL ); -- Obter o ID gerado na conexão: SELECT LAST_INSERT_ID();
09

Módulo 09 – Datas, Views e Segurança

Manipulação de datas, Views, SQL Injection, Parameters, Prepared Statements e Hosting.

6 aulas
SQL Dates

Tipos e funções temporais

15min
Resumo: Tipos temporais: DATE (YYYY-MM-DD), TIME (HH:MM:SS), DATETIME e TIMESTAMP. Funções como NOW(), DATEDIFF() e DATE_ADD() permitem operações temporais complexas.
SELECT NOW() AS agora, DATEDIFF(NOW(), '2024-01-01') AS dias_decorridos, DATE_ADD(NOW(), INTERVAL 30 DAY) AS vencimento_fatura;
SQL Views

Tabelas virtuais

15min
Resumo: Views são tabelas virtuais baseadas no resultado de uma consulta SELECT. Simplificam consultas complexas, padronizam regras de negócio e protegem colunas sensíveis.
CREATE OR REPLACE VIEW vw_alunos_ativos AS SELECT a.id_aluno, a.nome, a.email, COUNT(m.id_matricula) AS total_cursos FROM alunos a LEFT JOIN matriculas m ON a.id_aluno = m.id_aluno WHERE a.ativo = 1 GROUP BY a.id_aluno, a.nome, a.email;
SQL Injection

Vulnerabilidades de segurança

15min
Resumo: Vulnerabilidade crítica de segurança que ocorre quando dados não tratados do usuário são concatenados diretamente em comandos SQL, permitindo manipulação maliciosa do banco.
-- VULNERÁVEL (NUNCA faça concatenação de string em código de backend): -- "SELECT * FROM usuarios WHERE email = '" + emailInput + "';" -- Se emailInput for "' OR '1'='1", todo o controle de autenticação é quebrado!
SQL Parameters

Uso de placeholders (?)

15min
Resumo: Parâmetros parametrizados dissociam o comando SQL dos dados enviados, garantindo que valores fornecidos pelo usuário sejam interpretados estritamente como literais.
-- Exemplo conceitual com placeholders (?): SELECT id_usuario, nome, email FROM usuarios WHERE email = ? AND ativo = ?;
SQL Prepared Statements

Consultas pré-compiladas

15min
Resumo: Instruções preparadas pré-compilam a sintaxe do comando no servidor de banco de dados, oferecendo proteção absoluta contra SQL Injection e ganho de performance em repetições.
PREPARE consulta_aluno FROM 'SELECT nome, email FROM alunos WHERE id_aluno = ?'; SET @aluno_alvo = 10; EXECUTE consulta_aluno USING @aluno_alvo; DEALLOCATE PREPARE consulta_aluno;
SQL Hosting

Hospedagem e usuários

15min
Resumo: Implantação e hospedagem de bancos de dados em servidores dedicados ou nuvens gerenciadas. Exige atenção a portas (3306), firewalls e backups.
-- Boas práticas de usuário restrito para a aplicação web: CREATE USER 'app_lanchonete'@'192.168.1.%' IDENTIFIED BY 'SenhaForte123!#'; GRANT SELECT, INSERT, UPDATE, DELETE ON lanchonete_gestao.* TO 'app_lanchonete'@'192.168.1.%'; FLUSH PRIVILEGES;
10

Módulo 10 – Referências e Funções

Data Types, Keywords, Funções MariaDB/MySQL e Quick Ref.

4 aulas
SQL Data Types

Tipos de dados no MariaDB/MySQL

15min
Resumo: Tipos de dados no MariaDB/MySQL: Numéricos (INT, BIGINT, DECIMAL), Textos (CHAR, VARCHAR, TEXT), Temporais (DATE, DATETIME, TIMESTAMP) e Booleanos (TINYINT(1)).
-- Tabela demonstrando a tipagem recomendada para conformidade e precisão CREATE TABLE catalogo_tipos ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, codigo CHAR(8) NOT NULL, descricao VARCHAR(255) NOT NULL, valor_monetario DECIMAL(12,2), publicado_em DATETIME NOT NULL );
SQL Keywords

Palavras reservadas

10min
Resumo: Palavras reservadas da linguagem que possuem significado sintático especial (SELECT, FROM, WHERE, GROUP, ORDER, TABLE, JOIN). Se uma coluna tiver nome reservado, use crases (`nome`).
-- Uso de crases para campos com nomes coincidentes com palavras-chave SELECT `order`, `status`, `group` FROM pedidos_legado;
Funções MariaDB/MySQL

Funções embutidas úteis

15min
Resumo: Funções embutidas úteis: CONCAT(), COALESCE(), UPPER(), LOWER(), DATE_FORMAT(), TIMESTAMPDIFF(), JSON_EXTRACT(). Aumentam o poder de transformação de dados diretamente no banco.
SELECT CONCAT(nome, ' <', email, '>') AS destinatario, DATE_FORMAT(criado_em, '%d/%m/%Y às %H:%i') AS data_formatada_br, UPPER(cidade) AS cidade_alta FROM alunos;
SQL Quick Ref

Ordem de execução das cláusulas

15min
Resumo: Guia de consulta rápida contendo a ordem rigorosa de execução das cláusulas SQL: 1. FROM/JOIN, 2. WHERE, 3. GROUP BY, 4. HAVING, 5. SELECT, 6. DISTINCT, 7. ORDER BY, 8. LIMIT.
-- Estrutura canônica de uma consulta completa: SELECT c.categoria, COUNT(p.id) AS total, AVG(p.preco) AS media_preco FROM produtos p JOIN categorias c ON p.id_categoria = c.id WHERE p.ativo = 1 GROUP BY c.categoria HAVING media_preco > 20.00 ORDER BY total DESC LIMIT 10;
11

P1 – Usuários, Funcionários, Perfis e Permissões

Projeto Prático: Estrutura de autenticação e controle de acesso (RBAC).

3 aulas
Tabela cargos

Hierarquia profissional

15min
Resumo: Armazena a hierarquia e funções profissionais da lanchonete. A chave primária é id_cargo, com campo nome VARCHAR(100) marcado como UNIQUE.
CREATE TABLE IF NOT EXISTS cargos ( id_cargo BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(100) NOT NULL UNIQUE, descricao VARCHAR(255), ativo TINYINT(1) NOT NULL DEFAULT 1 ) ENGINE=InnoDB;
Tabela funcionarios

Cadastro de colaboradores

15min
Resumo: Registra os colaboradores operacionais e administrativos. Possui chave primária id_funcionario, chaves únicas para matricula e cpf, além de chave estrangeira fk_func_cargo.
CREATE TABLE IF NOT EXISTS funcionarios ( id_funcionario BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, matricula VARCHAR(30) UNIQUE, nome VARCHAR(100) NOT NULL, cpf CHAR(11) UNIQUE, id_cargo BIGINT UNSIGNED, data_admissao DATE, CONSTRAINT fk_func_cargo FOREIGN KEY (id_cargo) REFERENCES cargos(id_cargo) ) ENGINE=InnoDB;
Tabela usuarios

Gerenciamento de login

15min
Resumo: Gerencia o login no sistema. Implementa a regra CHECK que impede que um mesmo login seja simultaneamente funcionário e cliente.
CREATE TABLE IF NOT EXISTS usuarios ( id_usuario BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_funcionario BIGINT UNSIGNED UNIQUE, id_cliente BIGINT UNSIGNED UNIQUE, login VARCHAR(80) NOT NULL UNIQUE, senha_hash VARCHAR(255) NOT NULL, CONSTRAINT chk_usuario_vinculo CHECK (id_funcionario IS NULL OR id_cliente IS NULL) ) ENGINE=InnoDB;
12

P2 – Salões, Mesas e Canais de Venda

Projeto Prático: Operação local e mapeamento físico.

2 aulas
Tabela saloes

Espaços físicos

10min
Resumo: Mapeia os espaços físicos da lanchonete (ex.: 'Salão Principal', 'Varanda'). Permite segmentar relatórios de ocupação.
CREATE TABLE IF NOT EXISTS saloes ( id_salao BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(100) NOT NULL UNIQUE, ativo TINYINT(1) NOT NULL DEFAULT 1 ) ENGINE=InnoDB;
Tabela mesas

Controle de mesas

15min
Resumo: Representa as mesas físicas. Possui restrição de unicidade composta para garantir que não haja duas mesas com o mesmo número no mesmo salão.
CREATE TABLE IF NOT EXISTS mesas ( id_mesa BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_salao BIGINT UNSIGNED NOT NULL, identificacao VARCHAR(30) NOT NULL, status ENUM('LIVRE','OCUPADA','RESERVADA','INDISPONIVEL') NOT NULL DEFAULT 'LIVRE', UNIQUE KEY uk_mesa_salao (id_salao,identificacao) ) ENGINE=InnoDB;
13

P3 – Cardápio e Personalizações

Projeto Prático: Produtos, categorias e grupos de adicionais.

2 aulas
Tabela produtos

Catálogo de pratos e lanches

15min
Resumo: Catálogo de pratos e lanches vendidos. Possui fk_prod_categoria, controle de valor, tempo médio de preparo e flags para disponibilidade.
CREATE TABLE IF NOT EXISTS produtos ( id_produto BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_categoria BIGINT UNSIGNED, nome VARCHAR(150) NOT NULL, preco DECIMAL(12,2) NOT NULL DEFAULT 0, disponivel TINYINT(1) NOT NULL DEFAULT 1, CONSTRAINT fk_prod_categoria FOREIGN KEY (id_categoria) REFERENCES categorias_cardapio(id_categoria) ) ENGINE=InnoDB;
Tabela grupos_adicionais

Regras de customização

15min
Resumo: Regras de customização dos lanches. Define quantidades mínima e máxima e se o grupo é obrigatório.
CREATE TABLE IF NOT EXISTS grupos_adicionais ( id_grupo BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(100) NOT NULL, minimo SMALLINT UNSIGNED NOT NULL DEFAULT 0, maximo SMALLINT UNSIGNED NOT NULL DEFAULT 1, obrigatorio TINYINT(1) NOT NULL DEFAULT 0 ) ENGINE=InnoDB;
14

P4 – Pedidos de Venda

Projeto Prático: Coração transacional do negócio.

2 aulas
Tabela pedidos

Registro de vendas

20min
Resumo: Guarda número único do pedido, canal de venda, snapshots imutáveis do cliente/endereço, valores financeiros e status com máquina de estados refinada.
CREATE TABLE IF NOT EXISTS pedidos ( id_pedido BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, numero_pedido VARCHAR(30) NOT NULL UNIQUE, id_canal BIGINT UNSIGNED NOT NULL, status ENUM('RECEBIDO','CONFIRMADO','EM_PREPARO','PRONTO','ENTREGUE','CANCELADO') NOT NULL DEFAULT 'RECEBIDO', total DECIMAL(12,2) NOT NULL DEFAULT 0, recebido_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB;
Tabela pedido_itens

Linhas do pedido

15min
Resumo: Armazena o snapshot imutável do nome do produto e preço unitário histórico para que futuras alterações de cardápio não adulterem pedidos passados.
CREATE TABLE IF NOT EXISTS pedido_itens ( id_item BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_pedido BIGINT UNSIGNED NOT NULL, id_produto BIGINT UNSIGNED, nome_produto_snapshot VARCHAR(150) NOT NULL, quantidade DECIMAL(10,3) NOT NULL DEFAULT 1, preco_unitario DECIMAL(12,2) NOT NULL, CONSTRAINT fk_item_pedido FOREIGN KEY (id_pedido) REFERENCES pedidos(id_pedido) ON DELETE CASCADE ) ENGINE=InnoDB;
15

P5 – Produção, Cozinha e Despacho

Projeto Prático: KDS (Kitchen Display System) e logística de entregas.

2 aulas
Tabela producao_itens

Fila de produção em tempo real

15min
Resumo: Monitora entrada na fila, momento de início e conclusão por um cozinheiro, permitindo calcular o tempo de resposta da cozinha.
CREATE TABLE IF NOT EXISTS producao_itens ( id_producao BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_item BIGINT UNSIGNED NOT NULL, status ENUM('NA_FILA','EM_PREPARO','PRONTO','CANCELADO') NOT NULL DEFAULT 'NA_FILA', entrou_fila_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, pronto_em DATETIME ) ENGINE=InnoDB;
Tabela entregas

Logística de despacho

15min
Resumo: Rastreia atribuição ao motoboy, hora de saída, entrega concluída e taxa de frete.
CREATE TABLE IF NOT EXISTS entregas ( id_entrega BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_pedido BIGINT UNSIGNED NOT NULL UNIQUE, id_entregador BIGINT UNSIGNED, status ENUM('AGUARDANDO','EM_ROTA','ENTREGUE','FALHA') NOT NULL DEFAULT 'AGUARDANDO', saiu_em DATETIME, entregue_em DATETIME ) ENGINE=InnoDB;
16

P6 – Reservas e Fidelidade

Projeto Prático: CRM e retenção de clientes.

2 aulas
Tabela reservas

Agendamento prévio de mesas

15min
Resumo: Controla quantidade de pessoas, horário de início e término e status da reserva.
CREATE TABLE IF NOT EXISTS reservas ( id_reserva BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_cliente BIGINT UNSIGNED, nome_contato VARCHAR(150) NOT NULL, quantidade_pessoas SMALLINT UNSIGNED NOT NULL DEFAULT 1, inicio DATETIME NOT NULL, status ENUM('SOLICITADA','CONFIRMADA','ATENDIDA','CANCELADA') NOT NULL DEFAULT 'SOLICITADA' ) ENGINE=InnoDB;
Tabela fidelidade_clientes

Saldo de pontos

10min
Resumo: Saldo acumulado de pontos de fidelidade por cliente. Relação 1:1 estrita com a tabela de clientes.
CREATE TABLE IF NOT EXISTS fidelidade_clientes ( id_cliente BIGINT UNSIGNED PRIMARY KEY, pontos INT NOT NULL DEFAULT 0, CONSTRAINT fk_fid_cliente FOREIGN KEY (id_cliente) REFERENCES clientes(id_cliente) ) ENGINE=InnoDB;
17

P7 – Estoque, Ficha Técnica e Fornecedores

Projeto Prático: Suprimentos e controle de custos.

2 aulas
Tabela insumos

Matérias-primas e ingredientes

15min
Resumo: Mantém estoque atual, estoque mínimo para alerta de compra e custo médio unitário.
CREATE TABLE IF NOT EXISTS insumos ( id_insumo BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(150) NOT NULL, estoque_atual DECIMAL(12,3) NOT NULL DEFAULT 0, estoque_minimo DECIMAL(12,3) NOT NULL DEFAULT 0, custo_medio DECIMAL(12,4) NOT NULL DEFAULT 0 ) ENGINE=InnoDB;
Tabela fichas_tecnicas

Receita do produto

15min
Resumo: Cabeçalho da receita do produto para controle de custo e baixa automática de estoque.
CREATE TABLE IF NOT EXISTS fichas_tecnicas ( id_ficha BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_produto BIGINT UNSIGNED NOT NULL, versao INT UNSIGNED NOT NULL DEFAULT 1, UNIQUE KEY uk_ficha_versao (id_produto,versao) ) ENGINE=InnoDB;
18

P8 – Pagamentos, Caixa e Despesas

Projeto Prático: Gestão financeira e conciliação.

2 aulas
Tabela pagamentos

Lançamento de recebimentos

15min
Resumo: Permite múltiplos pagamentos para um mesmo pedido. Armazena referência externa do gateway/maquininha.
CREATE TABLE IF NOT EXISTS pagamentos ( id_pagamento BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_pedido BIGINT UNSIGNED NOT NULL, id_forma BIGINT UNSIGNED NOT NULL, valor DECIMAL(12,2) NOT NULL, status ENUM('PENDENTE','APROVADO','RECUSADO','ESTORNADO') NOT NULL DEFAULT 'PENDENTE', pago_em DATETIME ) ENGINE=InnoDB;
Tabela caixas

Turnos operacionais

15min
Resumo: Registra quem abriu e fechou o turno, saldo inicial (fundo de troco) e saldo final informado para conciliação bancária.
CREATE TABLE IF NOT EXISTS caixas ( id_caixa BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, aberto_por BIGINT UNSIGNED NOT NULL, aberto_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, saldo_inicial DECIMAL(12,2) NOT NULL DEFAULT 0, status ENUM('ABERTO','FECHADO') NOT NULL DEFAULT 'ABERTO' ) ENGINE=InnoDB;
19

P9 – Promoções e Auditoria

Projeto Prático: Controle de segurança e campanhas.

2 aulas
Tabela promocoes

Campanhas de marketing

15min
Resumo: Campanhas com vigência temporal estrita. Descontos configurados como PERCENTUAL ou VALOR_FIXO.
CREATE TABLE IF NOT EXISTS promocoes ( id_promocao BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(150) NOT NULL, tipo ENUM('PERCENTUAL','VALOR_FIXO') NOT NULL, valor DECIMAL(12,2) NOT NULL, inicio DATETIME NOT NULL, fim DATETIME NOT NULL ) ENGINE=InnoDB;
Tabela auditoria

Trilha forense de conformidade

15min
Resumo: Registra usuário, entidade/tabela afetada, ação executada, IP de origem e o diff (dados_anteriores vs. dados_novos).
CREATE TABLE IF NOT EXISTS auditoria ( id_auditoria BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_usuario BIGINT UNSIGNED, entidade VARCHAR(100) NOT NULL, acao ENUM('INSERT','UPDATE','DELETE','LOGIN','LOGOUT') NOT NULL, dados_anteriores LONGTEXT, dados_novos LONGTEXT, ocorrido_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB;
20

P10 – Views de Operação

Projeto Prático: Consultas otimizadas para dashboards.

2 aulas
View vw_pedidos_em_andamento

Monitor de expedição

15min
Resumo: Visão em tempo real de todos os pedidos ativos no estabelecimento (excluindo os já cancelados ou entregues).
CREATE OR REPLACE VIEW vw_pedidos_em_andamento AS SELECT p.id_pedido, p.numero_pedido, p.tipo_entrega, p.status, p.recebido_em, p.total FROM pedidos p WHERE p.status NOT IN ('ENTREGUE','CANCELADO');
View vw_fila_cozinha

Visão dedicada à cozinha (KDS)

15min
Resumo: Cruza itens de pedidos, produção e estações de preparo, filtrando estritamente os pratos 'NA_FILA' ou 'EM_PREPARO'.
CREATE OR REPLACE VIEW vw_fila_cozinha AS SELECT pr.id_producao, p.numero_pedido, pi.nome_produto_snapshot, pi.quantidade, ep.nome AS estacao, pr.status FROM producao_itens pr JOIN pedido_itens pi ON pi.id_item=pr.id_item JOIN pedidos p ON p.id_pedido=pi.id_pedido LEFT JOIN estacoes_producao ep ON ep.id_estacao=pr.id_estacao WHERE pr.status IN ('NA_FILA','EM_PREPARO');
21

P11 – Cadastros Básicos (Carga Inicial)

Projeto Prático: Seed de dados essenciais para o sistema.

2 aulas
Carga: Cargos, Perfis e Canais

Provisionamento padrão

15min
Resumo: Instrui o provisionamento padrão (seed) de cargos corporativos, perfis do sistema e canais de atendimento.
INSERT IGNORE INTO cargos (nome,descricao) VALUES ('Administrador','Gestão do sistema'), ('Gerente','Gestão da operação'), ('Atendente','Atendimento e registro de pedidos'), ('Cozinheiro','Preparo dos pedidos');
Carga: Permissões e Vínculo

Concessão global de acesso

15min
Resumo: Cadastra permissões granulares cobrindo todos os módulos do negócio e realiza a concessão global ao perfil de Administrador com CROSS JOIN.
INSERT IGNORE INTO perfil_permissoes (id_perfil,id_permissao) SELECT p.id_perfil,pe.id_permissao FROM perfis p CROSS JOIN permissoes pe WHERE p.nome='Administrador';
22

P12 – Projeto Final: Desafio Integrado End-to-End

Projeto Prático: Simulação de venda completa com transação atômica.

1 aulas
Desafio Integrado: Pedido, Pagamento e Baixa

Transação atômica completa

30min
Resumo: Simular em uma única transação atômica o ciclo de vida completo de uma venda: registrar o pedido, os itens, adicionais, o pagamento em dinheiro e disparar a movimentação contábil de saída dos insumos do estoque.
START TRANSACTION; -- 1. Criação do Pedido INSERT INTO pedidos (numero_pedido, id_canal, id_cliente, tipo_entrega, status, subtotal, total) VALUES ('PED-2024-9901', 2, 1, 'BALCAO', 'CONFIRMADO', 38.50, 38.50); SET @id_ped = LAST_INSERT_ID(); -- 2. Inserção do Item do Cardápio INSERT INTO pedido_itens (id_pedido, id_produto, nome_produto_snapshot, quantidade, preco_unitario, subtotal) VALUES (@id_ped, 1, 'X-Bacon Cheddar Duplo', 1.000, 38.50, 38.50); -- 3. Registro do Pagamento Integral INSERT INTO pagamentos (id_pedido, id_forma, valor, status, pago_em) VALUES (@id_ped, 2, 38.50, 'APROVADO', NOW()); -- 4. Baixa manual dos insumos consumidos INSERT INTO estoque_movimentacoes (id_insumo, tipo, quantidade, origem, id_origem, realizado_por, observacao) VALUES (1, 'SAIDA', 0.200, 'PEDIDO', @id_ped, 1, 'Consumo receita X-Bacon'); COMMIT;
🏆 Projeto Final

Projeto Final: Sistema de Gestão para Lanchonete

Aplique tudo o que aprendeu construindo um banco de dados relacional completo para uma lanchonete: tabelas de usuários, produtos, pedidos, pagamentos, estoque e entregas. Inclui views operacionais, carga inicial de dados e um desafio integrado de transação atômica (pedido, pagamento e baixa de estoque).

Acessar o projeto prático