Qual solução vc daria para este problema? (BD)

14 respostas
L

Qual solução vc daria para este problema?
E qual o embasamento teórico da sua solução?

Existem usuários.
Cada usuário pode OU NÃO ter 1(SOMENTE UM) endereco.

SOLUÇÃO 1:
Usuario(
id int pk,
nome varchar,
cep varchar,
cidade varchar,
endereco varchar,
numero int,
bairro varchar
)

SOLUÇÃO 2:

Usuario(

id int pk,

nome varchar

)

UsuarioEndereco(

id_usuario int pk fk,

cep varchar,

cidade varchar,

endereco varchar,

numero int,

bairro varchar

)

Quem tiver uma solução diferente pode apresentar.

minha intenção é a seguinte: se a tabela usuário tem muitos atributos…
e vc pode agrupar esses atributos por naturezas, por exemplo endereço…
suponha que a tabela usuario tenha 30 atributos…

há algum erro em “desacoplar” os atributos de endereço em uma segunda tabela???

14 Respostas

FernandoCartaxo

Se é 1-1 não precisa criar uma nova tabela…

Você tem que analisar a sua modelage:
se nunca um usuário terá mais de um endereço não tem necessidade de criar uma tabela
se no futuro pederá acontecer de precisar cadastrar mais de um endereço (sei lá, endereço de correspondência e endereço da casa…), modela logo em duas tabelas

Criaria também tabela de bairro e cidade, deixar para ser digitado não é uma boa idéia.

Dá uma olhada em normalização de banco de dados

http://www.luis.blog.br/normalizacao-de-dados-e-as-formas-normais.aspx

L

entendo… eu coloquei bairro e cidade como varchar so pra exemplificar…

minha intenção é a seguinte: se a tabela usuário tem muitos atributos…
e vc pode agrupar esses atributos por naturezas, por exemplo endereço…
suponha que a tabela usuario tenha 30 atributos…

há algum erro em “desacoplar” os atributos de endereço em uma segunda tabela???

boneazul

lauronolasco:
entendo… eu coloquei bairro e cidade como varchar so pra exemplificar…

minha intenção é a seguinte: se a tabela usuário tem muitos atributos…
e vc pode agrupar esses atributos por naturezas, por exemplo endereço…
suponha que a tabela usuario tenha 30 atributos…

há algum erro em “desacoplar” os atributos de endereço em uma segunda tabela???

Cara numero de colunas pra um banco não é problema desde que tratem um mesmo assunto…se a sua duvida for ficar muito atributo pra uma mesma classe…sua tabela pode ter 200 colunas se necessario…

Bom eu levo como criterio pra modelar qual a probabilidade disso ou daquilo acontecer??? Se a resposta de cara por exemplo te diz “vai poder tem mais de um” ou “pode chegar a ter mais de 1” é melhor prever já, porque depois se mudar vai ser trampo arrumar a casa…migração de dados…etcetc…

E a resposta vai te forçar a desacoplar,mesmo voce não querendo.

Se voce acha que fica mais organizado ou que vai ser utilizado em outro ponto também é valido desacoplar…

No caso endereço por exemplo se amanha voce começa a cadastrar empresa , fornecedor,etcetc voce ja tem uma entidade “localizacao” que cuida disso.
Alem do que seria desperdicio de recurso separar sem necessidade ja que a complexidade acaba aumentando junto…

L

Nessa questão do desperdício de recurso eu fico em dúvida…

Vou dar um exemplo rápido:

Supondo que eu tenha um webservice com um considerável volume de acessos.
Por exemplo, supondo que 1000 usuários estejam acessando ao mesmo tempo.
O método do webservice instancia um objeto Usuário sem a necessidade de utilizar os atributos de endereço.
Supondo também que cada atributo tenha um tamanho de 10bytes.

Se eu uso a solução 2 e mapeio UsuarioEndereço como LAZY teremos:
1 Usuário = 20 bytes
1000 usuários = 20kb

Agora utilizando a solução 1:
1 Usuário = 140 bytes
1000 usuários = 140kb

