Dúvida Noob modelagem de BD

20 respostas
Orocildo

Então pessoal, estou modelando uma tabela do campeonato brasileiro pra fins de estudo. Tenho uma tabela times, outra árbitros e precisava modelar uma tabela jogos que deve ser N*N.

Posso eu fazer essa tabela Jogos com chave primária composta tripla ? E ele fica sendo N*N assim mesmo ?

-id_time_de_casa(FK)
-id_time_de_fora(FK)
-id_arbitro(FK)

Tem alguma sugestão melhor de como modelar isso? A moral é que eu preciso fazer no exercício alguma coisa N*N nesse contexto do campeonato de futebol. Desculpem minha noobice :frowning:

Quem ajudar, agradeço :slight_smile:

20 Respostas

ErickRAR

Pode sim, mas não recomendo esse exemplo que você postou. Há chances de ter outro jogo com as mesmas condições(mesmos times e mesmo arbitro).
Acredito que colocar a data da partida não seja uma boa prática( não sei explicar porquê, apenas não acho legal), então crie uma tabela partida com id próprio e recebendo essas fk’s.

GTOJava

Orocildo:

Tem alguma sugestão melhor de como modelar isso? A moral é que eu preciso fazer no exercício alguma coisa N*N nesse contexto do campeonato de futebol. Desculpem minha noobice :frowning:

Quem ajudar, agradeço :)

Voce pode fazer uma sequencial para a tabela de jogos (sendo que possa haver um jogo com os mesmos times e arbitros), ficaria mais ou menos assim:

id_jogo (pk)
id_time_de_casa (fk)
id_time_de_fora (fk)
id_arbitro (fk)

Espero ter ajudado :wink:

drsmachado

GTOJava:
Orocildo:

Tem alguma sugestão melhor de como modelar isso? A moral é que eu preciso fazer no exercício alguma coisa N*N nesse contexto do campeonato de futebol. Desculpem minha noobice :frowning:

Quem ajudar, agradeço :)

Voce pode fazer uma sequencial para a tabela de jogos (sendo que possa haver um jogo com os mesmos times e arbitros), ficaria mais ou menos assim:

id_jogo (pk)
id_time_de_casa (fk)
id_time_de_fora (fk)
id_arbitro (fk)

Espero ter ajudado :wink:


++
O uso de PK composta só é recomendado quando:
Uma PK sequencial não pode ser utilizada e
Todas as colunas podem conter dados repetidos;
Tirando isto, eu nunca usaria PK composta.
A sugestão do GTOJava é a mais viável nesta circunstância.

JuniorMaia

eu criaria uma tabela normal, passando as chaves das outras tabelas, e colocaria um atributo data, ou então, uma tabela atributiva, onde teria todas as pk’s mais o atributo data

Orocildo

Mas essa implementação do GTOJava continua sendo N*N ?

E outra, tanto o clube de casa como de fora serão duas referências para o mesmo id da mesma tabela, a de clubes. Pode isso, sem problemas ?? Duas fks de uma mesma primary de uma mesma tabela ?

Se as duas repostas forem sim, fechou pra mim :slight_smile:

ErickRAR

Para a segunda pergunta, eu sei que sim. Não conheço nada de GTOJava para falar.

Essa será uma classe associativa. Normalmente, de muitos para muitos necessita de uma.

drsmachado

Camarada, desculpa aí, mas GTOJava é um outro forista do guj, que sugeriu uma forma de resolver o problema.
#RIALTO

ErickRAR

UAHAHU não tinha me ligado. :lol:

Enfim, o que ele disse está correto. Uma tabela com o id próprio e recebendo essas fk’s.

SpiderX

Camarada, desculpa aí, mas GTOJava é um outro forista do guj, que sugeriu uma forma de resolver o problema.
#RIALTO
+++++++

SpiderX

Mais engraçado seria se ele falasse que segundo as boas praticas do GTOjava isso não é permitido kkkkkkkkkkkkkkkkkkkk

Brincadeira cara, isso é normal, todo mundo erra !

Abraço.

GTOJava

ErickRAR:
Para a segunda pergunta, eu sei que sim. Não conheço nada de GTOJava para falar.

Primeiramente a questão é, o problema foi resolvido? , existem varias maneiras de fazer uma N*N , voce pode fazer com 1 pk, com 2 pk, com 3 pk,
independe também a quantidade de fk’s

Talvez voce possa especificar melhor o que deseja , então talvez resolveremos seu problema :wink:

Orocildo

Sendo N*N fecho pra mim GTOJava, obrigadão !

Agora meu desafio final é implementar o ranking atualizado do campeonato. Estava entre uma trigger que atualizasse uma tabela depois da atualização na jogos. Ou um view(acho bem melhor) que consultasse a tabela Jogos e mostrasse o ranking.

As tabelas que interessam (As fks vou colocar com alter depois no fim):

