Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Bom dia, pessoal.
Estou começando um sistema de pedido on-line e estou com algumas dúvidas básiccas, com classes, objetos, bd, etc.
Estava querendo fazer uma tabela e uma classe para cliente e endereço, mesmo sabendo que o cliente só tem um endereço. Até aí tudo bem. Posso fazer assim e dar extends de endereço na classe cliente, né?
O problema é na hora de salvar no BD, onde coloco o id(chave estrangeira) no cliente ou no endereço?
Como faço para salvar no bd o objeto cliente que extendeu do objeto endereço, se são duas tabelas diferentes? Tenho que primeiro dar insert com os dados do cliente e depois dou outro insert de endereço?
Lembrando que não utilizo frameworks
Desde já, agradeço.
Valeu pela ajuda.
Então você acha melhor eu fazer um cadastro de cliente com passo a passo. Primeiro pego os dados pessoais, ae quando o cliente clicar em avançar, eu salvo na tabela cliente e depois pego os dados de endereço e salvo na tabela endereço, é isso?
Voce acha que assim fica melhor que salvar tudo em uma tabela só?
Se você duplicar os endereços estará errado tb.
a table endereço não deve ter linhas repetidas.
o mais correto, é você cadastrar o CEP na tabela do cliente. E então usando o CEP como FK, você puxa a informação do endereço.
Entendi.
Mas só pra confirmar, é melhor eu fazer tabelas separadas e na hora de cadastrar fazer passo a passo, primiero os dados do cliente depois o endereço, né?
Não vamos complicar a cabeça do nosso amigo...
Apesar de querer por endereço em uma tabela separada ficaria meio estranho ter várias linhas repetidas, mas se você não quer quebrar um pouco a cabeça com isso, pode fazer sem peso na consciência.
Segundo a FK sempre vai na tabela que referencia a outra. O Usuario tem um endereço, então o Usuário referencia o endereço. Se fosse o contrário, um Endereço tinha um Usuário, então seria o contrário.
Deu pra ajudar em algo?
Isso, afinal você pode ter n clientes para 1 endereço :P
Mas só lembrando que se for utilizar o CEP como FK e para não duplicar endereços, você teria 2 formas de fazer:
1- Uma que é confiar nos dados do usuário ou
2- Usar um banco de dados separado e pago do CORREIOS com todas as ruas/cep's do Brasil para poder fazer a validação corretamente.
:thumbsup:
Entao voce acha melhor colcoar tanto o endereço quanto os dados pessoais do cliente, na tablea cliente, é isso?
Pois é, André, isso que pensei, não tem como eu pagar para usar os CEPs dos correios.
A saída vai ser colocar o id do endereço na tabela cliente mesmo. Até porque pelo cep eu só consigo o logradouro, o numero, complemento e outras informações são diferente para cada endereço
Analise as opções que você tem, e defina qual o melhor para o seu caso em específico, nós só podemos dar sugestão a partir do pouco que sabemos, mas a decisão final tem que ser sua, que está a par de todo o projeto.
>
Entao voce acha melhor colcoar tanto o endereço quanto os dados pessoais do cliente, na tablea cliente, é isso?
isso depende, se você quer cadastrar so 1 endereço por usuário e nao pretende mudar nunca isso ai da para adicionar os campos relativos a endereço na tabela usuário.
Agora se o usuário pode cadastrar mais de 1 endereço ai você faz uma tabela separada para os endereços e referencia na tabela usuário
Entendi.
Valeu mesmo pela ajuda.
mas caso eu opte pela utilização de duas tabelas separadas, eu tenho que fazer o cadastro de cliente na forma de passo a passo né? Primeiros os dados pessoais, insert na tabela cliente, depois o endereço e insert na tabela endereço. è isso?
Não é obrigado a fazer isso, você poderia também criar uma Stored Procedure para realizar a inserção de maneira semântica.
sim, você faz query cadastro do usuário e retorna o lastInsertId (id do usuário cadastrado) e com esse id você cadastra o endereço(s) referente ao usuário
Entendi.
É que vou iniciar um projeto grande, cheio de detalhes e que poderá vir a ser utilizado para mais de uma empresa, então quero ele certinho,q ue ter pra ser aproveitado o máximo possível. Tenho conhecimento de UML, OO, mas não muito com PHP, uso mais Java, mas esse sistema vai ser em PHP mesmo.
Como vocês costumam fazer as divisões de camada?
Eu atualmente, crio um diretorio modelo (classes), um controle (controle de cada classe, com funções para chamar a camada DAO e outras), um diretorio dao (com acesso ao BD), e varios outros diretorios, contendo html, js, css, esse tipo de coisas.
Voce dão alguma dica nessa divisao?
Obrigado
Voce poderia utilizar o padrão MVC (model/view/controller) para os arquivos php, e fora disso você criaria um diretorio @web-files, com css/js/imagens/etc...
Você poderia utilizar o code igniter para esse projeto, ele já traz uma estrutura de diretórios pronta, e o aprendizado dele é super rápido.
Demorei somente 2 dias para aprender a utiliza-lo. E hoje já produzo com ele.
Pessoal,
Voltando ao inicio dessa discussão. Surgiu uma nova duvida.
Se eu optar por utilizar uma tabela exclusiva para armazenar endereço, e associá-las a tabela empresa e também a tabela cliente. Eu não poderia colocar a chave estrangeira na tabela endereço, pois duas tabelas estão referenciando esta, ou seja, um cliente pode e vai ter o mesmo id de um empresa, então não tem como eu colocar esse id na tabela endereço. Por outro lado, a empresa 1 pode ter dois endereços, então eu teria que jogar o id da empresa no endereço. Como eu resolvo esse problema? Crio uma tabela endereço_empresa e outra endereço_cliente? Ou crio na tabela endereço dois campos que receberão a FK, tipo FK_empresa e FK_cliente? Caso essa segunda opção seja a melhor, não tem problema um desses FK ficarem null?
Obrigado
Eu não poderia colocar a chave estrangeira na tabela endereço
não não. De jeito nenhum
a empresa 1 pode ter dois endereços, então eu teria que jogar o id da empresa no endereço.
? também não.
Como eu resolvo esse problema? Crio uma tabela endereço_empresa e outra endereço_cliente?
sim, é por aqui a solução.
Ou crio na tabela endereço dois campos que receberão a FK, tipo FK_empresa e FK_cliente?
não !
Caso essa segunda opção seja a melhor, não tem problema um desses FK ficarem null?
sim, tem problema.
vai contra a segunda ou terceira forma normal(se não me engano)
leia:
http://wbruno.com.br/blog/2011/03/29/afinal-o-que-e-entidade/
n li tudo, apenas os 5/6 primeiros post....
Galera se usar o CEP como FK, o q vai ocorrer se dois usuários morarem na mesma rua? ou no mesmo conjunto domiciliar/apartamento/condominio?
Em caso extremo, dois usuários podem ser marido e mulher morarem na mesma casa... eu aconselho usar um colunaReferencia... é assim q eu faço em casos que a chave fica difícil de se encaixar ou pode gerar erros..
Cliente
id, nome, RG, relacaoEnd.
Endereço
id, pais, CEP, relacaoEnd.
select * from cliente where id="$id";
$relacaoEnd = $l['relacaoEnd'];
select * from endereco where relacaoEnd = '$relacaoEnd' ;William,
Valeu pelas dicas e pela ajuda. Mas eu ainda não entendi uma coisa direito: seu eu tenho que colocar o id do endereço na tabela empresa, como ficaria quando a empresa tem dois endereços? Eu precisaria de uma tabela associativa?
Galera se usar o CEP como FK, o q vai ocorrer se dois usuários morarem na mesma rua?
não vai acontecer nada.
Em caso extremo, dois usuários podem ser marido e mulher morarem na mesma casa... eu aconselho usar um colunaReferencia...
desnecessário cara.Okay, sem problemas.
Imagina assim:
>
TABLE endereco (cep(PK), logradouro)
00000-000, Rua dos Bobos
11111-111, Av Cirandinha
TABLE pessoa (id(PK), cep(FK), nome)
1, 11111-111, William
2, 11111-111, Juliana
No caso, sou casado com a Juliana, e moro na mesma rua que ela. Sem problema nenhum. Não vi nenhum erro.
Agora, se eu tiver mais de uma casa:
>
TABLE endereco (cep(PK), logradouro)
00000-000, Rua dos Bobos
11111-111, Av Cirandinha
TABLE pessoa (id(PK), nome)
1, William
2, Juliana
TABLE endereco_pessoa( id_pessoa(FK), cep(FK) )
1, 11111-111
2, 11111-111
1, 00000-000
Continuo morando na mesma rua que a Juliana, mas também tenho um outro endereço.Também sem nenhum problema.
pode gerar erros..
na verdade não.a tua coluna de referência é apenas um inteiro arbitrário.
Usar ou não, tanto faz. Só quero deixar claro, q usar o CEP não atrapalha em absolutamente nada.
KMRodrigo,
Essa sua coluna relEndereço, recebe que tipo valor? Os valores são iguais em ambas as tabelas né?
como ficaria quando a empresa tem dois endereços? Eu precisaria de uma tabela associativa?
sim, exatamente.
veja o post #21
é exatamente essa table associativa que explico no post do blog. você leu ?
Li sim, é que voce postou depois de eu ter postado minha duvida.
Agora entendi.
Li seu blog tambem, as coisas clarearam mais, inclusive para usar uma tabela para contatos também.
Mesmo o relacionamento sendo um(empresa) para varios(endereços) eu tenho que usar a tabela associativa então? Achei que era só para M:N
Fazendo dessa maneira, uma tabela para empresa, uma para contatos e outra para endereço, mesmo que, por enquanto eu tenha apenas uma empresa com um endereço, eu utilizo a tabela associativa para o endereço e para os contatos da empresa. Com isso eu posso ter uma tabela endereço única, que poderá ser utilizada tanto para clientes quanto para empresas, o que vai mudar apenas é a tabela associativa, entendi direito?
posso ter uma tabela endereço única, que poderá ser utilizada tanto para clientes quanto para empresas,
sim, exato.
>
o que vai mudar apenas é a tabela associativa, entendi direito?
hum.. sim.
se você tiver uma tabela para clientes e outra para empresa, então precisa de uma associativa para cada.
um workaround, seria ter uma coluna na tabela associativa, 'tipo', ai você informaria se aquela linha é para tipo empresa ou tipo cliente.
dessa forma, não teria 2 tabelas com a mesma função.
não sei, precisa pensar mais nessa modelagem..
Sobre a foreign key, creio que a mesma não seja na tabela de clientes, mas sim em endereço, veja:
andrey@andrey:~$ mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.41 Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create schema exemplo;
Query OK, 1 row affected (0.00 sec)
mysql> create table clientes(
-> id smallint( 6 ) not null auto_increment,
-> nome varchar( 20 ) not null,
-> primary key( id )
-> )engine = innodb;
Query OK, 0 rows affected (0.11 sec)
mysql> create table endereco(
-> cid smallint( 6 ) not null,
-> endereco varchar( 72 ) not null,
-> foreign key `fkClientes-Endereços`( cid ) references clientes( id ) on update restrict on delete cascade
-> )engine = innodb;
Query OK, 0 rows affected (0.06 sec)
mysql> insert into clientes values( 1, 'Andrey' ), ( 2, 'Marcos' ), ( 3, 'Henrique' );
Query OK, 3 rows affected (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into endereco values( 1, 'Rua 1' ), ( 2, 'Alto do Morro' ), ( 3, 'Em casa' );
Query OK, 3 rows affected (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from endereco;
+-----+---------------+
| cid | endereco |
+-----+---------------+
| 1 | Rua 1 |
| 2 | Alto do Morro |
| 3 | Em casa |
+-----+---------------+
3 rows in set (0.00 sec)
mysql> delete from endereco where cid = 1;
Query OK, 1 row affected (0.02 sec)
mysql> select * from clientes;
+----+----------+
| id | nome |
+----+----------+
| 1 | Andrey |
| 2 | Marcos |
| 3 | Henrique |
+----+----------+
3 rows in set (0.00 sec)
mysql> select * from endereco;
+-----+---------------+
| cid | endereco |
+-----+---------------+
| 2 | Alto do Morro |
| 3 | Em casa |
+-----+---------------+
2 rows in set (0.00 sec)
mysql> delete from clientes where id = 2;
Query OK, 1 row affected (0.03 sec)
mysql> select * from endereco;
+-----+----------+
| cid | endereco |
+-----+----------+
| 3 | Em casa |
+-----+----------+
1 row in set (0.00 sec)
mysql>
não!um cliente não é um endereço, e o endereço ñao é um cliente. Não tem nada a ver usar herança nisso.
a FK fica na tabela cliente.
o mais simples, é você ter um cadastro separado para os endereços. Primeiro cadastra o endereço, e depois o cliente.
Para pegar a chave da inserção do endereço, existem funções como mysql_last_insert_id(); //procure a correspondente para o teu driver