Bancos de dados do sistema SQL Server , que eu saiba, sempre possuem esses mesmos IDs e já vi muitos scripts de manutenção na internet contando com o predicado WHERE database_id > 4
para excluí-los das ações do script.
Além disso, se eu executar SELECT name, schema_id FROM sys.schemas;
em um novo banco de dados de usuário, recebo:
name schema_id
dbo 1
guest 2
INFORMATION_SCHEMA 3
sys 4
db_owner 16384
db_accessadmin 16385
db_securityadmin 16386
db_ddladmin 16387
db_backupoperator 16389
db_datareader 16390
db_datawriter 16391
db_denydatareader 16392
db_denydatawriter 16393
Executei essa consulta em duas instâncias diferentes, uma no SQL Server 2016 e a outra no SQL Server 2005, e ambas retornaram o mesmo resultado.
Perguntas:
- Existe alguma situação (ou versão do sql server) em que os bancos de dados do sistema master, tempdb, model e msdb teriam um database_id diferente de 1,2,3,4 respectivamente?
- Posso realmente confiar no fato de que os esquemas listados sempre terão os mesmos IDs em qualquer instância do SQL Server para que eu possa escrever scripts de manutenção com base nesses IDs?
Em teoria
As ações abaixo são apenas para fins de teste. Não tente nada disso se você não estiver bem com sua instância de banco de dados se tornando inutilizável, sem resposta e/ou seus dados sendo perdidos
Desanexar o
master
banco de dados para tentar reutilizar seu database_id não é possível.A desanexação
model
resultará na falha da instância e você não poderá anexá-la novamente. Isso resulta na necessidade de reconstruir todos os bancos de dados do sistema . Este processo remove todas as informações como logins, trabalhos, .... E seus bancos de dados de usuários são desanexados.Desanexar
Tempdb
para tentar reutilizar seu database_id, anexando-o novamente com um nome diferente, resultou no database_id 2 não sendo reutilizado etempdb
não funcionando.Consegui alterar o nome de volta para tempdb, mas a instância estava bastante confusa e não consegui iniciá-la normalmente.
---> Reconstrua todos os bancos de dados do seu sistema .
Mas, em teoria , existem 2 (ou mais) opções para alterar o
msdb
ID do banco de dados do sistema:Você pode alterar o
msdb
ID do banco de dados desanexandomsdb
, criando um novo banco de dados de usuário e, finalmente, criando um novomsdb
banco de dados enquanto segue as etapas documentadas para criar um novo banco de dados msdb .Você pode alterar o
msdb
id do banco de dados desanexandomsdb
, reanexando-o com um nome diferente e alterando o nome de volta paramsdb
. NÃO SUPORTADO, por favor, não faça issoPrimeiro inicie o servidor sql no 'modo de recuperação somente mestre'
Desanexar msdb e criar um novo banco de dados
Altere os nomes dos arquivos msdb, reinicie a instância normalmente
Inicialize o msdb:
Veja os IDs do banco de dados:
Método não compatível
Os 2 procedimentos normais de anexação
sp_attach_db
ecreate database ... for attach
não funcionam ao tentar anexarmsdb
.Mensagem de erro:
O que você pode fazer, apenas para fins de teste, é criar um banco de dados de usuários,
msdb2
Renomeie o banco de dados para
msdb
Reinicie a instância normalmente
e veja o
database_id's
:Resultado
Na prática
Felizmente, não vi isso em nenhum lugar, mas database_id 4 poderia, em teoria, ser reutilizado por bancos de dados de usuários. Se isso acontecesse, filtrar os bancos de dados do sistema em minhas consultas provavelmente seria o menor dos meus problemas.
Dito isto, usar
WHERE DB_NAME(database_id) NOT IN ('master','tempdb','model','msdb','distribution','ssisdb')
é a escolha certa.Praticamente falando, esses IDs serão os mesmos para todas as versões atualmente lançadas do SQL Server.
No entanto, não há garantias de que este será sempre o caso, ou que continuará a ser o caso no futuro. A Microsoft não fornece documentação nem garante que esses IDs sejam sempre os mesmos. Há garantias de que alguém entrou em um banco de dados e mexeu com esses esquemas de sistema.
Na próxima versão do SQL Server, a equipe do Produto pode decidir fazer uma alteração no esquema de números de identificação. Essa alteração pode ser retroportada para versões existentes em um Service Pack ou atualização cumulativa.
Isso pode ser improvável em um futuro próximo, então você pode não se preocupar com isso. Mas se você escrever um código incrível, seu código ainda poderá estar em uso daqui a uma ou duas décadas, quando isso acontecer. E então, seus sucessores terão um ninho de rato para desembaraçar, e seu código deixará de ser "código incrível".
Alterações futuras à parte, o código que depende de valores de ID enigmáticos e codificados não é legível. Nem todo mundo sabe que isso
schema_id > 16384
indica uma série de esquemas especiais. (Estou usando o SQL Server desde a virada do século e ficaria confuso com essa linha de código.)Faça com que seu código seja lido como prosa e você terá um código melhor e mais sustentável.
Esses bancos de dados são criados na instalação e são especificados como 1,2,3,4 conforme você escreveu. Você sempre pode quebrar um sistema se interferir nele, e a Microsoft pode alterar esses bancos de dados, tanto em IDs quanto em propósito. A MS pode criar um segundo
model
banco de dados para diferentes propósitos chamadomodel2
, ou adicionar um segundotempdb
banco de dados para dividir diferentes tipos de tabelas temporárias ou por qualquer motivo.Meu conselho é: tenha certeza de que nas versões atuais do SQL Server esses IDs de banco de dados são consistentes (na instalação). Eu também nunca os vi de outra forma. Se você está particularmente preocupado ou simplesmente não consegue se livrar dessa sensação incômoda, verifique esses fatos no início do seu programa/script, especificamente ID # = db name string.
Gosto de rastrear as suposições que faço no código enquanto o escrevo. Para código interno, essas suposições de nome e ID do banco de dados são bastante seguras. Para clientes externos, prefiro verificar tudo. Isso ajuda a) tirar isso da sua cabeça, seja essa suposição de nome/ID do banco de dados ou outra coisa, eb) se uma dessas suposições quebrar, você poderá encontrá-la muito rapidamente. Poupa muitos arranhões na cabeça e é reconfortante saber com o que você pode contar.
Quando você acertar essas perguntas, apenas verifique e siga em frente (embora não haja mal nenhum em postar a pergunta também, como você fez). Dessa forma, seu tempo é melhor gasto em questões reais e você pode limpar sua cabeça dessas perguntas irritantes. E dá confiança quando as coisas falham, não é uma dessas perguntas verificadas.
Nesse caso específico, nunca senti a necessidade de verificar esses IDs de banco de dados; Eu sempre os acessei por meio de sua funcionalidade, não diretamente. No entanto, se eu estivesse escrevendo um script para operar nesses bancos de dados, sabendo que as ramificações poderiam ser graves se o ambiente não fosse o que eu esperava, eu definitivamente verificaria minhas suposições.