Modelagem de Dados- Surrogate Key / Identity

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
carlosdev
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 9
Registrado em: Ter, 06 Abr 2010 4:55 pm
Localização: SP

Olá pessoal,
Basicamente o conceito de Surrogate Key é o mesmo que o Design Pattern Identity Field (Martin Fowler) que preza por utilizar uma chave que não tenha nada a ver com o negócio. Seja ID, GuiID, etc.
Eu sou desenvolvedor .Net e essa pratica é muito comum em desenvolvedores .Net ou Java pois facilita muito a Orientação a Objetos.
Particularmente eu curto e sempre trabalhei desse jeito (exceto para tabelas de dominio/sistema).
Tabela de Domínio/Sistema/Lookups = Tabelas auxiliares que não possuem cadastro e geralmente são utilizadas para preenchimento de combos. A inclusão de itens é feita geralmente por alguém de TI. Ex: Tabelas de estado civil, tabelas de status, tabelas de unidade federativa

Todas as demais tabelas de cadastro, utilizaria ID como PK ao invés de Chave Natural, onde os atributos de negócios não repetidos seriam controlados através de Indice Único.

Exemplo Cenário 1:
TAB_UF (Unidade Federativa) - Tabela de dominio alimentada por alguém de TI (DBA, AD, etc)
#CD_UF - SP (Chave Primária)
DS_UF - São paulo

TAB_CLIENTE (Clientes) - Tabela populada pelo usuário através de tela
#ID_CLIENTE - 1 (Chave Primária com Sequence)
NM_CLIENTE - FULANO DA SILVA
TP_PESSOA - F (CheckConstraint F=Fisica, J=Juridica)
CD_UF - SP
FL_STATUS - A (CheckConstraint A=Ativo, I=Inativo)

A empresa que trabalho decidiu adotar Surrogate Key para TODAS as tabelas e suspendeu o uso de CheckConstraints e consequentemente Enum no C#.
Ou seja, para implementar o mesmo exemplo acima, as tabelas ficariam conforme abaixo:

Exemplo Cenário 2:
TAB_UF (Unidade Federativa) - Tabela de dominio alimentada por alguém de TI (DBA, AD, etc)
#ID_UF - 1 (Chave Primária com sequence)
CD_UF - SP (Índice único)
DS_UF - São paulo

TAB_TIPOPESSOA (Tipo de Pessoa)-Tabela de dominio alimentada por alguém de TI (DBA, AD, etc)
#ID_TP_PESSOA - 1 (Chave Primária com sequence)
CD_TP_PESSOA - F (F=Física, J=Juridica)
DS_TP_PESSOA - Física

TAB_STATUSPESSOA (Status da Pessoa)-Tabela de dominio alimentada por alguém de TI (DBA, AD, etc)
#ID_ST_PESSOA - 1 (Chave Primária com sequence)
CD_ST_PESSOA - A (A=Ativo, I=Inativo)
DS_ST_PESSOA - Ativo

TAB_CLIENTE (Clientes) - Tabela populada pelo usuário através de tela
#ID_CLIENTE - 1 (Chave Primária com Sequence)
NM_CLIENTE - FULANO DA SILVA
ID_TP_PESSOA - 1 (ForeignKey)
ID_UF - 1 (ForeignKey)
ID_ST_PESSOA - 1 (ForeignKey)

Detalhes: Como esses IDs são Sequences, estes poderão ser diferentes entre os ambientes de DEV, HOM e Produção.

Dúvidas?
1) É correto/viável usar surrogate key para tudo ? Inclusive para tabelas de dominio como: Status, Estado Civil, UF?

2) Imaginem uma situação em que eu tenha uma Procedure e precise fazer um Case por Status ou Tipo de Pessoa. Com o primeiro cenário é simples, mas no segundo é complicado pois é tudo ID.

3) O que acham sobre isso? Vale a pena usar ID pra tudo ou fazer um mix conforme o cenário 1?

Obrigado,
Carlos Araujo
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Carlos,

No projeto onde trabalho usamos este conceito "Surrogate Key" em QUASE todas as tabelas, mas NÃO abrimos mãos das checks constraits (CK) para situações simples , como (SIM/não, MASCULINO/FEMININO).

Talvez o pessoal da sua empresa deseja aplicar esta solução por dois motivos:

- Eles querem manter 100% documentados a lista de valores de dominio, e tem medo de perder este controle
se usarem as CHECKS CONSTRAINTS;
- Eles não querem ficar dependendo de programadores PL/SQL ou DBAs para manutenção destas Checks contraints.
Com as tabelas de domínio, basta eles fazerem um INSERT para cadastrar o novo valor, sem necessidade de
criar um script de manutenção PL/SQL para as CKs;

