Início / Trilha 2 / Conteúdo / Tópico 7
7

Schemas e Owners

Organização de objetos, propriedade e acesso no Oracle

📖

O que é um Schema no Oracle?

Definição

Um Schema no Oracle é uma coleção lógica de objetos de banco de dados (tabelas, views, índices, procedures, etc.) que pertencem a um usuário específico. É o namespace que agrupa e organiza todos os objetos criados por ou para um determinado usuário.

Particularidade do Oracle: Schema = User

No Oracle, todo usuário possui automaticamente um schema com o mesmo nome. Quando você cria um usuário, o Oracle cria um schema correspondente. Esta é uma característica única do Oracle que difere de outros SGBDs como PostgreSQL, SQL Server e MySQL.

  • Criar usuário HR automaticamente cria o schema HR
  • O schema não pode existir sem o usuário correspondente
  • Objetos criados pelo usuário HR pertencem ao schema HR

Comparação com outros SGBDs:

SGBD Conceito de Schema
Oracle Schema = User (1:1, inseparável)
PostgreSQL Schema é namespace independente, user pode ter múltiplos schemas
SQL Server Schema é namespace, separado de usuários/logins
MySQL Schema = Database (sinônimos), separado de usuários

Exemplo Prático

-- Criar usuário automaticamente cria o schema
CREATE USER app_vendas IDENTIFIED BY senha123
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;

GRANT CONNECT, RESOURCE TO app_vendas;

-- Conectar como app_vendas
CONNECT app_vendas/senha123

-- Criar objetos - eles pertencem ao schema APP_VENDAS
CREATE TABLE produtos (
    produto_id NUMBER PRIMARY KEY,
    nome VARCHAR2(100),
    preco NUMBER(10,2)
);

CREATE TABLE clientes (
    cliente_id NUMBER PRIMARY KEY,
    nome VARCHAR2(100),
    email VARCHAR2(100)
);

-- Verificar schema atual
SELECT SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') FROM DUAL;
-- Retorna: APP_VENDAS
👤

Owner de Objetos

Conceito de Owner (Proprietário)

O Owner de um objeto é o schema (e portanto o usuário) que o criou. O owner tem privilégios completos sobre o objeto sem necessidade de grants explícitos.

Privilégios do Owner

  • Controle total sobre o objeto
  • Pode alterar estrutura (ALTER)
  • Pode deletar o objeto (DROP)
  • Pode conceder acesso a outros (GRANT)
  • Não precisa de permissões explícitas

Transferir Ownership

O Oracle não permite transferir ownership diretamente. Para mudar o owner, é necessário:

  • Exportar com DATAPUMP ou exp
  • Importar para o novo schema
  • Ou recriar o objeto no novo schema

Identificar o Owner de um Objeto:

-- Ver owner de tabelas específicas
SELECT owner, table_name, tablespace_name
FROM ALL_TABLES
WHERE table_name = 'PRODUTOS';

-- Ver todos os objetos e seus owners
SELECT owner, object_name, object_type, status
FROM ALL_OBJECTS
WHERE object_name LIKE 'PROD%'
ORDER BY owner, object_type, object_name;

-- Ver objetos de um schema específico
SELECT object_name, object_type, created, last_ddl_time
FROM ALL_OBJECTS
WHERE owner = 'APP_VENDAS'
ORDER BY object_type, object_name;
🔗

Prefixação schema.objeto

Notação Completa

A forma completa de referenciar um objeto no Oracle é: SCHEMA.OBJETO. Quando você omite o schema, o Oracle assume que você está referenciando um objeto no schema atual.

Formas de Referenciar Objetos:

-- Conectado como APP_VENDAS

-- 1. Sem prefixo - assume schema atual (APP_VENDAS)
SELECT * FROM produtos;
-- Oracle procura: APP_VENDAS.PRODUTOS

-- 2. Com prefixo explícito - acessa outro schema
SELECT * FROM hr.employees;
-- Oracle procura: HR.EMPLOYEES (precisa de privilégio)

-- 3. Próprio schema explícito (redundante mas válido)
SELECT * FROM app_vendas.produtos;
-- Oracle procura: APP_VENDAS.PRODUTOS

-- 4. JOIN entre schemas diferentes
SELECT
    v.produto_id,
    v.nome AS produto,
    e.first_name AS vendedor
FROM app_vendas.produtos v
INNER JOIN hr.employees e ON v.vendedor_id = e.employee_id;

Boas Práticas de Prefixação

  • Em código SQL de aplicação: sempre use prefixo schema.objeto para clareza e evitar ambiguidade
  • Em PL/SQL packages: prefixe objetos de outros schemas, não os do próprio schema
  • Em scripts de deploy: sempre use prefixo para garantir que o objeto correto é afetado
  • Em desenvolvimento ad-hoc: pode omitir prefixo se estiver no schema correto

Resolução de Nomes (Name Resolution)

Quando você referencia um objeto sem schema, o Oracle segue esta ordem de busca:

1.

Schema Atual (CURRENT_SCHEMA)

Primeiro procura no schema da sessão atual

2.

Sinônimos Privados

Verifica se existe sinônimo privado no schema atual

3.

Sinônimos Públicos (PUBLIC)

Por último, verifica sinônimos públicos

-- Exemplo de resolução de nomes
-- Conectado como APP_VENDAS

-- Busca nesta ordem:
-- 1. APP_VENDAS.EMPLOYEES
-- 2. Sinônimo privado APP_VENDAS.EMPLOYEES
-- 3. Sinônimo público PUBLIC.EMPLOYEES
SELECT * FROM employees;
🔐

Acessando Objetos de Outro Schema

Privilégios Necessários

Para acessar objetos de outro schema, você precisa de privilégios explícitos concedidos pelo owner ou por um usuário com privilégio GRANT ANY OBJECT PRIVILEGE.

Concessão de Privilégios Entre Schemas:

-- Conectado como HR (owner da tabela EMPLOYEES)

-- Conceder SELECT para outro usuário/schema
GRANT SELECT ON hr.employees TO app_vendas;

-- Conceder múltiplos privilégios
GRANT SELECT, INSERT, UPDATE ON hr.departments TO app_vendas;

-- Conceder com opção de repassar (WITH GRANT OPTION)
GRANT SELECT ON hr.jobs TO app_vendas WITH GRANT OPTION;

-- Agora APP_VENDAS pode acessar
CONNECT app_vendas/senha123

SELECT employee_id, first_name, last_name
FROM hr.employees
WHERE department_id = 50;

-- E pode repassar o privilégio (porque recebeu WITH GRANT OPTION)
GRANT SELECT ON hr.jobs TO outro_usuario;

Tipos de Privilégios de Objeto

  • SELECT - Consultar dados
  • INSERT - Inserir novas linhas
  • UPDATE - Modificar dados existentes
  • DELETE - Remover linhas
  • ALTER - Alterar estrutura (raro conceder)
  • INDEX - Criar índices na tabela
  • REFERENCES - Criar foreign keys
  • EXECUTE - Executar procedures/functions/packages

Verificar Privilégios Concedidos

-- Ver privilégios que VOCÊ concedeu a outros
SELECT grantee, table_name, privilege, grantable
FROM USER_TAB_PRIVS_MADE
ORDER BY grantee, table_name;

-- Ver privilégios que VOCÊ recebeu de outros
SELECT owner, table_name, privilege, grantable
FROM USER_TAB_PRIVS_RECD
ORDER BY owner, table_name;

-- Ver TODOS os privilégios de objetos (como DBA)
SELECT owner, table_name, grantee, privilege, grantable
FROM DBA_TAB_PRIVS
WHERE owner = 'HR'
ORDER BY table_name, grantee;

-- Revogar privilégios
REVOKE SELECT ON hr.employees FROM app_vendas;
REVOKE ALL ON hr.departments FROM app_vendas;
🔄

ALTER SESSION SET CURRENT_SCHEMA

Mudando o Schema Padrão da Sessão

O comando ALTER SESSION SET CURRENT_SCHEMA permite que você mude o schema padrão da sessão sem se reconectar. Isso é útil quando você precisa trabalhar com objetos de outro schema mas não quer prefixar cada referência.

Importante:

  • Muda apenas o schema padrão, não o usuário conectado
  • Você continua autenticado como o usuário original
  • Privilégios permanecem os do usuário original
  • Muito usado em scripts de manutenção e ferramentas de migração
  • A mudança dura apenas a sessão atual

Exemplo Prático:

-- Conectado como SYSTEM
CONNECT system/senha

-- Verificar schema atual
SELECT SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') AS current_schema,
       SYS_CONTEXT('USERENV', 'SESSION_USER') AS session_user
FROM DUAL;
-- current_schema: SYSTEM
-- session_user: SYSTEM

-- Mudar para schema HR
ALTER SESSION SET CURRENT_SCHEMA = hr;

-- Verificar novamente
SELECT SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') AS current_schema,
       SYS_CONTEXT('USERENV', 'SESSION_USER') AS session_user
FROM DUAL;
-- current_schema: HR
-- session_user: SYSTEM (ainda conectado como SYSTEM!)

-- Agora pode referenciar objetos sem prefixo
SELECT COUNT(*) FROM employees;  -- Acessa HR.EMPLOYEES
SELECT COUNT(*) FROM departments;  -- Acessa HR.DEPARTMENTS

-- Voltar ao schema original
ALTER SESSION SET CURRENT_SCHEMA = system;

Casos de Uso Comuns

1. Scripts de Manutenção como DBA

-- Conectar como DBA mas trabalhar no schema da aplicação
CONNECT dba_user/senha
ALTER SESSION SET CURRENT_SCHEMA = app_vendas;

-- Executar manutenção sem prefixar cada objeto
ANALYZE TABLE produtos COMPUTE STATISTICS;
REBUILD INDEX idx_produtos_nome ONLINE;
UPDATE produtos SET status = 'ATIVO' WHERE status IS NULL;
COMMIT;

2. Ferramentas de Migração

-- Conectar com usuário administrativo
CONNECT migration_user/senha

-- Trabalhar em cada schema sem reconectar
ALTER SESSION SET CURRENT_SCHEMA = schema1;
-- importar dados do schema1

ALTER SESSION SET CURRENT_SCHEMA = schema2;
-- importar dados do schema2

ALTER SESSION SET CURRENT_SCHEMA = schema3;
-- importar dados do schema3

3. Debugging e Troubleshooting

-- DBA investigando problema reportado por usuário
CONNECT dba/senha
ALTER SESSION SET CURRENT_SCHEMA = app_user;

-- Reproduzir queries do usuário exatamente como ele vê
SELECT * FROM minha_tabela WHERE status = 'ERRO';

-- Ver os mesmos objetos que o usuário vê
SELECT table_name FROM user_tables;
🌐

PUBLIC Schema

O que é PUBLIC?

PUBLIC é um schema especial no Oracle que representa todos os usuários do banco de dados. Não é um usuário real, mas sim um grupo lógico usado para conceder privilégios ou criar sinônimos acessíveis por todos.

Sinônimos Públicos

Permitem que objetos sejam acessados sem prefixo de schema por todos os usuários.

  • Criados com CREATE PUBLIC SYNONYM
  • Úteis para objetos compartilhados
  • Evitam prefixação em aplicações

Privilégios Públicos

Conceder privilégio a PUBLIC dá acesso a todos os usuários existentes e futuros.

  • GRANT ... TO PUBLIC
  • Útil mas deve ser usado com cautela
  • Implicação de segurança

Exemplos de Sinônimos Públicos:

-- Criar um sinônimo público (requer privilégio CREATE PUBLIC SYNONYM)
CONNECT system/senha

-- Tabela compartilhada acessível por todos
CREATE PUBLIC SYNONYM feriados FOR hr.feriados_nacionais;

-- Agora qualquer usuário pode acessar sem prefixo
CONNECT app_vendas/senha123
SELECT * FROM feriados;  -- Funciona! Resolve para HR.FERIADOS_NACIONAIS

-- Ver sinônimos públicos
SELECT synonym_name, table_owner, table_name
FROM ALL_SYNONYMS
WHERE owner = 'PUBLIC'
  AND synonym_name LIKE 'FERIADOS%';

-- Remover sinônimo público
CONNECT system/senha
DROP PUBLIC SYNONYM feriados;

Privilégios para PUBLIC

Atenção com Segurança!

Conceder privilégios a PUBLIC pode criar vulnerabilidades de segurança. Todo usuário do banco, incluindo contas de serviço e usuários criados no futuro, terão acesso. Use com cautela!

-- Conceder SELECT a todos os usuários (usar com cautela!)
GRANT SELECT ON hr.feriados TO PUBLIC;

-- Agora QUALQUER usuário pode consultar
CONNECT qualquer_usuario/senha
SELECT * FROM hr.feriados;

-- Ver privilégios concedidos a PUBLIC
SELECT table_name, privilege
FROM DBA_TAB_PRIVS
WHERE grantee = 'PUBLIC'
  AND owner = 'HR';

-- Revogar privilégio de PUBLIC
REVOKE SELECT ON hr.feriados FROM PUBLIC;

-- Exemplo de sinônimo público + privilégio público
-- (padrão do Oracle para views do dicionário de dados)
CREATE PUBLIC SYNONYM v$session FOR sys.v_$session;
GRANT SELECT ON sys.v_$session TO PUBLIC;

-- Resultado: todos podem fazer
SELECT sid, username, status FROM v$session;
🔍

Consultando Schemas

Views do Dicionário de Dados

O Oracle fornece várias views para consultar informações sobre schemas, usuários e objetos.

Principais Views:

  • DBA_USERS - Todos os usuários/schemas do banco
  • ALL_USERS - Usuários visíveis para você
  • USER_USERS - Informações do seu próprio usuário
  • DBA_OBJECTS - Todos os objetos de todos os schemas
  • ALL_OBJECTS - Objetos que você pode acessar
  • USER_OBJECTS - Objetos do seu schema
  • DBA_TABLES - Todas as tabelas do banco
  • ALL_TABLES - Tabelas que você pode ver
  • USER_TABLES - Tabelas do seu schema

Consultas Úteis:

-- Listar todos os schemas/usuários
SELECT username,
       account_status,
       created,
       default_tablespace,
       temporary_tablespace
FROM DBA_USERS
WHERE username NOT IN ('SYS', 'SYSTEM', 'OUTLN', 'XDB')
ORDER BY created DESC;

-- Listar schemas de aplicação (excluindo Oracle internal)
SELECT username
FROM DBA_USERS
WHERE oracle_maintained = 'N'  -- Oracle 12c+
ORDER BY username;

-- Contar objetos por schema
SELECT owner,
       COUNT(*) AS total_objects,
       COUNT(DISTINCT object_type) AS distinct_types
FROM DBA_OBJECTS
WHERE owner NOT IN ('SYS', 'SYSTEM')
GROUP BY owner
ORDER BY total_objects DESC;

-- Ver tipos de objetos em um schema específico
SELECT object_type,
       COUNT(*) AS quantity,
       SUM(CASE WHEN status = 'VALID' THEN 1 ELSE 0 END) AS valid,
       SUM(CASE WHEN status = 'INVALID' THEN 1 ELSE 0 END) AS invalid
FROM DBA_OBJECTS
WHERE owner = 'APP_VENDAS'
GROUP BY object_type
ORDER BY quantity DESC;

-- Tamanho ocupado por cada schema
SELECT owner,
       ROUND(SUM(bytes)/1024/1024, 2) AS size_mb,
       COUNT(*) AS num_segments
FROM DBA_SEGMENTS
WHERE owner NOT IN ('SYS', 'SYSTEM')
GROUP BY owner
ORDER BY size_mb DESC;

-- Tabelas e seu owner
SELECT owner, table_name, num_rows, last_analyzed
FROM DBA_TABLES
WHERE table_name LIKE 'PROD%'
ORDER BY owner, table_name;

Explorar Objetos de um Schema

-- Ver estrutura de objetos no schema
SELECT object_type, COUNT(*) AS qty
FROM USER_OBJECTS
GROUP BY object_type
ORDER BY qty DESC;

-- Listar todas as tabelas do schema atual
SELECT table_name, tablespace_name, num_rows
FROM USER_TABLES
ORDER BY table_name;

-- Ver colunas de uma tabela específica
SELECT column_name, data_type, data_length, nullable, data_default
FROM USER_TAB_COLUMNS
WHERE table_name = 'PRODUTOS'
ORDER BY column_id;

-- Ver dependências entre objetos
SELECT name, type, referenced_owner, referenced_name, referenced_type
FROM USER_DEPENDENCIES
WHERE referenced_owner = 'HR'
ORDER BY name;

-- Objetos inválidos no schema
SELECT object_name, object_type, status
FROM USER_OBJECTS
WHERE status = 'INVALID'
ORDER BY object_type, object_name;

Boas Práticas de Organização

Estratégias de Organização de Schemas

1. Schema por Aplicação

Criar um schema dedicado para cada aplicação ou módulo de sistema.

  • Exemplo: APP_VENDAS, APP_ESTOQUE, APP_FINANCEIRO
  • Separação clara de responsabilidades
  • Facilita backup e manutenção por módulo
  • Controle granular de acesso

2. Schema de Dados vs Schema de Código

Separar objetos de dados (tabelas) de objetos de código (packages, procedures).

  • Schema VENDAS_DATA - tabelas, índices, constraints
  • Schema VENDAS_CODE - packages, procedures, functions
  • Facilita deploys de código sem afetar dados
  • Controle de privilégios mais refinado

3. Convenções de Nomenclatura

Estabelecer padrões claros de nomes para schemas.

  • Prefixos: APP_, SRV_, ETL_
  • Ambiente: DEV_, HML_, PROD_ (se necessário)
  • Evitar nomes genéricos: DATA, TEST, USER1
  • Usar nomes descritivos e consistentes

4. Schemas de Serviço

Não usar schemas de aplicação para conectar diretamente. Criar schemas de serviço.

  • Schema APP_VENDAS - contém os objetos (owner)
  • Schema APP_VENDAS_APP - usado pela aplicação (apenas SELECT/INSERT/UPDATE/DELETE)
  • Princípio do menor privilégio
  • Protege objetos de alterações acidentais

5. Evitar SYS e SYSTEM

Nunca criar objetos de aplicação em schemas do sistema.

  • SYS e SYSTEM são para objetos internos do Oracle
  • Criar objetos neles pode causar problemas em upgrades
  • Dificulta manutenção e backup seletivo
  • Violação de boas práticas de Oracle

Exemplo de Estrutura Organizada

-- 1. Criar schemas de dados (owners)
CREATE USER vendas_data IDENTIFIED BY senha_forte
DEFAULT TABLESPACE app_data
QUOTA UNLIMITED ON app_data;

GRANT CONNECT, RESOURCE TO vendas_data;

-- 2. Criar objetos no schema de dados
CONNECT vendas_data/senha_forte

CREATE TABLE clientes (
    cliente_id NUMBER PRIMARY KEY,
    nome VARCHAR2(100),
    email VARCHAR2(100)
);

CREATE TABLE pedidos (
    pedido_id NUMBER PRIMARY KEY,
    cliente_id NUMBER REFERENCES clientes,
    data_pedido DATE,
    total NUMBER(10,2)
);

-- 3. Criar schema de código
CREATE USER vendas_code IDENTIFIED BY senha_forte
DEFAULT TABLESPACE app_data
QUOTA UNLIMITED ON app_data;

GRANT CONNECT, RESOURCE TO vendas_code;
GRANT SELECT, INSERT, UPDATE, DELETE ON vendas_data.clientes TO vendas_code;
GRANT SELECT, INSERT, UPDATE, DELETE ON vendas_data.pedidos TO vendas_code;

-- 4. Criar procedures no schema de código
CONNECT vendas_code/senha_forte

CREATE OR REPLACE PACKAGE pkg_vendas AS
    PROCEDURE registrar_pedido(p_cliente_id NUMBER, p_total NUMBER);
END;
/

CREATE OR REPLACE PACKAGE BODY pkg_vendas AS
    PROCEDURE registrar_pedido(p_cliente_id NUMBER, p_total NUMBER) IS
    BEGIN
        INSERT INTO vendas_data.pedidos (pedido_id, cliente_id, data_pedido, total)
        VALUES (seq_pedidos.NEXTVAL, p_cliente_id, SYSDATE, p_total);
        COMMIT;
    END;
END;
/

-- 5. Criar schema de aplicação (apenas privilégios, sem objetos)
CREATE USER vendas_app IDENTIFIED BY senha_app;
GRANT CONNECT TO vendas_app;

-- Dar acesso apenas via procedures
GRANT EXECUTE ON vendas_code.pkg_vendas TO vendas_app;

-- Aplicação conecta como vendas_app e executa:
-- EXECUTE vendas_code.pkg_vendas.registrar_pedido(100, 1500.00);
🛠️

Exemplos Práticos Completos

Cenário 1: Criação e Acesso Entre Schemas

-- PASSO 1: Criar dois schemas
CONNECT system/senha

CREATE USER loja IDENTIFIED BY senha123
DEFAULT TABLESPACE users
QUOTA UNLIMITED ON users;

CREATE USER relatorios IDENTIFIED BY senha456
DEFAULT TABLESPACE users
QUOTA 10M ON users;

GRANT CONNECT, RESOURCE TO loja;
GRANT CONNECT, RESOURCE TO relatorios;

-- PASSO 2: Criar objetos no schema LOJA
CONNECT loja/senha123

CREATE TABLE produtos (
    produto_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    nome VARCHAR2(100) NOT NULL,
    preco NUMBER(10,2) NOT NULL,
    estoque NUMBER DEFAULT 0
);

INSERT INTO produtos (nome, preco, estoque) VALUES ('Notebook', 3500.00, 10);
INSERT INTO produtos (nome, preco, estoque) VALUES ('Mouse', 50.00, 100);
INSERT INTO produtos (nome, preco, estoque) VALUES ('Teclado', 150.00, 50);
COMMIT;

-- PASSO 3: Tentar acessar de RELATORIOS (vai falhar!)
CONNECT relatorios/senha456

SELECT * FROM loja.produtos;
-- ORA-00942: table or view does not exist

-- PASSO 4: Conceder privilégio
CONNECT loja/senha123

GRANT SELECT ON produtos TO relatorios;

-- PASSO 5: Agora funciona!
CONNECT relatorios/senha456

SELECT produto_id, nome, preco
FROM loja.produtos
WHERE estoque > 0;

-- PASSO 6: Criar view no schema RELATORIOS
CREATE VIEW vw_produtos_disponiveis AS
SELECT produto_id, nome, preco, estoque
FROM loja.produtos
WHERE estoque > 0;

-- PASSO 7: Consultar a view
SELECT * FROM vw_produtos_disponiveis;

Cenário 2: Usando ALTER SESSION e Sinônimos

-- PASSO 1: Conectar como DBA
CONNECT system/senha

-- PASSO 2: Mudar para schema LOJA
ALTER SESSION SET CURRENT_SCHEMA = loja;

-- PASSO 3: Trabalhar sem prefixo
SELECT COUNT(*) FROM produtos;
UPDATE produtos SET preco = preco * 1.1 WHERE produto_id = 1;
COMMIT;

-- PASSO 4: Criar sinônimo público para facilitar acesso
CREATE PUBLIC SYNONYM produtos_loja FOR loja.produtos;

-- PASSO 5: Conceder SELECT a PUBLIC (com cautela!)
CONNECT loja/senha123
GRANT SELECT ON produtos TO PUBLIC;

-- PASSO 6: Qualquer usuário pode acessar
CONNECT relatorios/senha456

-- Ambas as formas funcionam agora:
SELECT * FROM loja.produtos;        -- Forma explícita
SELECT * FROM produtos_loja;        -- Via sinônimo público

-- PASSO 7: Limpar
CONNECT system/senha
DROP PUBLIC SYNONYM produtos_loja;

CONNECT loja/senha123
REVOKE SELECT ON produtos FROM PUBLIC;

Cenário 3: Diagnóstico e Auditoria

-- Auditoria completa de schemas de aplicação
CONNECT system/senha

-- 1. Listar schemas e seus tamanhos
SELECT
    u.username,
    u.account_status,
    u.created,
    u.default_tablespace,
    NVL(ROUND(SUM(s.bytes)/1024/1024, 2), 0) AS size_mb,
    NVL(COUNT(DISTINCT o.object_name), 0) AS num_objects
FROM dba_users u
LEFT JOIN dba_segments s ON u.username = s.owner
LEFT JOIN dba_objects o ON u.username = o.owner
WHERE u.oracle_maintained = 'N'
GROUP BY u.username, u.account_status, u.created, u.default_tablespace
ORDER BY size_mb DESC;

-- 2. Mapear todos os privilégios entre schemas
SELECT
    grantee AS quem_recebe,
    owner || '.' || table_name AS objeto,
    privilege AS privilegio,
    grantable AS pode_repassar
FROM dba_tab_privs
WHERE owner IN ('LOJA', 'RELATORIOS')
  AND grantee NOT IN ('SYS', 'SYSTEM')
ORDER BY grantee, owner, table_name;

-- 3. Ver objetos compartilhados (com grants para outros schemas)
SELECT
    owner,
    table_name,
    COUNT(DISTINCT grantee) AS num_grantees,
    LISTAGG(grantee || ':' || privilege, ', ')
        WITHIN GROUP (ORDER BY grantee) AS grants
FROM dba_tab_privs
WHERE owner = 'LOJA'
GROUP BY owner, table_name
HAVING COUNT(DISTINCT grantee) > 0;

-- 4. Identificar dependências entre schemas
SELECT DISTINCT
    d.owner AS schema_dependente,
    d.referenced_owner AS schema_usado,
    COUNT(*) AS num_dependencias
FROM dba_dependencies d
WHERE d.owner != d.referenced_owner
  AND d.owner IN ('LOJA', 'RELATORIOS')
GROUP BY d.owner, d.referenced_owner
ORDER BY num_dependencias DESC;

Resultado Esperado

O que você deve dominar após este tópico:

Entender Schema = User no Oracle

Compreender a relação única do Oracle entre schemas e usuários

Gerenciar ownership de objetos

Identificar owners e entender privilégios associados

Usar prefixação corretamente

Referenciar objetos com schema.objeto quando necessário

Conceder e revogar privilégios

GRANT e REVOKE entre schemas diferentes

Usar ALTER SESSION SET CURRENT_SCHEMA

Mudar schema padrão sem reconectar

Trabalhar com PUBLIC

Criar sinônimos públicos e entender implicações de segurança

Consultar dicionário de dados

Usar DBA_USERS, DBA_OBJECTS, ALL_TABLES efetivamente

Aplicar boas práticas

Organizar schemas de forma clara e segura

Parabéns!

Você concluiu o último tópico da Trilha 2 - Administração Básica! Agora você possui os fundamentos essenciais para administrar um banco de dados Oracle.

Continue para a Trilha 3 para aprender sobre segurança, usuários avançados e auditoria.

Anterior: Tablespaces e Datafiles Voltar ao Índice da Trilha