Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Salve pessoal,
Fui responder a duvida de um colega, e me apareceu outra duvida...
Caso eu tenha um banco de dados relacional tradicional, Ex:
create database loja_imaster;
use loja_imaster;
CREATE TABLE fornecedor(
id int(8) primary key auto_increment
,nome varchar(50)
);
INSERT INTO fornecedor (nome) values ('Intel'), ('Amd');
CREATE TABLE produtos(
id int(8) primary key auto_increment
,nome varchar(50)
,valor decimal(5,2)
,fornecedor_id int (8)
);
INSERT INTO produtos (nome, valor, fornecedor_id) values
('AMD 29030' , 78.18, 2)
,('Athlon' , 500.30, 2)
,('Phenom FX' , 542.82, 2)
,('Phenom X4' , 210.50, 2)
,('Phenom X2' , 111.18, 2)
,('Pentium 4' , 540.18, 1)
,('Core i7' , 900, 1)
,('Core i5' , 500, 1)
,('Core i3' , 300, 1)
,('Xeon série 7000' , 1245.18, 1)
,('Core Duo' , 500.50, 1)
,('Xeon' , 200.78, 1)
,('Pentium Dual-Core' , 15.44, 1)
;
Basicamente aquele velho exemplo...Produtos x Fornecedor
E eu queira criar a estrutura da foto abaixo:
JSON-TEXT:
[{"id":"9","fornecedor_id":"1","fornecedor_nome":"Intel","produtos":[{"id":"9","nome":"Core i3","fornecedor_id":"1"},{"id":"7","nome":"Core i7","fornecedor_id":"1"},{"id":"12","nome":"Xeon","fornecedor_id":"1"},{"id":"10","nome":"Xeon s\u00e9rie 7000","fornecedor_id":"1"},{"id":"8","nome":"Core i5","fornecedor_id":"1"},{"id":"6","nome":"Pentium 4","fornecedor_id":"1"},{"id":"13","nome":"Pentium Dual-Core","fornecedor_id":"1"},{"id":"11","nome":"Core Duo","fornecedor_id":"1"}]},{"id":"5","fornecedor_id":"2","fornecedor_nome":"Amd","produtos":[{"id":"5","nome":"Phenom X2","fornecedor_id":"2"},{"id":"3","nome":"Phenom FX","fornecedor_id":"2"},{"id":"1","nome":"AMD 29030","fornecedor_id":"2"},{"id":"4","nome":"Phenom X4","fornecedor_id":"2"},{"id":"2","nome":"Athlon","fornecedor_id":"2"}]}]
Alguém sabe se tem alguma maneira facilitada?Consegui apenas da seguinte maneira:
$conn = mysqli_connect("localhost", "root", "", "loja_imaster");
mysqli_set_charset ($conn , 'utf8');
$sql = '
select
produtos.id
,produtos.nome
,fornecedor.id as fornecedor_id
,fornecedor.nome as fornecedor_nome
from
fornecedor
inner join produtos on(
produtos.fornecedor_id = fornecedor.id
)
order by fornecedor_id
';
// $stmt = mysqli_query($conn, 'set utf8');
$stmt = mysqli_query($conn, $sql);
if (!$stmt) {
//echo "Não foi possível executar a consulta ($sql) no banco de dados: " . mysql_error();
echo mysqli_errno($conn) . ": " . mysqli_error($conn) . "\n";
die();
}
//$produtos = mysqli_fetch_assoc($stmt);
$produtos = mysqli_fetch_all($stmt, MYSQLI_ASSOC);
$noSql = array();
$last_fornecedor = 0;
$grafo = array();
for($i = 0; $i < count($produtos); $i++){
$produto = $produtos[$i];
if($last_fornecedor == 0 || $last_fornecedor != $produto['fornecedor_id']){
unset($produto['nome']);
$produto['produtos'] = array();
$grafo[] = $produto;
}
$last_fornecedor = $produto['fornecedor_id'];
}
// print_r($grafo);die();
foreach($produtos as $prod){
unset($prod['fornecedor_nome']);
for($i = 0; $i < count($grafo); $i++){
if($prod['fornecedor_id'] == $grafo[$i]['fornecedor_id']){
// unset($prod['fornecedor_id']);
$grafo[$i]['produtos'][] = $prod;
}
}
}
//Exibe estilo grafo.
// print_r($grafo);
header('Content-Type: application/json; charset=utf-8');
print json_encode($grafo);https://fiddle.jshell.net/w5zbmxmh/
Nunca tinha pensando em estruturas assim e faz bastante sentido em alguns casos principalmente em relacionamentos estilo arvores:
\
\
/ \ (Fornecedor)
/ \ (Computadores compatíveis)
/ \ (etc)
Enfim se alguém tiver matéria a compartilhar ou dicas de como deixar mais limpo (sem fazer 2x consultas no banco) seria bacana.Abraço a todos
Update:
Joguei a duvida no GitHub (Forum - frontendbr) pra envolver mais gente, caso queiram acompanhar:
@Gabriel Heming
Pelo SELECT IN (ou apenas com SQL) não é possível criar estrutura do JSON?
Outro crise existencial questionamento será que nesse caso facilita ou atrapalha o Front-End essa estrutura?
#emBuscaDoCodigoPerfeito
Meu objetivo principal seria fazer em apenas uma estrutura de dados exibir <selects/> de acordo com <selects/> como exemplo do fiddle abaixo:
https://fiddle.jshell.net/w5zbmxmh/
Já que é muito comum no dia a dia de desenvolvimento web esse problema.
Você já trabalhou com banco de dados no-sql?
-- Off sobre o Stack
Achei que seu código estivesse pronto kkkk que era só copiar e colocar kkkk
shausHAsuaHSuaHsuhUsu
Lembrei disso:
>
@Gabriel Heming
Pelo SELECT IN (ou apenas com SQL) não é possível criar estrutura do JSON?
Não. É um problema do banco de dados relacional. Se fosse um Mongo (ou outro similar), por exemplo, seus dados estariam praticamente prontos.
>
Outro crise existencial questionamento será que nesse caso facilita ou atrapalha o Front-End essa estrutura?
#emBuscaDoCodigoPerfeito
Meu objetivo principal seria fazer em apenas uma estrutura de dados exibir <selects/> de acordo com <selects/> como exemplo do fiddle abaixo:
https://fiddle.jshell.net/w5zbmxmh/
Já que é muito comum no dia a dia de desenvolvimento web esse problema.
Acho que este ano estou entrando no meu nono ano como programador profissional. A verdade nua e crua é que não existe código perfeito. Tudo que você fizer, terá um porém.
Seu código é rápido em exibir o segundo select, mas pesado em questão de processamento no front-end. Por outro lado, se toda a vez que você alterar a seleção do primeiro select criar uma consulta em ajax, para retornar apenas os dados pertinentes, seu código ficará lento por causa das consultas, mas será leve, pois carregará apenas o essencial.
A pergunta principal é, o quanto cada vantagem é boa e cada desvantagem é ruim. Apesar da primeira opção usar mais memória do browser que a segunda, tende a ser pouca memória, logo é aceitável. Se chegasse a travar o browser, ai é outra história.
Você já trabalhou com banco de dados no-sql?
Já. Mas profissionalmente, as empresas que eu tenho contato são mais conservadores e preferem banco de dados relacionais. Se precisarem de mais performance, vão para alternativas corporativas pagas, como Oracle ou SQL Server.
>
-- Off
shausHAsuaHSuaHsuhUsu cada uma viu...
Lembrei disso:
http://i.imgur.com/SZPjHwz.jpg
Bem isso... eahaeuhaeuae
Olha, consultando a documentação do MySQL relacionada à JSON, consegui chegar nesta solução:
SELECT
f.id, f.nome,
CONCAT('[', group_concat(
JSON_OBJECT('id', p.id, 'nome', p.nome, 'valor', p.valor)
), ']') as produtos
FROM fornecedor as f
INNER JOIN produtos as p ON p.fornecedor_id = f.id
GROUP BY f.id
Tem o fiddle para teste: http://rextester.com/JXLTDN39387
Aí depois seria só dar um JSON.parse no valor de produtos (ou dependendo de como você estiver fazendo, vai ser automático, igual ao id/nome do fornecedor)...
Bom exemplo @AndersonMamede, vi que é da nova versão do MySQL 5.7.8 com preview para a 8.0.0.
Bom exemplo @AndersonMamede, vi que é da nova versão do MySQL 5.7.8 com preview para a 8.0.0.
Acho que é mais ou menos isso... pelo que entendi através deste post, o JSON foi introduzido no MySQL na versão 5.7 (o fiddle do exemplo usa o MySQL 5.7.12), e na versão 8 vai ser adicionado funções de agregação (como JSON_ARRAYAGG e JSON_OBJECTAGG).
Olá pessoal,
Agradeço a resposta de todos.
A ideia era justamente essa pegar um ponto de vista diferente e tentar melhorar legibilidade do código utilizando funções nativas como por exemplo o JSON_OBJECT que eu desconhecia vlw @AndersonMamede!!!
@Williams Duarte trouxe um artigo bem completo a respeito de hierarquia.
SELECT name
FROM nested_category
WHERE rgt = lft + 1;
MIND-BLOWING
@Gabriel Heming
Sobre o 'código perfeito' é talvez 'perfeito' tenha sido uma palavra palavra infeliz hehe...
Bacana a balança de 'One Flat request' x 'Multiple Slim request' é sempre legal olhar o cenário para ver qual solução se encaixa melhor, nesse caso acredito por não passar de alguns KBS então uma requisição seria ideal.
Abraço a todos e obrigado pela contribuição.
Não tem muito segredo e nem muita mágica.
Você tem três caminhos a seguir, o seu atual (criando o problema N + 1), realizando mais de uma consulta ou resolvendo a questão N + 1 em um SELECT IN.
Essa semana, respondi uma questão bem similar no stack overflow:
http://pt.stackoverflow.com/questions/175164/como-reunir-dados-de-duas-consultas-em-um-objeto-php/175182#175182
Veja que não estou nem um pouco preocupado com a realização de N consultas. Entretanto, o autor do tópico de lá é preguiçoso em tentar entender o simples funcionamento.