Padronização de Nomenclatura de Banco de Dados

Eis uma coisa complicada. Cada programador, analista ou DBA tem uma forma de entender e montar uma estrutura de banco de dados.

Lembro-me do tempo do CLIPPER onde os arquivos DBF´s e NTX´s eram bem limitados. Tinha um esquema comumente chamado de 8.3 para nome de tabelas e quantidade limitada de caracteres para nome de campos. Tinhamos que fazer verdadeiros milagres no momento de dar nome as campos das tabelas. Haja abreviações. Era preciso definir padrões para as abreviações, bem documentados, para que outro programador pudesse entender, ou mesmo, o próprio desenvolvedor entendesse o que havia feito na hora de dar manutenção no sistema.

Com o avanço tecnológico, muita coisa mudou nessa área. Por exemplo, a evolução dos sistemas operacionais nos permite indentificar com mais clareza os arquivos. De igual forma, os bancos de dados relacionais. Houve um aumento no tamanho permitido para nome de tabelas, campos, chaves, etc.

Porém, com todo esse avanço, vejo que muita gente quer preservar algumas características legadas para dar nome às entidades relacionais do banco de dados. Por exemplo: um campo da tabela que servirá pra guardar endereço, há quem utilize END para nome do campo; um campo utilizado pra guardar a razão social, ha quem utilize RAZ_SOC para nomear o campo. Eu pergunto: PRA QUE TANTA ABREVIAÇÃO DE NOMES, HOJE EM DIA? Se o banco permite, porque não utilizar os nomes sem abreviações desnecessárias?! As justificativas apresentadas são as mais variadas. Mas não ouvi nenhuma que seja realmente convicente. Inclusive, se for uma prática do leitor usar essaS abreviaturas nos bancos de dados atuais, peço que registre um comentário explicando o seu motivo pra abreviar.

Mas não é só essa questão. Por exemplo, alguns analistas tem o costume de identificar os tipos de entidade no nome da entidade. Por exemplo: A tabela de usuários será nomada assim: TB_USUARIO. Uma vez eu vi uma situação que achei um excesso. Uma tabela com o seguinte nome de campo: TB_USUARIO_LOGIN, ou seja, o nome da tabala compondo o nome do campo. Essa prática é pouco indicada pra quem trabalha com orientação a objeto. Quem trabalha mapeamento O/R (como no Hibernate, por exemplo) terá um trabalho dobrado pra reduzir estes nomes; para adequar os nomes das tabelas à definição das classes persistentes.

Mas a realidade é essa: cada um com sua forma de pensar. Nas próximas linhas vou definir a minha. Como eu utilizo geradores de código apartir de definições de banco, é importante adotar um comportamento padrão. Vamos lá.

Definições Gerais

  1. Evitar abreviações. O nome completo deve ser preferido.
  2. Só utilizar letras maiúsculas.
  3. O nome das entidades de banco deve ser no sigular.
  4. Procurar utilizar nomes que identifiquem sua utilidade e aplicação.
  5. Para nomes compostos, separar com underline, por exemplo: RAZAO_SOCIAL.
  6. Evitar usar o nome da entidade em seus componentes internos, por exemplo: Se o nome da tabela for PACIENTE, o campo para preenchimento com o nome do paciente será NOME e não NOME_PACIENTE.

Tabelas

Para objetos relacionados com tabelas (chave primaria, chave estrangeira, campos, indices, etc.) vamos adotar o seguinte comportamento:

Chave Primaria

  1. Não usar chave primária composta.
  2. Deve ser sempre o primeiro campo na tabela e ser formado por “ID_NOME_DA_TABELA”. Para tabela PACIENTE, por exemplo, o champo de chave primária será ID_PACIENTE.
  3. O tipo do campo deve ser do tipo numérico mais abrangente possível ( numeric[18,0], bigint ), auto-incremental, com sequence ou generator, se necessário. Não use triggers para auto-incrementar o campo.

índices

  1. Deve ser criado sempre; de acordo com as necessidades de ajuste do banco. Normalmente os campos utilizados para ordenação e filtro nas querys precisam de índices.
  2. Para os campos que poderiam ter sido escolhidos para chave primária composta, construir o indice com a combinação dos campos utilizando índices marcados como únicos (unique).
  3. Seguindo uma sugestão de um de nossos leitores (Moriarty), deve ser formado por IX_TABELA_CAMPO. Por exemplo: a tabela PACIENTE terá dois índices, nome e registro: IX_PACIENTE_NOME e IX_PACIENTE_REGISTRO. Essa forma subistituiu a anterior onde no lugar do nome do campo a utilização era de um número sequencial, por exemplo, IX_PACIENTE1, IX_PACIENTE2….

Chaves estrangeiras

  1. Na tabela, o nome do campo deve ser igual ao campo chave primária da tabela a que corresponde.
  2. Indentificado assim: FK_NOME_DA_TABELA_NOME_DA_TABELA_ESTRANGEIRA. Por exemplo: a tabela PACIENTE possui uma chave estrangeira para tabela SEXO cuja chave primária é ID_SEXO. O nome do campo na tabela PACIENTE deve ser também ID_SEXO e o nome da chave estrangerira será FK_PACIENTE_SEXO.
  3. Se o nome ficar muito grande e o banco não aceitar criar, nesse caso, é permitido uma abreviação.

Restrições (constraint)

  1. A única restrição obrigatório é a NOT-NULL. Obviamente as restrições de relacionamento e índices são indispensáveis. Outras como por exemplo, as restrições para valores válidos nos campos, são opcionais.

Tipos

  1. Respeite o tipo de dado para o campo. Campo data para guardar datas, numéricos para guardar números, etc.
  2. Alguns bancos disponibilizam tipos comum com quantidade de bytes reduzidas. Por exemplo: para campo numérico existe: int, smallint, tynint, etc. Procure evitar as variações. Prefira os tipos que são comuns a todos os tipos de bancos. Use os tipos abaixo. Eles costumam ter tamanho bem definido e nome de tipos comuns a todos os bancos.
  • Numéricos: int ou integer
  • Data: DateTime ou TIMESTAMP
  • String: varchar
  • Boolean: smallint ou bit
  • Campos bynários ou longos: BLOB

SEQUENCE ou GENERATOR

  1. Deve ser criada da seguinte forma: GEN_NOME_DA_TABELA_ID. Para a tabela PACIENTE crie um sequence ou generator GEN_PACIENTE_ID.
  2. Se o nome ficar muito grande e o banco não aceitar criar, nesse caso, é permitido alguma abreviação.

Visões

  1. O nome da view deve ser V$NOME_VIEW ou VNOME_VIEW. Ex: V$PACIENTE_INTERNADO ou VPACIENTE_INTERNADO

Procedures, Functions, Triggers…

Eu evito terminantemente utilizar objetos que possam exigir reescrita caso seja necessário mudar de banco de dados, exceto as views, claro. Inclusive eu escrevi um post sobre “Independência de Banco de Dados”. Leia mais…

Nas aplicações…

  1. Na criação de junções utilizar explicitamente somente a combinação chave primaria/estrangeria definida no projeto físico do banco.
  2. As seleções de dados devem sempre utilizar um campo que possua índice. O banco deve ser planejado para realizar pesquisas utilizando os índices.
  3. Nas pesquisas com LIKE, o ‘%’ deve ser usado sempre no final da seleção evitando seu uso no início da string. Isso melhora a performance da pesquisa.
  4. Quando abrir um transação deve-se testar antes todas as possibilidades de a transação poder ser completada, ou seja, as validações de dados, testes de integridade referencial, testes de violações de chaves, etc. devem ser feitas antes da abertura da transação. O ‘rollback’ de uma transação deve ser preferencialmente utilizado apenas para erros internos de banco e não por violação de alguma regra de negócio.
  5. Evitar ‘select * from tabela’. Deve-se discriminar exatamente os campos de retorno da seleção. Além disso as seleções devem ter algum objetivo, ou seja, uma condição deve ser informada especialmente em tabelas com grande número de linhas. Evitar deixar a cargo da aplicação os filtros e as seleções de dados que poderiam ser realizadas diretamente pelo banco através de uma query.
  6. Mesmo que restrições ou constraints estejam definidas no banco a aplicação deve também realizar essas verificações.

É isso. Espero ter ajudado. Quem tiver alguma maneira diferente de entender ou enxergar este assunto, por favor, não deixe de registrar um comentário ou me enviar por email. Desde já obrigado.

Blz!

Anúncios