Jump to content

Archived

This topic is now archived and is closed to further replies.

Rodrigo Attique

Hernaça Múltipla de dados

Recommended Posts

Bom dia meus amigos, estou estudando modelagem de banco de dados, e estou desenvolvendo um pequeno sistema de cadastro de entidades para treinar.

Meu sistema cadastra 4 entidades específica: clientes, funcionarios, fornecedores e prestadores.

 

Criei as tabelas

Pessoa

PessoaFisica e Juridica que herdam de pessoa

e as outras com excessão de funcionario que herda somente de pessoafísica as outras tres herdam das duas tabelas pessoa.

 

Minha dúvida é como traduzir isto no banco de dados, pois meu cliente pode ser pessoa física e jurídica ao mesmo tempo assim como pode ser meu funcionário...

 

Quero fazer algo que me evite deixar campos nulos e permita que eu arpoveite o maximo de dados possível.

 

Desde já agradeço.

Share this post


Link to post
Share on other sites

Imagino que através de uma terceira tabela que sirva unicamente para relacionar os 'tipos de pessoa" (isso soou estranho) com as pessoas em si você resolveria.

 

Estou especulando, mas veja se não faz sentido. A grande maioria dos dados ficarão, digamos, na tabela users, e na tabela usersGroups você teria que ID X pertence ao grupo de ID Y.

 

Se um usuário for apenas pesoa física, haverá apenas uma ocorrência do ID dele nessa tabela. Se for física e jurídica haverão dois.

Share this post


Link to post
Share on other sites

Acho que entendi o negocio de usuarios e grupos, fala de fazer as tabelas pf e pj e usar as outras entidades como um grupo, digo grupo de clientes daí eu vou lá e adiciono o id da pf no cliente e faço o mesmo das outras?

Share this post


Link to post
Share on other sites

Acho que que você imagina é diferente do que o que eu imagino. Pensei em algo como:

 

groups (id, title)

1, Pessoa Física

2, Pessoa Jurídica

3, Funcionário

4, Cliente

 

users (id, name)

1, Bruno Augusto

2, iMasters

 

usersGroups (id, gid, uid)

1, 1, 1

2, 2, 2

3, 1, 4

 

Vê que o Bruno Augusto, cujo ID é 1 aparece duas vezes na tabela de relacionamento? Assim você pode ter um mesmo usuário pertencente à múltiplos grupos sem precisar duplicar informações.

Share this post


Link to post
Share on other sites

Interessante sua dúvida. Aonde trabalho lidamos bastante com esses tipos de relacionamentos, e fazemos como o Bruno disse, com alguma diferença.

 

Na classe relacionamentos, nós mantemos:

id

id_objX

id_classeX

id_objY

id_classeY

 

Além de outros campos como data de registro, status, operador, etc.

 

Esta tabela serve para relacionar qualquer objeto de qualquer classe, com qualquer outro objeto de qualquer outra classe. Eu posso ter dois dois objetos com o mesmo ID, porém cada objeto pertencendo a uma classe diferente da outra. No seu caso, talvez só o exemplo do Bruno já seja suficiente, mas para aplicações maiores talvez seja interessante guardar a classe para evitar conflito de ID, pois eu posso ter objetos com mesmo ID sendo estes de tabelas diferentes.

 

No nosso caso, não usamos uma tabela para guardar os grupos, que seriam as classes. Temos uma classe somente para TIPOS que contém um enumerado para cada tipo, e um deles é o de classes:

 

 type
   tpClasses = (Cliente, Funcionario, Fornecedor, Prestador);

E no caso usamos uma classe Relacionamento para cuidar dos relacionamentos (óbvio, rs), onde esta classe possui como atributos os campos da tabela (id, idObjX, idClasseX, idObjY, idClasseY), e possui métodos que retornam uma instância do relacionamento. Saliento que esta forma de relacionamento somente se torna necessária quando temos uma relação n..n (muitos para muitos), se o relacionamento é de 1..n, não há necessidade, neste caso basta criar uma chave estrangeira (id por exemplo) na tabela que representa a classe do lado n, a qual fará uma referência ao objeto que estará na tabela do lado 1.

 

Exemplo Prático

 

Digamos que eu tenha um objeto Proprietário, e um objeto Imóvel. Digamos que no nosso sistema, um proprietário pode ter vários Imóveis, assim como um imóvel pode possui vários proprietários. Digamos que além disso, o proprietário pode ser uma pessoa física, ou uma pessoa jurídica, e o imóvel pode ser uma Casa, ou um Apartamento, ou quaquer outro tipo. Logo minha classe de relacionamentos funcionaria da seguinte forma (em PHP):

 