Mas pense no caso das situações onde tenho uma informação que aceita dois três estados (ex: SUCESSO/FRACASSO, MASCULINO/FEMININO, PAR/IMPAR). Vocês vão criar inúmeras tabelas de dois registros com a descrição destes estados. Se você precisar fazer uma consulta em uma tabela que armazene a coluna de FK destas tabelinhas -ex: CLIENTE, com a coluna ID_SEXO - você sempre precisará ficar fazendo JOINS para entender qual o SEXO do funcionário.

Imagine inclusive que você tem uma indicador que só aparece em uma única tabela do sistema. Se seguir esta lógica, você será obrigado a criar mais uma uma destas tabelinhas somente para guardar o status da mesma.

Então, eu não acho que aplicar este conceito "ao extremo" seja uma boa idéia, sabe? E quando falo isso, nem estou aqui mencionando PERFORMANCE ou ESPACO EM DISCO. Estas tabelinhas pequenas podem ficar em CACHE na base de dados, por exemplo.

Mas considero que para seus desenvolvedores (ou quem fizer a manutenção no código) sempre será cansativo fazer queries de JOIN de uma tabela principal com um monte de tabelinhas de domínios.

Eu pessoalmente acho a CHECK constraint uma importante característica do banco de dados ORACLE, pois você terá todas as informações nas tabela que você precisa pesquisar, sem precisar fazer joins com tabelinhas de dominio.

Em nossa empresa, adotamos a seguinte política:

- Usamos o conceito da SURROGATE KEY na maioria das tabelas;
- Para campos com lista pequena/média de valores (SIM/ANO, MASCULINO/FEMININO) adotamos as CHECKS;
- Para estas CKs, é obrigatório adicionar nos COMMENTS a lista de valores aceita e seu significado (ex:
IN_ESTADO_CIVIL. COMMENTS IS "Esta coluna armazena o estado civil da pessoa. Os valores possíveis
são :[C]asado/[V}iuvo/[D]ivorciado/[S]olteiro"

Sua pergunta é um tema bem interessante de se distutir neste forum. Espero que os outros foristas possam dar a opinião deles sobre o assunto.

Abraços,

Sergio Coutinho
carlosdev
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 9
Registrado em: Ter, 06 Abr 2010 4:55 pm
Localização: SP

Sergio,
primeiramente muito obrigado pelo seu feedback. Eu sou um cara que curto tecnologia e discussões técnicas como esta.
Eu tenho a mesma opinião que a sua e não poderia ter escrito argumentos melhores. Porém, não sou o dono da verdade e estou sempre em busca de opiniões e argumentos de outras pessoas para saber o estou no caminho certo afim de aumentar meu conhecimento.
As vezes vejo desenvolvedores ou arquitetos adotando a mesma arquitetura para TODOS os sistemas, mas sabemos que existem diversos tipos de sistemas e não posso criar uma arquitetura robusta que siga diversos Design Patterns e diversas camadas só por orgulho ou preciosismo.
Do mesmo modo que acho que TODAS as tabelas não precisam ser modeladas do mesmo modo com Surrogate Key pelos motivos que você citou:
-Quantidade de tabelas excessivas para determinar cada dominio de uma tabela que poderia ser controlado por CK
-Excesso de joins

Trabalhei em empresas no passado que utilizam a mesma política que a sua inclusive quando você fala da obrigatoriedade dos COMMENTS na coluna da tabela. A diferença é que nessa empresa, a obrigatoriedade era em TODOS os campos e não apenas nos campos que possuem CK.

Mais uma vez obrigado e espero também que outros foristas possam dar sua opinião ou citar a experiência de trabalho.

[]s
Carlos Araujo
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Carlos,

Também não me considero dono da verdade, mas sou da velha escola de modelagem de dados (adepto da forma normal).

Já tive que defender estes pontos de vista frente a arquitetos java. Um caso absurdo, por exemplo, foi a de desejarem criar uma tabela com uma ÚNICA coluna, filha de uma tabela pai. Quando perguntei porque não era melhor deixar tudo na tabela-pai, simplesmente como uma coluna adcional do tipo NULL (podendo até ser validada por uma CK), me vieram com um papo de herança e coisas assim. Que tinha que ser assim e ponto final.

Só alguns meses depois, conversando com outro arquiteto, o mesmo disse que esta modelagem solicitada era um absurdo, e me disse que os solicitantes só queriam fazer isso porque eram inexperientes na configuração da camada de aplicação. Mas este absurdo passou em outros sistemas anteriores.

Acho excelente a sua postura de questionar estes temas. Nenhum de nós é dono da verdade absoluta, e nem sempre um conceito deve ser adotado eternamente. Mas graças a Deus, o criador nos deu o dom do "bom-senso" para desconfiar de exageros, purismos e coisas do gênero.

Eu reli a sua pergunta, onde você descreve alguma situações de programação e eventuais diferenças entre ambientes de DESENV-HOMOLOG-PRODUCAO. Eu já passei por esta situação. Tive em minhas rotinas que desenvolver queries complexas de muitos JOINS, onde no final encontrava a situação desejada comparando com a DESCRICAO do campo. (ex: ,... AND UPPER(DS_DESCRICAO) LIKE 'DIVORCIADO%'). Ai de mim se o usuário cadastrasse descrições parecidas, com caracteres acentuados ou até mesmo diferentes (ex: "DIVORCIADO" em DESENV, "DIVORCADO" em HOMOLOGACAO e "Divorciados" em PRODUCAO).

Realmente é um tema interessante e fico ansioso para ver a opinião dos outros foristas.

Abraços,

Sergio Coutinho
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

1) É correto/viável usar surrogate key para tudo ? Inclusive para tabelas de dominio como: Status, Estado Civil, UF?
2) Imaginem uma situação em que eu tenha uma Procedure e precise fazer um Case por Status ou Tipo de Pessoa. Com o primeiro cenário é simples, mas no segundo é complicado pois é tudo ID.
3) O que acham sobre isso? Vale a pena usar ID pra tudo ou fazer um mix conforme o cenário 1?
1- Sim.
2- Depende.
3- Depende.

Hehehehe.
OK, sem ser tão direto agora:

1- Acredito que todas formas são corretas,desde de que bem planejados e avaliado. O que entra em questão é qual a proposta da arquitetura que está sendo implementada. Se você for seguir todas formas normais na arquitetura do banco, fatalmente você acabará em criando várias células minúsculas para representar cada tipo de entidade, e assim eliminar dependencias funcionais e multivaloradas das entidades.
No caso da utilização das CheckConstraints, são muito válidas e dependendo do atributo/informação podem sim ser usadas com mesmo rigor e de fácil manutenção, mas requer mais comprometimento dos envolvidos no sistema.
Uma coisa a se pensar é na volatilidade da informação. Pensemos no caso de UF. Uma coisa relativamente "fixa", porém não é IMPOSSÍVEL que um dia se divida mais um estado e crie outro.
Qual arquitetura se adaptará com mais suavidade a esta alteração? Se tiver uma tabela de UF com codigo e descricao ou um campo de CHECK que terá que alterar na aplicação aquele código e descrição?

2- Sobre a dificuldade do acesso à informação depende da ferramenta a se trabalhar e do nível de conhecimento dela.

3- Vale a pena sim. Se por um lado é mais rigoroso e chato, por outro o deixa mais íntegro, menos susceptível e erros (caso bem planejado). Mas dependendo do atributo Checks Constraints bem planejadas dão conta do recado sim. Como acredito ser seu caso.

OBS: Só por curiosidade: se alguém modelou algum sistema onde uma pessoa era casada com outra e obrigava o cadastro do parceiro a ser do sexo oposto. Bem, recentemente se ferrou. :P.
Rafael_Santos
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 72
Registrado em: Sex, 18 Nov 2011 4:51 pm

Olá a todos,
a minha opinião sobre check constraints seria utiliza-las onde há um regra de négocio, por exemplo já utilizei check constraint em um modelo de banco de ideias onde uma ideia só poderia estar um determinado conjunto([E] em análise, [M] em modificação, [D] em discussão, [A] em aprovação, [X] em execução, implementada) de acordo com o processo que aquela ideia sofria ao longo do tempo ela passava por estas etapas, isso era uma regra do négocio, por isso achei interessante implementar uma check constraint.
Um modelo onde exista uma maioridade um certo campo só liberará se o campo idade for > 18.

Fica minha opinião, mas achei muito interessante este tópico, já compartilhei!
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Normalmente, não existe um jeito melhor pra TUDO. Eu pelo menos, acho que a resposta pra quase tudo é "depende". Tem casos que é bom usar surrogate key. Tem outros, que é melhor usar uma PK mesmo, UNIQUE, etc.

Como eu trabalho para o cliente, normalmente eu não discuto muito isso. Faço conforme a definição ou padrões da empresa :-/
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 16 visitantes