1) O documento discute como visualizar dados de múltiplas tabelas relacionadas usando JOINs ou múltiplos queries. 2) Apresenta exemplos de listagem de dados mestre-detalhe entre tabelas de famílias e mariachis. 3) Discutem técnicas de paginação e navegação para listagens com muitos registros.
2. visualizar dados de várias tabelas
Quando queremos visualizar dados que estão distribuídos por duas
tabelas ligadas entre si, podemos:
• criar um query baseado num JOIN que permita obter todos os dados;
• criar vários recordsets de acordo com a informação necessária
A solução adequada depende da situação em que se aplica
4. listar os mariachis
$query = "SELECT idMariachi, nome FROM Mariachi";
$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){
echo $row_rsMari[“nome"];
}
5. listar os mariachis com família
$query = "SELECT Mariachi.idMariachi, Mariachi.nome,
Familia.nomeFamilia FROM Mariachi INNER JOIN Familia ON
Mariachi.Familia_idFamilia = Familia.idFamilia";
$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){
echo $row_rsMari[“nome"].” - “.
$row_rsMari[“nomeFamilia].”<br/>”;
}
6. listar os mariachis com família (not so good)
$query = "SELECT idMariachi, nome, Familia_idFamilia FROM
Mariachi";
$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){
$qFami = "SELECT nomeFamilia FROM Familia WHERE
idFamilia = ".$row_rsMari[“Familia_idFamilia”];
$rsFami = mysql_query($qFami , $connection);
$row_rsFami = mysql_fetch_assoc($rsFami);
echo $row_rsMari[“nome"].” - “.
$row_rsFami[“nomeFamilia].”<br/>”;
}
7. observações
uma página pode ter muitos recordsets
os valores obtidos num recordset podem ser utilizados para filtrar
resultados a obter noutro recordset
soluções com múltiplos acessos há BD são, normalmente, mais lentas
no entanto, existem circunstâncias em que a quantidade de informação
resultante de um INNER JOIN pode justificar a opção por múltiplos
queries!
8. master - detail
nesta estrutrura de informação temos:
• uma página inicial que lista vários tópicos de um modo genérico;
• uma página de detalhe que permite ver os detalhes do tópico escolhido na
página master
que informação é necessário transferir entre as páginas?
querystring: id_item
master .../page.php?a=5
detail
detalhes do item
item1 escolhido na página
master
item2
item3 voltar
10. exemplo: master > familias.php
$qFami = "SELECT * FROM Familia";
$rsFami = mysql_query($qFami , $connection);
while ($row_rsFami = mysql_fetch_assoc($rsFami)){
$line = ‘<p><a href=”mariachisFamilia.php?id=’.
$row_rsFami[“idFamilia”].
’”>’.
$row_rsFami[“nomeFamilia"].
‘</a></p>’;
echo $line;
}
os URLs na página serão, por exemplo: “mariachisFamilia.php?id=3”
11. exemplo: detail > mariachisFamilia.php
$idValue = intval($_GET['id']);
$qMari = "SELECT * FROM Mariachi
WHERE Familia_idFamilia = ".$idValue;
$rsMari = mysql_query($qMari , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){
$line = ‘<p>$row_rsMari[“nome”]</p>’;
echo $line;
}
Como mostrar nesta página o nome da família?
12. exemplo: master-detail (parte 2)
master: listar todas as famílias
detail: listar os mariachis dessa família
e incluir o número de relacionamentos com chicas
13. exemplo: master-detail (parte 2)
soluções a discutir:
• um query único baseado num INNER JOIN entre Mariachis e
Mariachi_has_chica com operação de COUNT e filtragem pelo Mariachi?
• um query para o nome do Mariachi e um query para contar o número de
registos do Mariachi em Mariachi_has_Chica?
14. exemplo: master-detail (parte 2)
problema com query único, típico destas situações:
• se um Mariachi não tiver uma ocorrência em Mariachi_has_Chica o
resultado será um recordset vazio! Porquê?
• não será possível mostrar os dados da informação pessoal do Mariachi
neste cenário, a solução a adotar deve ser a segunda!
ou ainda melhor... uma solução com OUTER JOIN
TPC -> implementar esta solução :)
15. exemplo: master-detail (parte 2)
por zonas condicionais entende-se partes do código que devem ser
processadas quando um recordset está ou não vazio
por exemplo:
• se o mariachi nunca teve relacionamentos apresentar uma mensagem
“este mariachi não é um bom exemplo!”
• nos outros casos mostrar os relacionamentos
como implementar este tipo de condição?
• if ($rsName) ...
16. navegação e paginação
imagina que uma família pode ter centenas de mariachis!
• faz sentido mostrar numa página uma listagem com um número ilimitado
de itens?
navegação - permite navegar nos itens, tipicamente:
• previous - next (page 3 of 6)
paginação - mais complexa e permite navegar diretamente para uma
página, tipicamente
• 1 ... 5 6 7 8 9 ... 20
17. navegação
o que é necessário saber
• número total de registos
• número de itens por página
• número da página atual
• registos para mostrar na página atual
18. navegação - número total de registos
recordset com query de COUNT de registos da tabela
19. navegação - número de itens por página
é um valor definido por nós e pode simplesmente ser guardado numa
variável
se o utilizador tiver a possibilidade de alterar então podemos necessitar
de uma cookie ou um parâmetro adicional na querystring
20. navegação - número da página atual
passado na querystring!
• next -> lê página atual e soma 1
• previous -> lê página atual e subtrai 1
• chama novamente a página com o novo id da página a visualizar
• é necessário ter em atenção as condições para não permitir clicar nas
opções quando não existem mais páginas para trás ou para a frente
• se não há valor da página deve assumir-se que é a primeira que deve ser
mostrada
• verificar valores que podem ser introduzidos manualmente no URL
21. navegação - registos para mostrar na página atual
NUNCA fazer uma query a pedir sempre todos os registos!
na query do pedido deve ser especificado o LIMIT (length e offset)
• SELECT .... LIMIT offset, length
• length é o valor do número de itens por página
• offset é calculado com base na página atual e o número de itens por
página
22. desafio
criar uma função genérica que adicione, em qualquer cenário, uma barra
de navegação!
• navigation_bar(nrTotalItens, nrItensPerPage,
pageNumber)
NOTA: a função não é responsável por mostrar os registos na página! Essa
lógica é da página e não da função.
DICA: para construir o URL ver chaves da super-variável _SERVER