SQL
Tipos de bancos
- NoSQL: Cassandra, Redis, FaunaDB
- SQL: MySQL, Postgres, MariaDB
- GraphOriented: NEO4J
Modelagem
- Entidade Relacionamento (ER)
- Cardinalidade
- Você deve pegar sempre a cardinalidade máxima para criar o modelo físico
::card{icon="mdi:code-json"} #title DDL - Linguagem de Definição de Dados #description É o grupo de comandos dentro da linguagem SQL utilizado para a criação, modificação e remoção de objetos de banco de dados. ::
Basic Query
CREATE
CREATE TABLE Cliente
(
Nome VARCHAR(50) NOT NULL,
CPF VARCHAR(11) PRIMARY KEY NOT NULL,
DataNascimento Date NOT NULL,
IdEndereco INT
);ALTER
Permite modificar a estrutura de uma tabela de banco de dados.
ALTER TABLE `vendas` ADD CONSTRAINT
`fk_vendas_codcliente` FOREIGN KEY (`codcliente`)
REFERENCES `clientes` (`codcliente`) ;DROP
Apaga um objeto do banco de dados
DROP TABLE name_table::card{icon="mdi:code-json"} #title DML - Linguagem de Manipulação de Dados #description É o grupo de comandos dentro da linguagem SQL utilizado para a recuperação, inclusão, remoção e modificação de informações em bancos de dados. ::
INSERT
insert into Especialidade(cod_espec,espec)
values (100, 'Pediatria');UPDATE
update Cliente
set Cidade = 'Sarandi'
where nome = 'Lucas'DELETE
DELETE from Cliente WHERE nome = 'Lucas'ALTER
ALTER TABLE Clientes DROP COLUMN Rua;SELECT
SELECT codCliente, nome, rua, cidade From cliente
Where cidade = "Porto Alegre"Operadores
NOT NULL
Garante que uma coluna não possa receber o valor NULL.
CREATE TABLE Estudante (
Id integer NOT NULL,
Nome varchar(45) NOT NULL,
Turma varchar(10)
);DEFAULT
Atribui um valor padrão quando nenhum valor é especificado.
CREATE TABLE Estudante (
Id integer Unique,
Nome varchar (30),
Turma varchar (30),
Média DEFAULT 70
);UNIQUE
Garante que todos os valores numa coluna sejam diferentes.
CREATE TABLE Estudante (
Id integer UNIQUE,
Nome varchar (30),
Turma varchar (30)
);CHECK
Garante que todos os valores numa coluna satisfaçam um determinado critério.
CREATE TABLE Estudante (
Id integer CHECK (Id > 0),
Nome varchar (30),
Turma varchar (30),
Média DEFAULT 70
);AUTO INCREMENT
Auto incrementa o valor de uma coluna.
CREATE TABLE Clientes (
idcliente int NOT NULL AUTO_INCREMENT,
nome varchar(255) NOT NULL,
);SEQUENCE
Sequence é um objeto que gera uma sequência de números. É muito útil para gerar valores únicos para uma coluna.
CREATE SEQUENCE cod_seq
MINVALUE 1 MAXVALUE 1000
INCREMENT BY 1 START WITH 1;
-- How to use this
INSERT INTO Estudante (ID, NOME)
VALUES (cod_seq.nextval, 'jose');DISTINCT
Faz com que o resultado da consulta não tenha valores repetidos.
SELECT DISTINCT cod_med
FROM consulta
WHERE cod_pac = 100Funções de agregação
Operam sobre um conjunto de tuplas úteis na determinação de alguns cálculos matemáticos na consulta.
COUNT
Contador de ocorrências. Não conta valores nulos. Ex: obter o total de tuplas da tabela de pacientes.
SELECT count(*) FROM pacienteSUM
Função de somar valores de atributos numéricos.
SELECT Sum(salario)
FROM funcionario
WHERE setor = 'b'AVG
Média de valores de atributos numéricos
SELECT avg(idade) FROM medico;GROUP BY
Agrupa parte do result de uma query, da qual da pra usar funções de agregação. Ex: buscar o código dos médicos e o total de consultas para cada médico
SELECT cod_med, count(*)
FROM consulta
GROUP BY cod_medHAVING
O having é usado para filtrar o resultado de uma consulta agrupada.
SELECT cod_med, COUNT(data_hora)
FROM consulta
GROUP BY cod_med
HAVING COUNT(*) > 5STRING E CHAR
::card{icon="mdi:code-json"} #title LIKE: Permite a definição de padrões de busca #description LIKE ‘c%’: o valor do atributo inicia com o caracter ou string c. :br LIKE ‘%c’: o valor do atributo termina com o caracter ou string c. :br LIKE ‘%c%’: o valor do atributo possui o caracter ou string c no meio da cadeia. ::
SELECT nome
FROM paciente
WHERE nome LIKE 'C%'DATE E DATETIME
- DATE: YYYY-MM-DD
SELECT * FROM Orders WHERE OrderDate='2008-11-11'- DATETIME: YYYY-MM-DD HH:MI:SS
SELECT * FROM Orders WHERE OrderDate='2008-11-11 12:10:20'- TIMESTAMP: YYYY-MM-DD HH:MI:SS
- YEAR: YYYY or YY
- EXTRACT: estrair partes de uma data ou datetime.
SELECT EXTRACT(DAY FROM data) from table_name;
SELECT EXTRACT(MONTH FROM data) from table_name;
SELECT EXTRACT(YEAR FROM data) from table_name;
SELECT EXTRACT(HOUR FROM data) from table_name;INNER JOIN
Table A Table B
id name id name
-- ---- -- ----
1 Pirate 1 Rutabaga
2 Monkey 2 Pirate
3 Ninja 3 Darth Vader
4 Spaghetti 4 NinjaJuntar duas ou mais tabelas por chaves correspondentes.
LEFT JOIN
permite obter não apenas os dados relacionados de duas tabelas, mas também os dados não relacionados encontrados na tabela à esquerda da cláusula JOIN.
LEFT OUTER JOIN
Produz um conjunto completo de registros da Tabela A, com os registros correspondentes (quando disponíveis) na Tabela B. Se não houver correspondência, o lado direito conterá nulo.
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
-- result
id name id name
1 Pirate 2 Pirate
2 Monkey null null
3 Ninja 4 Ninja
4 Spaghetti null null
--------------------------------
-- Sem valores ta tabela B
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableB.id IS null
-- result
id name id name
2 Monkey null null
4 Spaghetti null nullRIGHT JOIN
Ao contrário do LEFT JOIN, a cláusula RIGHT JOIN retorna todos os dados encontrados na tabela à direita de JOIN.
FULL JOIN
Juntar o poder das junções (Join) internas (Inner), a listagem de todas as outras linhas não associadas, tanto do lado direito (Right) da junção como do lado esquerdo (Left). Não é suportado pelo Mysql.
FULL OUTER JOIN
Produz o conjunto de todos os registros na Tabela A e na Tabela B, com registros correspondentes de ambos os lados, quando disponíveis. Se não houver correspondência, o lado ausente conterá null.
SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
-- result
id name id name
1 Pirate 2 Pirate
2 Monkey null null
3 Ninja 4 Ninja
4 Spaghetti null null
null null 1 Rutabaga
null null 3 Darth VaderSEMI JOIN
São joins que retornam linhas de uma tabela A baseado na existência de linhas correlacionadas em uma tabela B. Se a consulta retorna apenas atributos (campos) da tabela da esquerda, então o join é chamado de Left Semi Join; se retorna apenas atributos da tabela da direita, então é chamado de Right Semi Join. Um semi join pode ser produzido usando INNER JOINS, EXISTS, IN e também com o INTERSECT.*
-- recuperar todos os clientes que já realizaram compras na empresa com IN
SELECT
c.ClienteID,
c.Nome,
c.Sobrenome
FROM
dbo.Clientes c
WHERE
c.ClienteID IN (
SELECT
v.ClienteID
FROM
dbo.Vendas v
)
-- recuperar todos os clientes que já realizaram compras na empresa com EXISTS
SELECT
c.ClienteID,
c.Nome,
c.Sobrenome
FROM
dbo.Clientes c
WHERE
EXISTS (
SELECT
1
FROM
dbo.Vendas v
WHERE
v.ClienteID = c.ClienteID
)ANTI-SEMI JOIN
Ocorre quando linhas em uma tabela A não possuem correspondentes em uma tabela B (é baseado na não-existência). É possível alcançar um anti-semi join através de subconsultas utilizando NOT IN ou EXISTS, ou ainda através do operador EXCEPT. Também é possível alcançar um anti-semi join utilizando outer join, filtrando somente as outer rows.
-- 1) Usando NOT IN
SELECT
c.ClienteID,
c.Nome,
c.Sobrenome
FROM
dbo.Clientes c
WHERE
c.ClienteID NOT IN (
SELECT
v.ClienteID
FROM
dbo.Vendas v
)
-- 2) Usando NOT EXISTS
SELECT
c.ClienteID,
c.Nome,
c.Sobrenome
FROM
dbo.Clientes c
WHERE
NOT EXISTS (
SELECT
1
FROM
dbo.Vendas v
WHERE
v.ClienteID = c.ClienteID
)SQL Query Optimization
- N+1 Problem tweet (opens in a new tab)
- N+1 Problem Stackoverflow (opens in a new tab)
- Fast and maintainable patterns for fetching from a database (opens in a new tab)
- Prisma Query Optimization (opens in a new tab)
SQL Injection
SQL Injection é a vulnerabilidade mais encontrada em aplicações Web, que permite a um usuário mal-intencionado invadir bancos de dados associados a páginas Web explorando falhas de programação.
Num perfil de ataque SQL Injection, o usuário mal-intencionado irá explorar as falhas da aplicação (provenientes de uma cláusula SQL sem tratamento de dados) para conseguir acesso ao sistema, procurando inserir valores que sejam sempre verdadeiros para o sistema.
select * from tabela_Usuarios where campo_email = '' OR 1=1;
'/*' and campo_senha = '/*--';Essa entrada de dados pelo usuário configura um caso de SQL Injection, pois mesmo os valores sendo incoerentes para conceder acesso a aplicação Web, quando o sistema for executado retornará sempre verdadeiro. O ataque ocorre devido aos caracteres especiais “ /* ” e “--” e também pela condição sempre verdadeira de “1 = 1”. Nesse caso os caracteres especiais serão interpretados como comentários de código para a linguagem SQL, anulando, portanto, o código após os caracteres especiais e verificando apenas a condição “1=1”, que sempre retornará verdadeiro, permitindo ao usuário acessar a aplicação sem saber o e-mail e senha corretos.
Em um caso mais grave, o usuário mal-intencionado pode já saber algumas informações do banco de dados, como nome de tabelas e colunas, para formular uma cláusula SQL Injection mais elaborada. O usuário mal-intencionado executa o comando da própria linguagem SQL “DROP TABLE senha”, onde excluirá qualquer tabela especificada. Também é possível alterar, adicionar e retornar dados já armazenado no banco de dados.
select * from tabela_Usuarios where campo_email = '123';
DROP TABLE senha; '/*' and campo_senha = '/*--';