TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

26
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

Transcript of TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Page 1: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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

Page 2: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Agenda

Apresentação

Projeção

Chaves

Joins

Views e Triggers

Bind Variables

ANSI

Exemplo Real

Page 3: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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?

Page 4: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Projeção

Todos sabem o que é a Projeção do SQL?

Conteúdo da Projeção

Sub Select na Projeção

Função na Projeção

Page 5: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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_

Page 6: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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

Page 7: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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'

Page 8: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Chaves e Joins

Chaves Primárias

Texto

Decimal

Junções (Chaves estrangeiras)

Indexação da junção

Page 9: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Chaves e Joins

Recente:

@Entity

@Table(name = "teams", indexes={

@Index(name="TEAM_CITY_NAME_INDEX", unique=true,

columnList="CITY,NAME"),

@Index(name="TEAM_ID_NAME_INDEX", unique=true,

columnList="ID,NAME"),

@Index(name="TEAM_DIVISION_NAME_INDEX", unique=true,

columnList="DIVISION_ID,NAME")

})

public class Team implements Serializable {...

Page 10: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Chaves e Joins

Hibernate:

alter table teams add constraint

TEAM_CITY_NAME_INDEX unique (city, name)

Hibernate:

alter table teams add constraint

TEAM_ID_NAME_INDEX unique (arena)

Hibernate:

alter table teams add constraint

TEAM_DIVISION_NAME_INDEX unique (division_id,

name)

Page 11: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Views e Triggers

Views

Para que servem?

Quando viram um problema?

Triggers

Como nascem?

Como lembramos?

Page 12: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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

Page 13: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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

Page 14: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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

Page 15: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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…

Page 16: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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

Page 17: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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_

Page 18: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Exemplo Real

Tabela1: idGlobalTabela1, idTabela1, ...

TabelaDeLigacao: idGlobalTabela1, idTabela1, idGlobalTabela2,

idTabela2

@ManyToOne(fetch=FetchType.LAZY)

@JoinColumns({

@JoinColumn(name="idGlobalTabela2", insertable=false,

updatable=false),

@JoinColumn(name="idTabela2", insertable=false,

updatable=false) })

Tabela2 tabela2;

Continuação...

Page 19: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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...

Page 20: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Exemplo Real

CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();

CriteriaQuery<Tabela2> criteriaQuery =

criteriaBuilder.createQuery(Tabela2.class);

Root<Tabela2> root = criteriaQuery.from(Tabela2.class);

Join<Tabela2, TabelaDeLigacao> join = root.join(Tabela2_.registros);

List<Predicate> predicates = new ArrayList<>();

predicates.add(criteriaBuilder.equal(join.get(TabelaDeLigacao_.tabel

aDeLigacaoPK).get(TabelaDeLigacaoPK_.idGlobalTabela1),

valorIdGlocalTabela ));

Continuação...

Page 21: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Exemplo Real

predicates.add(criteriaBuilder.equal(join.get(TabelaDeLigacao_.t

abelaDeLigacaoPK).get(TabelaDeLigacaoPK_.idTabela1),

valorIdTabela2));

criteriaQuery.select(root);

criteriaQuery.where(criteriaBuilder.and(predicates.toArray(new

Predicate[]{})));

criteriaQuery.orderBy(criteriaBuilder.asc(join.get(TabelaDeLigac

ao_.tabela2).get(Tabela2_.nmTabela2)));

TypedQuery<Tabela2> typedQuery =

entityManager.createQuery(criteriaQuery);

List<Tabela2> resultado = typedQuery.getResultList();

Continuação...

Page 22: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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

CROSS JOIN Exxx_Tabela2 Tabela2_2

WHERE Tabeladeligacao.Id_Tabela2 = Tabela2_2.Id_Tabela2

AND Tabeladeligacao.Id_Global_Tabela2 = Tabela2_2.Id_Global_Tabela2

AND Tabeladeligacao.Id_Global_Tabela1 = Valoridglocaltabela

AND Tabeladeligacao.Id_Tabela1 = Valoridtabela2

ORDER BY Tabela2_2.nmTabela2 ASC;

Continuação...

Page 23: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Exemplo Real

Erro:

criteriaQuery.orderBy(criteriaBuilder.asc(join.get(TabelaDeLigac

ao_.tabela2).get(Tabela2_.nmTabela2)));

Correção:

criteriaQuery.orderBy(criteriaBuilder.asc(root.get(Tabela2_.nmTa

bela2)));

Continuação ...

Page 24: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

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;

Page 25: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Encerramento

Twitter: @capin79

LinkedIn: https://br.linkedin.com/in/capin

[email protected]

Scripts para base de testes está no Github:

https://github.com/vinnyvoffice/tdcfloripa2016

Page 26: TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores

Globalcode – Open4education

Encerramento

Muito Obrigado!

Twitter: @capin79

LinkedIn: https://br.linkedin.com/in/capin

[email protected]

Dúvidas?

Agradecimento Especial ao Vinny pelo apoio

incansável dos exemplos com JPA!