quinta-feira, 25 de junho de 2009

Atribuição ou Função?

Olá,

Apesar de ser um assunto nada relevante no que se refere à administração de banco de dados Oracle, por incrível que pareça o mesmo sempre me intrigou e que, agora, parece que o "problema" era simplesmente um erro de tradução do termo "role" na camada de mensagens do Oracle Client 10g (release 1) e versões anteriores. No Oracle client 10g (release 2) e 11g, a tradução da mensagem informativa que aparece após a execução do comandos create role e drop role foi devidamente corrigida:

-- Oracle Client 10g release 1
C:\>sqlplus system/******

SQL*Plus: Release 10.1.0.2.0 - Production on Qui Jun 25 13:45:32 2009

Copyright (c) 1982, 2004, Oracle. All rights reserved.

Conectado a:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create role teste;

Função criada.

Podemos ver acima a mensagem "Função criada.", mas eu criei uma atribuição e não uma função! Se alterarmos a sessão para utilizar o idioma Inglês, poderemos perceber abaixo a mensagem "Role dropped." e não "Function dropped.":

SQL> alter session set nls_language=american;

Session altered.

SQL> drop role teste;

Role dropped.

SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit
Production With the Partitioning, OLAP, Data Mining and Real Application Testing options

Irei agora utilizar o SQL*Plus do Oracle Client 11g release 1 ...

-- Oracle Client 11g release 1
C:\>sqlplus system/******

SQL*Plus: Release 11.1.0.6.0 - Production on Qui Jun 25 13:47:02 2009

Copyright (c) 1982, 2007, Oracle. All rights reserved.

Conectado a:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create role teste;

Atribuição criada.

SQL> drop role teste;

Atribuição eliminada.

Realizando o teste utilizando o SQL*Plus do Oracle 10g (release 2) diretamente do servidor onde o banco de dados está instalado, o termo "Atribuição" é corretamente mostrado, o que indica que o "problema", ao meu ver, estava apenas no Oracle Client do Oracle 10g release 1 e versões anteriores:

[oracle@linux ~]$ export NLS_LANG="BRAZILIAN PORTUGUESE_BRAZIL.WE8ISO8859P1"
[oracle@linux ~]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Qui Jun 25 15:13:07 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Conectado a:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create role teste;

Atribuição criada.

SQL> drop role teste;

Atribuição eliminada.


quarta-feira, 17 de junho de 2009

Definição de senhas case-sensitive no Oracle 11g ...

Olá,

Para quem está planejando migrar o seu atual banco de dados Oracle para a mais recente versão Oracle 11g, ao utilizar o DBCA (Database Configuration Assistant), irá se deparar com uma nova tela de configuração intitulada de "Definições de Segurança". O objetivo desta tela é configurar, além de algumas definições padrão de auditoria, um novo perfil de senhas como mostrado na figura abaixo:



As configurações de segurança padrão ativam a auditoria para muitos privilégios de sistemas diferentes, como create session, create user, drop user, create any procedure, alter system, alter database, entre outras, de forma a seguir algumas exigências normativas definidas na legislação americana Sarbanes-Oxley (SOX).

O objetivo deste artigo é demonstrar a nova funcionalidade de senhas case-sensitive do Oracle 11g que, até então, eram case-insensitive, ou seja, no Oracle 11g existe a diferenciação entre letras maiúsculas e minúsculas na definição de uma senha de usuário de banco de dados. Por exemplo: Nas versões anteriores ao Oracle 11g, caso criássemos um usuário de banco de dados SCOTT e definíssemos sua senha para TIGER, poderíamos então nos conectar no banco de dados através deste usuário digitando a senha TIGER, Tiger, tiger, TiGer ou tiGER, sem qualquer distinção entre letras maiúsculas e minúsculas.

Agora no Oracle 11g, ao escolher a primeira opção conforme mostrado na figura acima, o banco de dados fará distinção entre letras maiúsculas e minúsculas ao entrar com a senha do usuário. No exemplo anterior, a senha do usuário SCOTT foi definida como TIGER (todas em maiúsculas), portanto, a conexão com o banco de dados só será bem sucedida caso a senha seja fornecida seja TIGER, não mais Tiger, tiger, TiGer ou tiGER.

Podemos ver abaixo o novo parâmetro de inicialização responsável por implementar este novo perfil de senhas case-sensitives no Oracle 11g:

SQL> show parameter sec_case_sensitive_logon

NAME                                 TYPE        VALUE
------------------------------------ ----------- --------------------------
sec_case_sensitive_logon             boolean     TRUE
 
Como demonstrado acima, o parâmetro SEC_CASE_SENSITIVE_LOGON está atualmente configurado como TRUE, ou seja, para realizar uma conexão bem sucedida no banco de dados, um usuário deverá fornecer a senha exatamente como foi definida durante a criação do usuário (diferenciando maiúsculas e minúsculas), isso supondo que a mesma tenha sido definida já no próprio Oracle 11g. Vamos então a um exemplo prático:

C:\>sqlplus / as sysdba

SQL*Plus: Release 11.1.0.6.0 - Production on Qua Jun 17 09:32:49 2009

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Conectado a:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SYS> create user scott identified by tiger;

Usuário criado.

SYS> grant connect to scott;

Concessão bem-sucedida.

SYS> connect scott/TIGER
ERROR:
ORA-01017: senha/nome do usuário inválido; log-on negado


Advertência: Você não está mais conectado ao ORACLE.
@> connect scott/Tiger
ERROR:
ORA-01017: senha/nome do usuário inválido; log-on negado


@> connect scott/TiGer
ERROR:
ORA-01017: senha/nome do usuário inválido; log-on negado


@> connect scott/tiGER
ERROR:
ORA-01017: senha/nome do usuário inválido; log-on negado


@> connect scott/tiger
Conectado.
 
De acordo com a demonstração acima, podemos perceber que o usuário SCOTT só conseguiu se logar no banco de dados quando a senha "tiger" (todas em minúsculas) foi fornecida. Ao consultarmos a view de dicionário de dados DBA_USERS, poderemos perceber duas mudanças significativas:

SYS> select username, password, password_versions from dba_users;

USERNAME              PASSWORD                 PASSWORD_VERSIONS
--------------------- ------------------------ -----------------
MGMT_VIEW                                      10G 11G
SYS                                            10G 11G
SYSTEM                                         10G 11G
DBSNMP                                         10G 11G
SYSMAN                                         10G 11G
SCOTT                                          10G 11G
OUTLN                                          10G 11G
ANONYMOUS
WMSYS                                          10G 11G
XDB                                            10G 11G
DIP                                            10G 11G
ORACLE_OC                                      10G 11G
TSMSYS                                         10G 11G
XS$NULL                                        10G 11G

14 linhas selecionadas. 

A primeira mudança que podemos notar é que a informação do valor hash da senha na coluna PASSWORD não é mais mostrada como nas versões anteriores do Oracle, portanto, a mesma foi omitida no Oracle 11g, mas nada nos impede visualizar o seu valor hash na tabela base de dicionário de dados SYS.USER$.

SYS> select name,password from sys.user$ where name='SCOTT';

NAME                       PASSWORD
-------------------------- ------------------------------
SCOTT                      F894844C34402B67
 
Vale a pena salientar que o novo valor hash gerado pela senha case-sensitive é armazenada na coluna SPARE4 da tabela base SYS.USER$ do dicionário de dados.
Uma outra mudança perceptível na view de dicionário de dados DBA_USERS foi adição de uma nova coluna chamada PASSWORD_VERSIONS que indica em qual versão do Oracle a senha do usuário foi criada.

O valor "10g 11g" significa que a senha em questão possui informações hash tanto na coluna PASSWORD quanto na coluna SPARE4 da tabela base SYS.USER$, e que a mesma pode ou não ser case-sensitive (Isso vai depender se o parâmetro SEC_CASE_SENSITIVE_LOGON está ativado ou não).

O valor "10g" significa que somente a coluna PASSWORD possui a informação hash da senha do usuário, indicando que independente do parâmetro SEC_CASE_SENSITIVE_LOGON estar ativado ou não, a senha deste usuário vai ser case-insensitive até que a mesma seja alterada.

O valor "11g" indica que somente a coluna SPARE4 possui a informação hash da senha do usuário, indicando que a mesma é case-sensitive, portanto, o usuário conseguirá se conectar no banco de dados apenas quando o parâmetro SEC_CASE_SENSITIVE_LOGON estiver configurado com o valor TRUE (ativado). Abaixo irei realizar uma pequena demonstração:

SYS> alter user scott identified by TIGER;

Usuário alterado.

SYS> select password,spare4 from user$ where name='SCOTT';

PASSWORD                   SPARE4
-------------------------- --------------------------------------------------------------
F894844C34402B67           S:2CA14104071F06830C95527377C53B0DBF0349DE1B7BF4238EA663C806FD

SYS> select password_versions from dba_users where username='SCOTT';

PASSWORD
--------
10G 11G

SYS> alter user scott identified by values 'F894844C34402B67';

Usuário alterado.

SYS> select password,spare4 from user$ where name='SCOTT';

PASSWORD                   SPARE4
-------------------------- ----------------------------------------------------------
F894844C34402B67

SYS> select password_versions from dba_users where username='SCOTT';

PASSWORD
--------
10G

SYS> alter user scott identified 
  2  by values 'S:2CA14104071F06830C95527377C53B0DBF0349DE1B7BF4238EA663C806FD';

Usuário alterado.

SYS> select password,spare4 from user$ where name='SCOTT';

PASSWORD                   SPARE4
-------------------------- --------------------------------------------------------------
                           S:2CA14104071F06830C95527377C53B0DBF0349DE1B7BF4238EA663C806FD

SYS> select password_versions from dba_users where username='SCOTT';

PASSWORD
--------
11G
 
Em resumo, quando se define uma nova senha de usuário utilizando o Oracle 11g, a mesma irá atualizar os valores hash nas colunas PASSWORD e SPARE4 independente do parâmetro SEC_CASE_SENSITIVE_LOGON estiver ativado ou não.

Portanto, quando migramos usuários de versões Oracle anteriores (8i, 9i, 10g) para o Oracle 11g, seja utilizando uma importação FULL com o tradicional utilitário de importação (imp), ou usando o utilitário Import Datapump (impdp), nas quais as senhas dos usuários são case-insensitives, as senhas desses usuários continuarão case-insensitives, independente do parâmetro SEC_CASE_SENSITIVE_LOGON estar ativado ou não.

No caso de usuários com privilégios SYSDBA e SYSOPER, um outro parâmetro foi adicionado ao utilitário orapwd de forma a controlar senhas case-sensitives no arquivo de senhas:

$ orapwd file=orapwBD01 entries=5 ignorecase=y password=minha_senha
 
O parâmetro ignorecase, demonstrado no comando acima, pode ter o valor "n" (default), informando que as senhas serão tratadas como case-sensitives, ou "y" informando que as senhas serão tratadas como case-insensitives.

Para finalizar, e aproveitando o assunto de segurança de acesso e senhas de usuários, agora no Oracle 11g foi também disponibilizada uma view de dicionário de dados DBA_USERS_WITH_DEFPWD que ajuda o DBA a identificar quais usuários possuem a senha padrão "default" desde a criação do banco de dados, de forma que as mesmas possam ser alteradas quando possível:

SYS> select * from dba_users_with_defpwd;

USERNAME
------------------------------
DIP
XS$NULL
TSMSYS
OUTLN
EXFSYS
ORACLE_OCM
XDB
WMSYS

8 linhas selecionadas.

domingo, 7 de junho de 2009

Banco de Dados: Este mercado é promissor? Vale a pena a certificação?

Olá,

Recebi de um leitor uma questão relacionada ao mercado de banco de dados e certificações Oracle, e resolvi então publicar aqui de forma a compartilhar e expor o meu humilde ponto de vista.


Olá Eduardo Legatti,

primeiramente quero parabenizar pelo blog, sendo uma ótima fonte de estudos, cheguei até ele através do google, quando procurava informações sobre certificação Oracle OCA.

Estou começando meus estudos na área, faço Análise e Desenvolvimento de Sistemas e ao estudar pela primeira vez Banco de Dados, tive uma enorme vontade de me especializar em algum banco específico, pesquisando pela web percebi que é uma boa estudar Oracle, desde então venho buscando fontes de estudo.

Até mais.. e mais uma vez parabéns.

ps: ao seu ver, esse mercado é promissor, vale a pena a certificação?


Primeiramente, obrigado pelo comentário. Realmente acho que o mercado de banco de dados, seja ele Oracle, MS SQL Server, DB2, etc.. é promissor.

Na minha visão, o mercado de trabalho para um DBA é a mesma para qualquer outra área de tecnologia. Tudo depende da demanda do mercado. Por exemplo, às vezes acontece de empresas estarem muito precisando de um profissional trainee para trabalhar com administração de banco de dados Oracle e/ou MS SQL Server. Também, não é raro existirem muitas demandas de profissionais que tenham conhecimentos básicos em DB2 da IBM, ou PostgreSQL ou MySQL, ou Oracle para cargo de trainee.

Acredito que para entrar nesta área, o profissional necessitará ter o conhecimento mínimo básico para iniciar um trabalho de trainee ou DBA Júnior.

Olha, tem muita gente que tira certificação sem qualquer experiência na área achando que com isso irá conseguir um emprego rápido. Na verdade, a certificação vai dar uma maior visibilidade no currículo e chamar a atenção de quem está recrutando. Isso mostra que um profissional certificado tem mais oportunidades de quem não tem certificação. Quem tira certificação em uma determinada tecnologia, na verdade, está assinando que é um "expert" na mesma, ou seja, a certificação ajudou o profissional a ser chamado para uma entrevista. Agora, se nessa entrevista, o mesmo não demonstrar nenhuma experiência e/ou habilidades necessárias para ocupar o cargo, então pode ter certeza de que o mesmo não será contratado. Infelizmente ou felizmente, é o mercado quem dita as regras, portanto, é necessário que estejamos sempre preparados. No mais, com certeza vale a pena a certificação.

Em relação às fontes de estudo, quando eu estava estudando para tirar a certificação OCA/OCP 9i, eu estava estudando pelos manuais oficiais de quando eu fiz os cursos do Oracle 9i. Eu também tinha comprado os livros "OCA/OCP Introdução ao Oracle 9i SQL (1Z0-007)" e "OCA/OCP Oracle9i Database Fundamentos I (1Z0-031)" ambos da Oracle Press - Autor Jason Couchman. Posteriormente, quando estava estudando para atualizar a minha certificação OCP 9i para OCP 10g, passei mais tempo praticando no próprio banco de dados Oracle 10g e lendo mais a documentação oficial.

Agora, se você está estudando para tirar a certificação do Oracle 10g ou 11g (Recomendo o 11g), então eu sempre indico os manuais da SYBEX porque eles abordam todos os tópicos que caem nos exames. Outra coisa que também acho importante é a de praticar nos simulados da SelfTest ou Transcender. Caso você consiga algum material (no Google), os mesmos serão muito úteis para o seu aprendizado.

Aproveitando a sua questão, e já que você está cursando "Análise e Desenvolvimento de Sistemas", vou comentar um pouco de perfis de DBA's. Bom, acredito que existam no mínimo 2 tipos de DBA's hoje no mercado.

O tipo 1 seria aquele DBA que trabalha no servidor de produção, realizando manutenções necessárias de tuning, sugerindo ajustes de memória e I/O quando necessários, fazendo realocações de arquivos de banco de dados, criando e executando políticas de backup/recovery, realizando aplicações de patches e correções críticas, entre outras, sem ter uma noção clara de como os SQL’s foram codificados nas aplicações de terceiros que são executadas no servidor.

O outro tipo de DBA (tipo 2) que é mais o meu caso, é aquele voltado para o desenvolvimento de aplicações na qual, é de fundamental importância, o conhecimento das regras de negócios em questão, de forma a fornecer a melhor solução de banco de dados para um determinado tipo de problema, além de possuir conhecimentos sólidos de modelagem de dados, ser apto a sugerir a criação de um padrão de nomenclatura de objetos de banco de dados e, conseqüentemente, ser apto de fiscalizar e garantir o uso desse padrão pelos analistas de sistemas e desenvolvedores. Outra tarefa seria a criação de uma política de melhores práticas de construções de instruções SQL, realização de análise de performance dos SQL’s construídos de forma a capturar o melhor plano de acesso aos registros e, assim, realizar os ajustes necessários avaliando a necessidade de criação de índices (btree/bitmap), views materializadas, tabelas/índices particionados, etc…

Em resumo, o trabalho do DBA tipo 2 seria mais de prover suporte à equipe de desenvolvimento, garantindo asimm a qualidade das aplicações desenvolvidas no que se refere ao modelo de dados e acesso ao banco de dados.

Fazendo uma comparação, acredito que um bom trabalho realizado pelo DBA tipo 2 facilitaria muito, em parte, o trabalho realizado pelo DBA tipo 1.

Boa sorte e até mais ...

quinta-feira, 4 de junho de 2009

Dúvidas sobre modelagem de dados ...

Olá,

Recentemente recebi de um colega, uma dúvida sobre modelagem de dados e resolvi então compartilhar aqui.

Cenário:

Possuo um cadastro de clientes que usa o serviço de hospedagem de sites e um outro cadastro que utiliza o serviço de registro de domínios. A grande questão é como representar isso, os casos são os seguintes:


  • Um cliente pode ter somente o serviço de hospedagem de sites, logo, todos os seus dados estariam na tabela de hospedagem.
  • Um cliente pode ter somente o serviço de registro de domínios, logo, todos os seus dados estariam na tabela de registro de domínios.
  • Um cliente pode ter ambos os serviços, logo, teria dados nas 2 tabelas, mas, esses dados poderiam ser os mesmos, como também não poderiam.


Detalhe: Essa estrutura precisaria ser preparada para num futuro próximo aumentar os serviços, ou seja, além de hospedagem e domínios, possuir outros, loja virtual, etc.


Enfim, imaginei uma terceira tabela para controlar isso, mandei um esboço em anexo mas estou receoso devido ao fato de com isso existirem muitas chaves estrangeiras nulas e a aplicação precisaria descobrir em qual tabela estariam os dados do cliente.


Solução:

Bem, em relação ao último parágrafo do texto acima, posso dizer que chaves estrangeiras nulas não são problema algum. Imagine que eu tenha uma tabela de clientes onde a mesma possua uma coluna (id_servico) que armazene códigos de serviços, e que a mesma referencie a tabela de serviços.


Se pode haver clientes que não prestam nenhum serviço, então poderiam existir vários clientes onde a coluna id_serviço estaria NULA.


Não se pode confundir chave estrangeira com chave primária. Chave primária é obrigatória, mas chave estrangeira pode ou não ser obrigatória e isso vai depender da regra de negócio em questão.


Voltando ao cenário proposto, isso está me parecendo um relacionamento simples onde "Um Cliente pode prestar vários serviços" e "Um serviço pode ser prestado por vários clientes".

Se você quer uma estrutura flexível e, já pensando em um futuro próximo, permitir o registro de mais serviços, então criar tabelas específicas para armazenar cada serviço seria praticamente inviável e sem sentido. Acredito que com apenas 3 tabelas o seu problema seria solucionado, mas para complicar um pouco avalie se uma quarta tabela seria útil para você. Então, neste caso, avalie a solução abaixo:

1) criar uma tabela de clientes
2) criar uma tabela de serviços
3) criar uma tabela que armazenará os serviços que cada cliente poderá prestar

4) criar uma tabela com colunas adicionais que registrará todos os serviços de todos os clientes


Portanto, tome como exemplo os dados abaixo de acordo com o modelo acima proposto:


=======
CLIENTE
=======

ID_CLIENTE NOME_CLIENTE
---------- ------------
         1 Cliente A
         2 Cliente B
         3 Cliente C


=======
SERVICO
=======

ID_SERVICO NOME_SERVICO
---------- -------------------
         1 Hospedagem de sites 
         2 Registro de domínio
         3 Loja Virtual
         4 Outro, etc...

Abaixo irei definir quais serviços cada cliente poderá prestar:

===============
CLIENTE_SERVICO
===============

ID_CLIENTE ID_SERVICO
---------- ----------
         1          1
         1          2
         2          3
         3          2
         4          1

Para finalizar, a tabela REGISTRO abaixo armazenaria todos os serviços de todos os clientes sendo que a coluna ID_REGISTRO seria um seqüencial.


========
REGISTRO
========

ID_REGISTRO ID_CLIENTE ID_SERVICO ENDERECO_WEB ETC...
----------- ---------- ---------- ------------ ------
          1          1          1 http:// .... ... 
          2          1          2 http:// .... ...
          3          2          3 http:// .... ...
          4          3          2 http:// .... ...
          5          4          1 http:// .... ...


Como você viu acima, a tabela REGISTRO, a princípio, parece ser redundante no modelo pois faz o mesmo papel da tabela CLIENTE_SERVICO mas, neste caso, você poderia armazenar mais registros do mesmo serviço para o mesmo cliente. Por outro lado, bastaria também fazer um relacionamento não identificado na tabela CLIENTE_SERVICO onde as colunas ID_CLIENTE e ID_SERVICO seriam apenas chaves estrangeiras, e não chaves primárias.


Dependendo do caso, você poderá trabalhar somente com a tabela CLIENTE_SERVICO deixando a tabela REGISTRO fora do modelo, ou seja, a tabela REGISTRO seria opcional.

No mais, isso realmente vai depender das regras de negócios envolvidas na sua aplicação de forma a atingir os requisitos necessários.


Enfim, de acordo com o modelo e na minha visão, a tabela CLIENTE_SERVICO teria apenas o papel de armazenar de forma parametrizável o que cada cliente poderia fornecer, obedecendo assim, o requisito na qual você diz que "Um cliente poderá ter somente o serviço X ou Y ou ambos ..."