CREATE TABLE JOGOS (

id_jogo int not null,
id_clube_casa int not null,
id_clube_fora int not null,
gols_clube_casa int not null,
gols_clube_fora int not null,
vencedor int not null, – Aqui minha ideia seria o Id do vencedor, caso empate, seria null
id_arbitro int not null,
_data date not null,
rodada int no null,
CONSTRAINT PK_JOGOS PRIMARY KEY (id_jogo)

);

CREATE TABLE CLUBES(

id_clube int not null,
nome varchar(50) not null,
estadio int not null,
CONSTRAINT PK_CLUBES PRIMARY KEY (id_clube)

);

Então, alguém tem uma sugestão de implementação para criar um ranking ala Globo Esporte ?

Estava indo por esse caminho, criando uma view(colunas: colocação, nome do clube, pontuação, numero de jogos) :

CREATE VIEW RANKING AS SELECT …

GTOJava

Orocildo:
Sendo N*N fecho pra mim GTOJava, obrigadão !

Agora meu desafio final é implementar o ranking atualizado do campeonato. Estava entre uma trigger que atualizasse uma tabela depois da atualização na jogos. Ou um view(acho bem melhor) que consultasse a tabela Jogos e mostrasse o ranking.

As tabelas que interessam (As fks vou colocar com alter depois no fim):

CREATE TABLE JOGOS (

id_jogo int not null,
id_clube_casa int not null,
id_clube_fora int not null,
gols_clube_casa int not null,
gols_clube_fora int not null,
vencedor int not null, – Aqui minha ideia seria o Id do vencedor, caso empate, seria null
id_arbitro int not null,
_data date not null,
rodada int no null,
CONSTRAINT PK_JOGOS PRIMARY KEY (id_jogo)

);

CREATE TABLE CLUBES(

id_clube int not null,
nome varchar(50) not null,
estadio int not null,
CONSTRAINT PK_CLUBES PRIMARY KEY (id_clube)

);

Então, alguém tem uma sugestão de implementação para criar um ranking ala Globo Esporte ?

Estava indo por esse caminho, criando uma view(colunas: colocação, nome do clube, pontuação, numero de jogos) :

CREATE VIEW RANKING AS SELECT …

Cara, com uma view funcionará perfeitamente bem , o select é simples e sem muitas ligações (2 tabelas)
Apenas aconselho fazer uma ligação com o “join” e não direto no “where” , com a minha experiencia em banco de dados já comprovei que o join é mais rápido e funcional (não é atoa que existe)
Falo isso porque vejo muita gente fazendo ligação direto no “where” entre as tabelas, dependendo do caso isso não irá influenciar, mas é sempre bom adotar uma boa prática para (expansão por exemplo)

No seu caso eu faria assim :

SELECT JOGOS.(CAMPOS)...,
            CLUBCASA .(CAMPOS)...,
            CLUBFORA .(CAMPOS)...
FROM  JOGOS
JOIN CLUBES AS CLUBCASA ON (CLUBCASA.ID_CLUBE = JOGOS.ID_CLUBE_CASA)
JOIN CLUBES AS CLUBFORA ON (CLUBFORA.ID_CLUBE = JOGOS.ID_CLUBE_FORA)
WHERE ("Aqui voce irá fazer o tratamento que voce querer (que nao seja ligação de tabelas"))
ORDER "creio que para um ranking voce ira precisar de um order"

Mas man, é mais ou menos isso, basta implementar o que voce deseja.

Qualquer duvida posta ai

Orocildo

Hum. Entendi… Mas o “punk” mesmo onde estou parado é como vou implementar a pontuação. De que maneira vou modelar a tabela Jogos e construir a query da view.

Uma alternativa que cheguei e funcionaria seria dado o resultado da partida eu registrava(usando uma trigger) em outra tabela “Auxiliar Resultado”, a pontuação que cada um adquiriu naquele jogo, tipo:

Dado o jogo : SP 1 x 1 Palmeiras. Faz de conta que SP tem id 7 e Palmeiras 17.
Dado o jogo : Inter 1 x 0 Grêmio. Faz de conta que Inter tem id 2 e Grêmio 14.

A trigger gravava na tabela:

id_clube | pontos
7 1
17 1
2 3
14 0

Aí sim, ficava um docinho de coco, só fazer um SUM() agrupando pelo id_clube e tava resolvida o problema da pontuação. Agora fazendo uma view diretos na tabela Jogos “me quebrou as pernas”, pois não saberia como implementar dessa maneira a pontuação.

raphael.ricci

Uma idéia seria criar uma trigger mesmo, seria mais fácil depois para que você obtenha um ranking. Ou então você pode fazer um campo pontuação dentro da tabela, mas isso não seria legal.

GTOJava
Orocildo:
Hum. Entendi... Mas o "punk" mesmo onde estou parado é como vou implementar a pontuação. De que maneira vou modelar a tabela Jogos e construir a query da view.

Uma alternativa que cheguei e funcionaria seria dado o resultado da partida eu registrava(usando uma trigger) em outra tabela "Auxiliar Resultado", a pontuação que cada um adquiriu naquele jogo, tipo:

Dado o jogo : SP 1 x 1 Palmeiras. Faz de conta que SP tem id 7 e Palmeiras 17.
Dado o jogo : Inter 1 x 0 Grêmio. Faz de conta que Inter tem id 2 e Grêmio 14.

A trigger gravava na tabela:

id_clube | pontos
7 1
17 1
2 3
14 0

Aí sim, ficava um docinho de coco, só fazer um SUM() agrupando pelo id_clube e tava resolvida o problema da pontuação. Agora fazendo uma view diretos na tabela Jogos "me quebrou as pernas", pois não saberia como implementar dessa maneira a pontuação.

Creio entao, que voce deveria ter uma tabela que fazia a "pontuação de cada time"
Se voce não quiser fazer isso, teria que modelar a tabela JOGOS de uma maneira um pouco diferente (que inclua o ponto obtidos no jogo )

raphael.ricci:
Uma idéia seria criar uma trigger mesmo, seria mais fácil depois para que você obtenha um ranking. Ou então você pode fazer um campo pontuação dentro da tabela, mas isso não seria legal.

Não acho que seja legal, acho que seja viavel e estremamente util, e nao prejudicaria em nada o desempenho

Isto facilitaria a sua criação da view, e faria o calculo no proprio select

Ex:
-- TABELAS

CREATE TABLE JOGOS ( 

id_jogo int not null, 
id_clube_casa int not null, 
id_clube_fora int not null, 
gols_clube_casa int not null, 
gols_clube_fora int not null, 
id_vencedor int not null, -- FK PARA CLUBES 
id_arbitro int not null, -- FK PARA ARBITRO
_data date not null, 
rodada int no null, 
pontos_jogo    -- criei este novo campo    
CONSTRAINT PK_JOGOS PRIMARY KEY (id_jogo) 

); 

CREATE TABLE CLUBES( 
id_clube int not null, 
nome varchar(50) not null, 
estadio int not null, 
CONSTRAINT PK_CLUBES PRIMARY KEY (id_clube) 
); 


-- SELECT DA VIEW

SELECT JOGOS.I_VENCEDOR,
	   VENCEDOR.NOME,
	   SUM(JOGOS.PONTOS_JOGO) AS TOTALPONTOS,
FROM  JOGOS  
JOIN CLUBES AS CLUBCASA ON (CLUBCASA.ID_CLUBE = JOGOS.ID_CLUBE_CASA)  
JOIN CLUBES AS CLUBFORA ON (CLUBFORA.ID_CLUBE = JOGOS.ID_CLUBE_FORA)  
JOIN CLUBES AS VENCEDOR ON (VENCEDOR.ID_CLUBE = JOGOS.ID_VENCEDOR)  
group by JOGOS.I_VENCEDOR,
	   VENCEDOR.NOME
order by TOTALPONTOS

Uma coisa assim talvez Orocildo?

GTOJava

Faltou trazer os que não venceram nada , sorry.

Mas a lógica segue no mesmo caminho.

Orocildo

Boa! Agora sim, chegou bastante perto mesmo, bem isso… Só uma duvida, com esse cruzamento de várias tabelas que tu faz ele vai somar os pontos independente se o time está em casa ou fora, a contagem será unificada, correto ? (Pelo que entendi, só para confirmar)

E outra, o empate funcionará ? Ele não vai somar duas vezes 1 ponto caso se tenha empate ?

Desculpa pelas perguntas nbs, é que estou montando o código só no txt, só mais tarde em casa que vou testar. Mas pelo entendi é 99% praticamente isso.

GTOJava

Orocildo:
Boa! Agora sim, chegou bastante perto mesmo, bem isso… Só uma duvida, com esse cruzamento de várias tabelas que tu faz ele vai somar os pontos independente se o time está em casa ou fora, a contagem será unificada, correto ? (Pelo que entendi, só para confirmar)

E outra, o empate funcionará ? Ele não vai somar duas vezes 1 ponto caso se tenha empate ?

Desculpa pelas perguntas nbs, é que estou montando o código só no txt, só mais tarde em casa que vou testar. Mas pelo entendi é 99% praticamente isso.

Desculpa também não estar especificando corretamente, é que também to no txt

Funciona assim:
O select ira somar os pontos dos vencedores.

No caso do empate , eu modificaria a tabela, porque só 1 id_vencedor não irá dar certo,
voce pode ter então 2 id_vencedor que aceitam nulo, assim se tiver 1 vencedor pelo menos o teu select funcionara perfeitamente bem

Man, espero que voce tenha entendido o esquema. To indo pra casa,

Amanha tem mais

Orocildo

Obrigado pela tua disposição em ajudar cara, muito obrigado mesmo! Quando bater o martelo quanto a implementação te dou um “feed”, por aqui.

Abraço!

Criado 18 de junho de 2012
Ultima resposta 19 de jun. de 2012
Respostas 20
Participantes 7