Acredito que o meu exemplo tem lógica…

O que acham??

boneazul

lauronolasco:
Nessa questão do desperdício de recurso eu fico em dúvida…

Vou dar um exemplo rápido:

Supondo que eu tenha um webservice com um considerável volume de acessos.
Por exemplo, supondo que 1000 usuários estejam acessando ao mesmo tempo.
O método do webservice instancia um objeto Usuário sem a necessidade de utilizar os atributos de endereço.
Supondo também que cada atributo tenha um tamanho de 10bytes.

Se eu uso a solução 2 e mapeio UsuarioEndereço como LAZY teremos:
1 Usuário = 20 bytes
1000 usuários = 20kb

Agora utilizando a solução 1:
1 Usuário = 140 bytes
1000 usuários = 140kb

Acredito que o meu exemplo tem lógica…

O que acham??

Entao cara voce tem que pensar diferente… o que vai sobrecarregar seu banco é um exemplo do tipo

select [b]*[/b] (leia-se todas colunas da tabela)

Essa estrela que ja vem por padrão do hibernate nem sei se é ele que voce usa mesmo para mapear que pesa no banco
pq o select sempre faz de tudo.
Faça o filtro das colunas especificas que voce vai usar nesse caso pra nem carregar de banco o que voce nao vai precisar e nem utilizar recurso java pra popular suas instancias…que seja as 1000 ao mesmo tempo…

Cara 2 regrinhas basicas o que ponderar…

No java custo de processamente é bastante na palavra chave new essa palavrinha é uma das que mais consomem recurso…
Em banco de dados é seu select quanto menas coisa pedir menor trabalho ele tem pra te trazer…

É como voce falar pra alguem
solução 1 - "entao pra chegar la é so seguir reto"
solução 2 - “entao pra voce chegar la segue aqui pelo direita porque voce vai precisar dar carona pra um pessoal”

Cara se um usuario tem mais de 1 endereco sua relacao vai ter que ser 1-N sua outra solução nao vai te atender…ate atende mais dai voce estaria modelando incorretamente e fazendo não normalizado gerando duplicidade de registro eu iria alem e te proporia o seguinte modelo.

Usuario
|--------ID
|--------NOME

Usuario_Localizacao
|-------ID_USUARIO
|-------ID_LOCALIZACAO

Localizacao
|---------ID
|---------RUA
|---------NÚMERO
|---------BAIRRO

Com esse modelo voce reaproveitaria a tabela localizacao pra outros fins que eu exempliquei se amanha aparece outra classe que envolva localizacao voce ja teria meio caminho andado…

L

ok…

ja vi varios exemplos desta solução 2 pela internet…
inclusive eu também uso em algumas situações… por achar mais organizado.
um exemplo de uso que fica mais organizado:

tenho empresa(id int pk)

e tenho empresaParametroFiscal(id_empresa int pk fk,  varios atributos fiscais  )

supondo que a empresa possa, ou não, ter parametro fiscal.

raramente usarei parametro fiscal, logo mapeio como LAZY e ele só será carregado quando eu quiser…
ou seja, se eu nao invocar o GET, ele nao vai criar new ParametroFiscal()

não gosto da ideia de se misturar “200” atributos de diferentes naturezas em uma só tabela…
imagine como fica a manutenção…

boneazul

lauronolasco:
ok…

ja vi varios exemplos desta solução 2 pela internet…
inclusive eu também uso em algumas situações… por achar mais organizado.
um exemplo de uso que fica mais organizado:

tenho empresa(id int pk)

e tenho empresaParametroFiscal(id_empresa int pk fk,  varios atributos fiscais  )

supondo que a empresa possa, ou não, ter parametro fiscal.

raramente usarei parametro fiscal, logo mapeio como LAZY e ele só será carregado quando eu quiser…
ou seja, se eu nao invocar o GET, ele nao vai criar new ParametroFiscal()

não gosto da ideia de se misturar “200” atributos de diferentes naturezas em uma só tabela…
imagine como fica a manutenção…

“Cara numero de colunas pra um banco não é problema desde que tratem um mesmo assunto

