AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 241280
Accepted
lit
lit
Asked: 2019-06-25 06:31:04 +0800 CST2019-06-25 06:31:04 +0800 CST 2019-06-25 06:31:04 +0800 CST

Omitindo nomes de esquema para gerenciar o acesso a bancos de dados SQL Server com mais flexibilidade

  • 772

Quando os aplicativos codificam um nome de esquema, dbo.TABLE, ele reduz a capacidade do DBA de migrar os dados conforme necessário.

É seguro e mais flexível para os aplicativos omitirem nomes de esquema?

Eu sei que você dirá que isso é "baseado em opinião", mas é uma questão crítica para o gerenciamento de bancos de dados.

sql-server application-design
  • 2 2 respostas
  • 170 Views

2 respostas

  • Voted
  1. Hannah Vernon
    2020-10-31T06:07:25+08:002020-10-31T06:07:25+08:00

    A resposta curta aqui é Não, não é "seguro" nem "conveniente" e provavelmente não é mais flexível omitir o nome do esquema. Na verdade, fazer isso é uma das formas clássicas de "dar um tiro no pé".

    Uma das principais regras de programação é codificar em um estilo defensivo. Essa é uma tática bem conhecida que ajuda a evitar bugs, especialmente os difíceis de rastrear. A programação defensiva é definida como:

    Projetar com previsão para garantir que um software continue funcionando corretamente em circunstâncias imprevistas.

    É importante notar que cada objeto no SQL Server pertence a um esquema específico. Na maioria das vezes, esse esquema é simplesmente o dboesquema, e pode-se facilmente projetar um banco de dados inteiro cheio de procedimentos armazenados, visualizações, funções, etc. no dboesquema. Alguém poderia fazer isso, mas eu não recomendaria, pelas seguintes razões:

    1. Isso dificulta a interpretação do código. Observando as duas SELECTdeclarações abaixo, há mais clareza em torno daquela em que o esquema é especificado explicitamente.

      SELECT name FROM databases;
      
      SELECT name FROM sys.databases;
      

      Como especifiquei sys.databases, você sabe instantaneamente e sem dúvida que os resultados virão da visão do sistema. Especificar o esquema torna o código complexo muito mais fácil de entender de forma confiável.

    2. A resolução do esquema pode nem sempre funcionar como você pretende. Se você tiver vários esquemas no banco de dados, o SQL Server precisará realizar uma pesquisa de objetos quando você não especificar o esquema. Quando você especifica o esquema, o SQL Server sabe exatamente onde procurar o objeto.

      • Dois desenvolvedores, Melanie e Hannah, estão trabalhando no código. Melanie tem seu esquema padrão definido como 'Melanie', Hannah tem seu esquema padrão definido como 'Hannah'. Melanie cria a tabela, x, inadvertidamente no Melanieesquema, pois eles não especificaram dbona CREATE TABLEinstrução. Melanie diz a Hannah para começar a usar a mesa x. Hannah então passa a usar a tabela xsem especificar um esquema, mas como ambos os desenvolvedores têm esquemas padrão diferentes atribuídos ao seu login, seu novo código não consegue localizar o objeto. Isso parece um bug para Hannah, enquanto isso, quando Melanie executa o mesmo código , funciona perfeitamente. Se ambos os desenvolvedores especificarem o esquema, eles nunca verão esse bug.

      • Seu banco de dados tem dois esquemas warehousee accounting. Ambos os esquemas têm uma tabela chamada Invoices. A warehouse.Invoicetabela contém detalhes sobre faturas que precisam ser processadas. A accounting.Invoicestabela contém todas as colunas pertinentes à fatura real, como detalhes de cobrança, valor a pagar, etc. O código escrito por um usuário que não tem nem warehousenem accountingcomo esquema padrão, que não especifica o nome do esquema, retornará uma resolução de objeto erro em tempo de execução ou quando o código está sendo salvo no banco de dados. No código abaixo, estou criando as duas invoicestabelas, em esquemas separados:

        CREATE SCHEMA warehouse
        CREATE TABLE invoices
        (
            i int NOT NULL
                PRIMARY KEY CLUSTERED
            , HasShipped bit NOT NULL
                DEFAULT (0)
        );
        GO
        CREATE SCHEMA accounting
        CREATE TABLE invoices
        (
            i int NOT NULL
                PRIMARY KEY CLUSTERED
            , TotalAmount decimal(10,4) NOT NULL
        );
        GO
        

        Agora, se eu tentar criar uma visão sem especificar esquemas, recebo um erro:

        CREATE VIEW SomeView
        AS
        SELECT *
        FROM invoices;
        GO
        
        Msg 208, Nível 16, Estado 1, Procedimento SomeView, Linha 4 [Linha Inicial de Lote 25]   
          Nome de objeto inválido 'faturas'.

        Agora, veja o exemplo de criação de um procedimento armazenado no dboesquema:

        CREATE PROCEDURE myproc
        AS
        BEGIN
            SELECT *
            FROM invoices;
        END
        GO
        

        Quando você executa o código para criar esse procedimento, o SQL Server não relata erros, devido à resolução de nomes adiada do SQL Server. No entanto, quando você vai executar o proc, você recebe o seguinte erro:

        Msg 208, Nível 16, Estado 1, Procedimento myproc, Linha 4 [Linha de início de lote 42]  
          Nome de objeto inválido 'faturas'.
    3. O desempenho pode sofrer. De várias maneiras.

      • Planos de Execução que normalmente seriam compartilhados entre usuários com diferentes esquemas padrão serão armazenados em cache separadamente se a instrução T-SQL referenciada no Plano de Execução não tiver prefixos de esquema. Assim, por exemplo, a seguinte instrução T-SQL simples seria armazenada em cache várias vezes para cada usuário que possui um esquema padrão diferente:

        SELECT UserName FROM Users;
        

        Para um banco de dados complexo, com muitas instruções T-SQL variadas sendo executadas por muitos usuários diferentes, isso pode resultar em um aumento significativo do cache do plano, o que pode afetar negativamente a execução da consulta. Sem mencionar que cada usuário pode obter um plano significativamente diferente dependendo da complexidade das instruções que estão sendo executadas e se a detecção de parâmetros está em jogo.

      • Em um ambiente onde há muitos esquemas e muitos objetos, especificar o nome do esquema limita o trabalho que o SQL Server deve fazer ao resolver nomes de objetos para IDs de objetos no tempo de compilação. Especificar o esquema pode resultar em uma redução significativa de carga para bancos de dados grandes e ocupados, com código complexo.

      • A contenção de Spinlock pode se tornar problemática quando você não especifica o esquema. Este documento da Microsoft sobre como diagnosticar e resolver a contenção de Spinlock afirma:

      Os nomes totalmente qualificados de todos os objetos resultarão na remoção da necessidade de o SQL Server executar caminhos de código necessários para resolver nomes. Observamos pontos de contenção também no tipo spinlock SOS_CACHESTORE encontrado ao não utilizar nomes totalmente qualificados em chamadas para procedimentos armazenados. A falha em qualificar totalmente esses nomes resulta na necessidade de o SQL Server pesquisar o esquema padrão para o usuário, o que resulta em um caminho de código mais longo necessário para executar o SQL.

    4. Alguns objetos não possuem um esquema padrão. Veja o exemplo mostrado aqui por Maria Zakourdaev sobre gatilhos DDL. Quando você cria um gatilho do lado do servidor, esse gatilho não tem o conceito de um esquema padrão e, portanto, falhará em tempo de execução , o que pode ser particularmente doloroso. Maria admite no artigo que eles geralmente não especificam esquemas, a menos que o código exija. Eu diria que, se eles tivessem o hábito de sempre especificar o esquema, Maria não teria passado horas perseguindo esse bug.

    Em resumo, eu sempre especifico o esquema para cada pedaço de código que escrevo, simplesmente porque não requer quase nenhum esforço ao escrever o código, e isso me garante que certos bugs simplesmente nunca acontecerão.

    Especificar o esquema é de baixo custo e alto impacto, o que acho que todos concordamos que é A Good Thing™.

    • 4
  2. Best Answer
    Laughing Vergil
    2019-06-25T08:56:14+08:002019-06-25T08:56:14+08:00

    Você parece entender isso, mas apenas no caso... você nem sempre precisa especificar o esquema, desde que o esquema seja o esquema padrão do usuário.

    Portanto, você pode lidar com isso no nível de logon do SQL Server. Um login pode ser definido como padrão para, digamos, o esquema 'MySchema'. Para este login, a tabela mySchema.Ordersseria o padrão para esse usuário, endereçável simplesmente Orders.

    Isso não é usado com frequência, pois pode ficar confuso, mas é uma maneira totalmente funcional de fazer isso. Mas note: se você não tiver a tabela mySchema.Ordersem seu banco de dados, o sistema irá procurar dbo.Orderstambém. Isso é ótimo se você quiser algumas tabelas personalizadas e algumas em comum - ruim se os mySchemausuários não tiverem acesso às dbotabelas.

    • 0

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve