none
Chave primaria de tabela - Qual melhor tipo de dados e por que? RRS feed

  • Pergunta

  • Olá, bom dia a todos.

    Trabalho numa empresa que desenvolvemos módulos de software para uma plataforma chamada Dynamics CRM.

    Notei logo quando vim trabalhar aqui que a chave primaria das tabelas é de um tipo de dados Texto apelidado de 'GUID'.

    Também pude notar que quando vamos integrar nosso sistema com de outros clientes, usamos geralmente um campo texto para identificar os registros.

    Na minha época de faculdade lembro-me dos professores falando que isso não era uma boa prática porque prejudica muita a performance do banco de dados. Gostaria de saber se é realmente verdade e qual seria o porque exatamente(uma explicação mais técnica se possível). E se usar o tipo 'Inteiro' como chave primária ou como qualquer outro campo identificador durante uma integração é recomendável?


    Wagner dos Santos


    • Editado Wagner Santos terça-feira, 6 de outubro de 2015 20:38 Erros de ortografia
    quarta-feira, 30 de setembro de 2015 12:13

Respostas

  • Wagner,

    Realmente o tipo de dados "uniqueidentifier" não deve ser a primeira opção para definir uma coluna como "Chave Primária".

    Não apenas por performance para localizar a informação, uma vez que este "GUID" é uma string alfanumérica que ocupa "16bits", mas também impacta o armazenamento dos dados em disco para a própria "Chave Primária" (índice clusterizado) e bem como outros índices (não clusterizados) que utilizam esta coluna. Para conhecer mais sobre o tipo de dados "uniqueidentifier" veja este documento do BOL:

    https://msdn.microsoft.com/pt-br/library/ms187942(v=sql.120).aspx

    O ideal na modelagem de um banco de dados é que sua(s) coluna(s) que possa(m) ser relacionada(s) como Chave, utilizem o tipo de dados "Numéricos Exatos", que são:

    • bigint
    • numeric
    • bit
    • smallint
    • decimal
    • int
    • tinyint

     É importante analisar os valores que devem ser armazenados para definir o "tipo de dados" ideal para sua solução. Então se você está criando uma tabela para uso de configuração de sistemas, o ideal será utilizar um tipo de dados com pouco armazenamento, como: "smallint" ou "tinyint" (dependendo do caso). Isso diminui a paginação do banco de dados e vai aumentar a performance nas suas consultas e na manipulação de dados.

    Para colunas que exigem maior capacidade, por exemplo, se tratar de "Pedidos de Clientes" ou "Lista de Atendimentos", o ideal é utilizar um "tipo de dados" com maior capacidade, como exemplo: "int" ou "bigint".

    Se houver a possibilidade de ajustes, procure avaliar a possibilidade de substituir esta coluna "GUID" por outra com tipo de dados de "números exatos" até que o processo de relacionamento entre as tabelas seja totalmente refeito.

    Para maiores informações veja:

    https://msdn.microsoft.com/pt-br/library/ms187752%28v=sql.120%29.aspx

    https://technet.microsoft.com/pt-br/library/ms172424(v=sql.110).aspx

    https://msdn.microsoft.com/pt-br/library/ms378715(v=sql.110).aspx


    Se ajudou na sua solução, não esqueça de marcar como resposta !


    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012 | MCSE - Data Platform
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"

    quarta-feira, 30 de setembro de 2015 13:00
    Moderador

Todas as Respostas

  • Wagner,

    Eu geralmente sugiro aos desenvolvedores sempre que possivel criar a chave primaria e o clustered, usando campos inteiro preferencialmente campo que nao tenha muito update e no melhor dos mundos que o campo seja identity.

    Mas isso tem que ver as particularidades de cada projeto.


    Se a resposta foi útil por favor classifique. Tiago Neves - @tiagolneves - acesse o meu blog http://www.tiagoneves.net


    • Editado Tiago_Neves quarta-feira, 30 de setembro de 2015 13:07
    • Sugerido como Resposta _Wagner dos Santos quarta-feira, 30 de setembro de 2015 13:22
    quarta-feira, 30 de setembro de 2015 12:21
  • Wagner,

    Realmente o tipo de dados "uniqueidentifier" não deve ser a primeira opção para definir uma coluna como "Chave Primária".

    Não apenas por performance para localizar a informação, uma vez que este "GUID" é uma string alfanumérica que ocupa "16bits", mas também impacta o armazenamento dos dados em disco para a própria "Chave Primária" (índice clusterizado) e bem como outros índices (não clusterizados) que utilizam esta coluna. Para conhecer mais sobre o tipo de dados "uniqueidentifier" veja este documento do BOL:

    https://msdn.microsoft.com/pt-br/library/ms187942(v=sql.120).aspx

    O ideal na modelagem de um banco de dados é que sua(s) coluna(s) que possa(m) ser relacionada(s) como Chave, utilizem o tipo de dados "Numéricos Exatos", que são:

    • bigint
    • numeric
    • bit
    • smallint
    • decimal
    • int
    • tinyint

     É importante analisar os valores que devem ser armazenados para definir o "tipo de dados" ideal para sua solução. Então se você está criando uma tabela para uso de configuração de sistemas, o ideal será utilizar um tipo de dados com pouco armazenamento, como: "smallint" ou "tinyint" (dependendo do caso). Isso diminui a paginação do banco de dados e vai aumentar a performance nas suas consultas e na manipulação de dados.

    Para colunas que exigem maior capacidade, por exemplo, se tratar de "Pedidos de Clientes" ou "Lista de Atendimentos", o ideal é utilizar um "tipo de dados" com maior capacidade, como exemplo: "int" ou "bigint".

    Se houver a possibilidade de ajustes, procure avaliar a possibilidade de substituir esta coluna "GUID" por outra com tipo de dados de "números exatos" até que o processo de relacionamento entre as tabelas seja totalmente refeito.

    Para maiores informações veja:

    https://msdn.microsoft.com/pt-br/library/ms187752%28v=sql.120%29.aspx

    https://technet.microsoft.com/pt-br/library/ms172424(v=sql.110).aspx

    https://msdn.microsoft.com/pt-br/library/ms378715(v=sql.110).aspx


    Se ajudou na sua solução, não esqueça de marcar como resposta !


    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012 | MCSE - Data Platform
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"

    quarta-feira, 30 de setembro de 2015 13:00
    Moderador
  • Para evitar a perda de rendimento ao utilizar o tipo GUID como chave primária deve-se gerá-lo com a função NEWSEQUENTIALID(utiliza uma lógica sequencial), pois evita que o SQL Server efetue demasiadas buscas em estruturas B-Tree.

    Caso você utilizar a chave primária e gerar o GUID utilizando outro recurso como a função NEWID ou pela aplicação que insere dados no BD, o risco de fragmentação é elevado caso se tratar de índice setorizado. Ou seja, se o GUID não manter a lógica sequencial seu índice deve ser não setorizado.

    O melhor a ser utilizado é um campo INT ou BIGINT que seja identity, ou caso a data(de inclusão) for um dado importante na tabela, utilizar uma chave composta pelo campo de data e o descrito anteriormente(identity).

    Note que para este caso a data deve manter a lógica de inclusão(GETDATE) e que nunca deve ser alterada.

    Isto otimiza busca por range nestas datas.

    quarta-feira, 30 de setembro de 2015 13:12