Eu falei do mesmo assunto e nao de assunto diferentes…coisas diferentes devem ser mapeados SE NECESSARIO em tabelas diferentes…

L

exatamente neste ponto que eu queria chegar…
tudo depende da análise que se faz ao agrupar os atributos…

então não se pode considerar um erro a solução 2, visto que o endereço,
dependendo da visão de quem está modelando e do problema proposto,
pode ser “acoplado” ou “desacoplado” de empresa.

fantomas

Oi lauronolasco,

Se entendi sua dúvida a resposta, ao meu entender, é não.

Não há problema em agrupar colunas por “natureza” em outra tabela.

O tema é NORMALIZAÇÃO: A formula normal que sustenta esta decisão deve ser a terceira. Dá uma olhada no conteúdo deste link para começar: http://pt.wikipedia.org/wiki/Banco_de_dados_relacional#Primeira_Forma_Normal_.28FN1.29

O único porem é a performance, haverá mais chaves, indices e etc… que serão utilizados para acessar os dados na tabela mas isso é algo que pode ser imperceptivel.

Nesta hora o que vale mais é o bom senso, algumas vezes para atingir performance você tem que “fugir” de algumas regras, principalmente em se tratando de normalização.

flws

L

fantomas…
Concordo plenamente com vc!!
Abri este tópico ao conversar com um amigo quanto a solução do problema.
Segundo ele, a solução 2 seria um erro.

Fazendo uma analogia:
vc tem uma distribuidora… e tem uma entrega a fazer, que soma 10kg…
vc tem uma motocicleta e um caminhão baú para transportar os produtos…

vc leva de motocicleta ou de caminhão??

L

Excelente colocação!

boneazul

lauronolasco:
exatamente neste ponto que eu queria chegar…
tudo depende da análise que se faz ao agrupar os atributos…

então não se pode considerar um erro a solução 2, visto que o endereço,
dependendo da visão de quem está modelando e do problema proposto,
pode ser “acoplado” ou “desacoplado” de empresa.

Cara suas 2 soluções estão corretas mas ambas fazem coisas diferentes…

a primeira atende 1-1 (Voce tem certeza que 1 cliente vai ter só 1 endereço)
a segunda 1-N (Um usuario pode ter mais de 1 endereço)

Agora o que voce nao pode e nem deve fazer é que sua solução 1 atenda a solução 2,ou seja,querer cadastrar +1 endereço pra um mesmo cliente na sua primeira modelagem…

L

boneazul…

A soução 2 também é 1x1… se vc der uma olhada, só foi repetida a chave com FK refrenciando o id da tabela empesa.

boneazul

lauronolasco:
boneazul…

A soução 2 também é 1x1… se vc der uma olhada, só foi repetida a chave com FK refrenciando o id da tabela empesa.

"SOLUÇÃO 2:
Usuario(
id int pk,
nome varchar
)
UsuarioEndereco(
id_usuario int pk fk,
cep varchar,
cidade varchar,
endereco varchar,
numero int,
bairro varchar
) "

pelo que eu entendi sua solução 2 é essa nuim é??? isso é 1-N e 1-N é 1-0…N (zero ou nenhum, incluindo 1-1(pra quem faz a linha sem o pe de galinha) essa solução tambem aborda a solução 1-1 mas o que pra mim seria uma tabela desnessaria se a relacao realmente for 1-1 e a solução 1 seria a mais interessante…

Acontece que voce ta querendo usar a solução 2 so pra “organizar” e continuar na ideia 1-1 e usar o LAZY pra nao carregar caso nao precise…pro hibernate isso pesa mais quando voce realmente precisa…voca acaba consumindo mais recurso do que economizando…se bem que isso pra banco hoje em dia é mole…o que pega mais é o recurso java mesmo…como um colega disso a diferença disso é imperceptivel a baixa escala…mas como voce tinha dito que o proposito é a larga escala isso ja é um pequeno diferencial…

Criado 27 de março de 2010
Ultima resposta 30 de mar. de 2010
Respostas 14
Participantes 4