Este documento fornece um resumo de uma palestra sobre boas práticas de SQL em bancos de dados relacionais para desenvolvedores. A palestra inclui tópicos como projeção, chaves, junções, views, triggers, bind variables, padrões ANSI e um exemplo real utilizando JPA. O palestrante tem mais de 18 anos de experiência em TIC e atua como DBA há 10 anos principalmente em projetos Java.
Boas Práticas de SQL em Banco Relacional para Devs
1. Globalcode – Open4education
Fernando Franquini - Capin
Profissional da área de TIC a mais de 18 anos, atuando a mais de 10 anos
como DBA em projetos de desenvolvimento de Software principalmente
com JAVA.
Boas Práticas de SQL em Banco
Relacional para Devs
3. Globalcode – Open4education
Apresentação
Quem sou?
Quem vocês são?
Já criou e executou instrução SQL direto no BD
Já analisou instrução SQL enviada ao BD
Nunca viu SQL!
Agora: Que diabos faz um DBA em uma trilha de
JAVA?
5. Globalcode – Open4education
Projeção
/* select
t
from
Team t */
select
team0_.id as id1_11_,
team0_.arena as arena2_11_,
team0_.city as city3_11_,
team0_.creationYear as creation4_11_,
team0_.division_id as division8_11_,
team0_.logo as logo5_11_,
team0_.name as name6_11_,
team0_.version as version7_11_
from
teams team0_
6. Globalcode – Open4education
Chaves
Chave candidatas
Ex.: CPF e CNPJ
Chaves compostas
Alguns impactos nos frameworks:
Se forem EAGER é um CAOS (balde de Siri)
Em alguns casos mesmo sendo LAZY podem gerar problemas
Índices do tipo Texto
7. Globalcode – Open4education
Chaves
/* select g
from Game g
where g.dateLegacy = '2016-04-13' */
select
game0_.id as id1_5_,
game0_.arena_name as arena_na9_5_,
game0_.arena_location as arena_l10_5_,
game0_.awayPoints as awayPoin2_5_, game0_.awayTeam_id as
awayTea11_5_, game0_.date as date3_5_, game0_.dateLegacy as
dateLega4_5_, game0_.homePoints as homePoin5_5_,
game0_.homeTeam_id as homeTea12_5_, game0_.time as time6_5_,
game0_.timeLegacy as timeLega7_5_, game0_.version as version8_5_
from games game0_
where game0_.dateLegacy='2016-04-13'
12. Globalcode – Open4education
Bind Variables
Mesma instrução executada N vezes
Problema:
SQL dinâmicos (montados em código)
Ex.:
‘Select * from Pais where Nome = ‘ + ‘Brasil’
Ex.:
‘Select * from Pais where Nome = ‘ :1
Using : ‘Brasil’
Segurança contra SQL INJECTION
13. Globalcode – Open4education
Bind Variables
/* select g
from Game g
where g.date = :date
order by g.time */
SELECT Game0_.Id AS Id1_5_, Game0_.Arena_Name AS Arena_Na9_5_,
Game0_.Arena_Location AS Arena_L10_5_, Game0_.Awaypoints AS
Awaypoin2_5_,
Game0_.Awayteam_Id AS Awaytea11_5_, Game0_.Date AS Date3_5_,
Game0_.Datelegacy AS Datelega4_5_, Game0_.Homepoints AS
Homepoin5_5_,
Game0_.Hometeam_Id AS Hometea12_5_, Game0_.Time AS Time6_5_,
Game0_.Timelegacy AS Timelega7_5_, Game0_.Version AS
Version8_5_
FROM Games Game0_
WHERE Game0_.Date = ?
ORDER BY Game0_.Time
14. Globalcode – Open4education
ANSI
Funções que são múltiplos Banco de Dados:
CASE
COALESCE
CAST para conversões de tipos de dados
Melhor portabilidade de Banco de Dados
Usem Dialeto do JAVA
15. Globalcode – Open4education
ANSI
/* select
distinct e.playerContract,
coalesce(
( select sum(ev.value)
from GameEvent ev
where ev.playerContract = e.playerContract
and ev.eventType =
org.nba.model.GameEventType.POINTS_MADE),
0)
from
GameEvent e */
Continuação…
16. Globalcode – Open4education
ANSI
SELECT DISTINCT Gameevent0_.Playercontract_Id AS Col_0_0_,
Coalesce((SELECT SUM(Gameevent2_.Value)
FROM Game_Events Gameevent2_, Player_Contracts Playercont3_
WHERE Gameevent2_.Playercontract_Id = Playercont3_.Id
AND Gameevent2_.Playercontract_Id =
Gameevent0_.Playercontract_Id
AND Gameevent2_.Eventtype = 5), 0) AS Col_1_0_,
Playercont1_.Id AS Id1_6_, Playercont1_.Finishdate AS
Finishda2_6_, Playercont1_.Player_Id AS Player_I5_6_,
Playercont1_.Startdate AS Startdat3_6_, Playercont1_.Team_Id AS
Team_Id6_6_, Playercont1_.Version AS Version4_6_
FROM Game_Events Gameevent0_
INNER JOIN Player_Contracts Playercont1_
ON Gameevent0_.Playercontract_Id = Playercont1_.Id
17. Globalcode – Open4education
Função ‘ANSI’ #SQN
/* select FUNCTION('DATE_FORMAT', b.date, '%d/%m/%Y'),
b.awayTeamName,
b.awayPoints,
b.homePoints,
b.homeTeamName
from
BoxScore b */
SELECT Date_Format(Boxscore0_.Date, '%d/%m/%Y') as Col_0_0_,
Boxscore0_.Awayteamname AS Col_1_0_,
Boxscore0_.Awaypoints AS Col_2_0_,
Boxscore0_.Homepoints AS Col_3_0_,
Boxscore0_.Hometeamname AS Col_4_0_
FROM Boxscoreview Boxscore0_
19. Globalcode – Open4education
Exemplo Real
...
Tabela2: idGlobalTabela2, idTabela2, nmTabela2
@OneToMany(fetch=FetchType.LAZY, mappedBy="tabela2")
collection<TabelaDeLigacao> registros;
....
-- Retornar todos os registros da "Tabela2" inseridos na "TabelaDeLigacao"
-- Entrada: idGlobalTabela1 e idTabela1
-- Selecionar em Tabela2
-- Fazer join em TabelaDeLigacao
-- Adicionar as condições idGlobalTabela1=x e idTabela1=y
Continuação...
24. Globalcode – Open4education
Exemplo Real
SELECT Tabela2.Idglobaltabela2, Tabela2.Idtabela2,
Tabela2.Nmtabela2
FROM Exxx_Tabela2 Tabela2
INNER JOIN Exxx_Tabela_De_Ligacao Tabeladeligacao
ON Tabela2.Id_Tabela2 = Tabeladeligacao.Id_Tabela2
AND Tabela2.Id_Global_Tabela2 =
Tabeladeligacao.Id_Global_Tabela2
WHERE Tabeladeligacao.Cd_Sistema_Entidade = Valoridglocaltabela
AND Tabeladeligacao.Cd_Entidade = Valoridtabela2
ORDER BY Tabela2.Nmtabela2 ASC;
25. Globalcode – Open4education
Encerramento
Twitter: @capin79
LinkedIn: https://br.linkedin.com/in/capin
fernando.franquini@gmail.com
Scripts para base de testes está no Github:
https://github.com/vinnyvoffice/tdcfloripa2016
26. Globalcode – Open4education
Encerramento
Muito Obrigado!
Twitter: @capin79
LinkedIn: https://br.linkedin.com/in/capin
fernando.franquini@gmail.com
Dúvidas?
Agradecimento Especial ao Vinny pelo apoio
incansável dos exemplos com JPA!