public class PessoaFisica extends ObjectBase implements Pessoa {

  $id;
  $nome;
  $cpf;
  $imoveis;

public function __construct($id) {
  // procura o registro do objeto na tabela PessoaFisica, e atribui os valores a cada atributo,       sendo que imoveis recebe um array vazio
  }
}

public class Relacionamentos {

  public function GetRel($idClasse, $idObjeto) {
  // retorna um array contendo o valor do campo idObjY e tendo como índice o valor do campo idClasseY, de todos os registros cujo idClasseX = $idClasse e idObjX = $idObjeto, e também o valor do campo idObjX tendo como índice idClasseX, de todos os registros cujo idClasseY = $idClasse e idObjY = $idObjeto
}

Daí para usar:

$pessoa = new PessoaFisica(3);
$relacionamento = new Relacionamento($pessoa->getClasse, $pessoa->id);

foreach ($relacionamento as $classe => $valor) {
  array_push($pessoa->relacoes[$classe], $valor);
}

O método getClasse do objeto pessoa, assim como o atributo relacoes, na verdade pertencem a uma classe base, onde todas as classes da aplicação herdam dela. Ela basicamente procura pelo nome da classe no enum criado, e retorna o índice dele no array. Note que qualquer relacionamento ao ser criado, usa esse mesmo método para gravar no banco nos campos idClasseX e idClasseY, assim cada classe terá um índice único. A parte chata é que cada nova classe deve ser inserida no array (talvez tenha uma forma melhor de fazer isso).

 

Este loop fará o seguinte: o atributo relacoes será um array que terá como índice todas as classes que possuem relacionamento no banco, onde terá como valor um array contendo o id de todos os objetos daquela classe.

 

Você também pode transformar Proprietario em uma classe abstrata que herde de ObjectBase e criar um método getImoveis nele, que faça o mesmo que o getRel, porém esta função pode retornar um array de objetos Imovel. Exemplos:

 

public class getImoveis(Relacionamento $relacionamento) {
  $relacionamento = new Relacionamento($this->getClasse, $this->id);
  foreach ($relacionamento as $classe => $valor) {
    $class = $this->getClasseID($classe);
    $class = new ReflectionClass($classe);
    if ($class->implementsInterface('Imovel')) {
      $imovel = $class->newInstance($valor);
      array_push($this->imoveis, $imovel);
    }
  }
  return $this;
}

 

Esse método recebe um relacionamento (que conterá uma lista de todos os relacionamentos do objeto PessoaFisica, ou PessoaJuridica, qualquer um que herde de Proprietario (o qual terá acesso ao método getImoveis). Fará um loop em todos os relacionamentos existentes, recuperando na variável $classe o id da classe. O método getClasseID é da classe Base, e retorna o nome da classe, dado um id passado como parâmetro (como foi feito), Feito isso, classe recebe um ReflectionClass passando como parâmetro o nome da classe do imóvel (pode ser casa, apto, etc). Não entrando em detalhes, $class passa a ser uma espécie de reflexão da própria classe. Fazemos uma verificação para ver se esta classe é um imóvel, e caso sim, $imovel recebe uma nova instância da classe em questão, passando como parâmetro o valor do objeto daquela classe.

 

Feito isso, ele joga este objeto recém-criado dentro do atributo imoveis, que pertence a qualquer classe que herde de Proprietario, pois todo proprietário pode ter imóveis. Ele fará isso com todos os objetos que sejam de classes que implementem Imóvel, no final ele retorna o próprio objeto. Caso a classe Casa tenha um método que me mostre o valor dela, por exemplo, seria simples chamá-lo:

 


$pessoa = new PessoaFisica(5); $relacionamento = new Relacionamento($pessoa->getClasse, $pessoa->id); $pessoa->getImoveis($relacionamento)->imoveis[4]->getPreco;

Veja que uma pessoa recupera uma lista de seus imóveis, depois acessa o quinto imóvel da lista (lembrando que o array começa em zero), e retorna o preço dele.

 

Daí o céu é o limite cara, eu fiz esse código as pressas, talvez tenha algum erro que eu não tenha notado aí no meio xD mas só pra tentar ajudar em algo.

 

Abrass!

 

Share this post


Link to post
Share on other sites

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.