Para que são usadas as chaves negativas?

12

Um pouco novo no uso de bancos de dados SQL padrão (atualmente trabalhando principalmente com o MySQL) ainda não encontrei muitos usos disso.

Quando e por que é útil ter chaves negativas (ou melhor, assinadas) indexando uma tabela?

Garet Claborn
fonte
5
primeiro, quem está votando sem deixar feedback, está fazendo um desserviço. Em seguida, a resposta para esta excelente pergunta.
jcolebrand
1
Este assunto é intrigante. Eu pessoalmente nunca ouvi falar desse conceito. Esta questão nunca deveria ter sido votada. +1 de mim por apresentar esse conceito.
RolandoMySQLDBA

Respostas:

13

Tudo o que uma chave primária é é um valor que determinamos ser o de maior importância em um registro. Se essa chave é um int assinado, um não assinado, uma string, um blob (na verdade, existem limites) ou um UUID (ou qualquer que seja o nome que leva hoje), o fato ainda é que é uma chave e que é a coisa da maior importância.

Como não somos constrangidos a usar apenas números orientados positivos para nossas chaves, faz sentido considerar que um int assinado irá apenas para ~ 2 bilhões, enquanto um int não assinado irá para ~ 4 bilhões. Mas não há nada de errado em usar um int assinado, configurando o valor inicial para ~ -2 bilhões e configurando um incremento de um. Após ~ 2 bilhões de registros, você atingirá "zero" e continuará a ~ 2 bilhões.

Quanto ao motivo pelo qual seria útil ter "chaves negativas" em uma tabela, essa é a mesma pergunta que "por que é útil ter chaves em uma tabela". O "valor" de uma chave não afeta seu status como chave. Uma chave é uma chave é uma chave.

O importante é se a chave é válida.

Quanto ao motivo pelo qual seria útil permitir chaves negativas, posso sugerir alguns motivos:

E se você quisesse indicar retornos em um sistema de vendas como números negativos de pedidos de vendas, que correspondessem ao número positivo de pedidos de vendas, facilitando a correlação (isso é ingênuo e mal projetado, mas funcionaria no sentido de "planilha").

E se você quiser ter uma tabela de usuários e indicar que aqueles com números negativos foram controlados pelo sistema (o SO faz exatamente isso para usuários de feed de bate-papo).

Eu poderia continuar, mas realmente a única razão pela qual o número negativo é importante é se você ou eu atribuímos importância a ele. Além disso, não há uma grande razão para o valor de uma chave ter alguma influência na própria chave.

jcolebrand
fonte
Editado o bit de 'ocorrência de nicho', pois é mais do que provável um mal-entendido devido à inexperiência. Leitura interessante. Eu estava imaginando que haveria uma situação em que o valor negativo da chave fosse de alguma forma útil na codificação (ie, sem decidir que isso significa uma coisa em particular), mas isso é muito útil quando você tem uma forte divisão em dois grupos e não quero usar um bool extra: p
Garet Claborn 23/05
1
@ Garet ~ Então você faz um bom argumento: "o valor da chave foi de alguma forma útil na codificação" e eu uso minhas chaves de vez em quando dessa maneira, mas isso não tem nada a ver com o aspecto do banco de dados. O banco de dados é um armazém. O aplicativo que consome os dados, por outro lado, se preocupa com os valores . Mas sim, que +/- booleano é um truque interessante, eu já vi muitas vezes usado para esse efeito.
jcolebrand
2
-1 por sugerir que valores de propósito duplo como este são outra coisa senão uma má ideia. Você precisa de um int e um bool? Use um int e um bool.
Jack diz que tente topanswers.xyz
1
@JackPDouglas Não me lembro de incentivar as pessoas a fazer isso, lembro estritamente de implicar que o campo e seus dados são duas coisas diferentes. Obrigado por, pelo menos, oferecer feedback construtivo no seu voto negativo, mas não posso dizer que essa observação signifique algo à luz do conceito do "para que servem as chaves negativas", já que esse é um problema de lógica de aplicativo, não um problema de camada de banco de dados . Eu queria destacar como essas coisas são usadas na camada de aplicação, mas na camada de banco de dados elas não têm nenhum significado.
jcolebrand
1
@JackPDouglas ~ Eu usei esse exemplo em particular porque existe um site muito conhecido (rede de sites) que você já ouviu falar que faz exatamente isso, por isso não quero desconsiderá-lo, porque é um válido "truque". Confira este usuário dba.stackexchange.com/users/-1/community e me diga qual é o ID dele. Eu quase posso garantir que o ID do usuário é a chave primária (e em muitas outras tabelas uma chave estrangeira). Só porque o design do aplicativo é ruim para você, não significa que não seja válido. Mas mais uma vez, isso não é design de banco de dados, é design de domínio. Concedido, os suportes lógicos db-lo
jcolebrand
10

Se falamos sobre colunas de identidade ou número automático, o valor em si não deve ter significado. (às vezes acontece, de acordo com os usuários de bate-papo da SO mencionados pelo drachenstern, o que eu fiz antes de mim)

No entanto, geralmente você perderia metade do seu intervalo se estiver usando números inteiros assinados.
Consulte: O que fazer quando um campo em uma tabela se aproxima do número inteiro máximo de 32 bits com ou sem sinal?

Outro exemplo: em pequenos cenários de replicação, o uso de valores negativos para um site e positivos para outro fornece algum conhecimento implícito da origem de qualquer linha.

gbn
fonte
e verifique se você está restringindo de alguma forma os valores inseridos em cada site, caso contrário, você ficará numa bagunça horrível quando o seu "conhecimento implícito" estiver errado.
Jack diz que tente topanswers.xyz
@JackPDouglas: você usaria NOT FOR REPLICATION para evitar gerar valores no site errado
gbn
juntamente com restrições de verificação ? Além disso, existe um MySQL (ou outro) análogo NOT FOR REPLICATIONque você conhece?
Jack diz que tente topanswers.xyz
@JackPDouglas: desculpe, não tenho certeza sobre o não SQL Server
GBN
8

Nem todos os sistemas de banco de dados oferecem suporte a tipos inteiros não assinados, sendo o MSSQL um deles. Nesses casos, valores negativos são possíveis nos campos de chave inteira simplesmente porque são possíveis no tipo (você pode usar regras ou gatilhos para bloqueá-los, conforme mostrado neste exemplo , mas provavelmente não há necessidade de adicionar a sobrecarga de impor tais regras a cada inters / atualização).

No que diz respeito ao banco de dados, o valor real de uma chave primária não importa, desde que seja exclusivo na tabela. Para ele, -42 e 42 são apenas dois números diferentes, da mesma forma que 42 e 69 são - o significado só será dado à negatividade ou não do valor pelo seu código.

Não oferecer suporte a tipos inteiros não assinados é provavelmente uma decisão de design baseada na redução da complexidade - ou seja, não desejar que dois tipos inteiros de 32 bits se preocupem com a verificação de intervalos ao atribuir valores entre eles. Ele limita o número de índices possíveis em um campo de incremento automático iniciando de 0 ou 1 à metade do que seria possível em um tipo não assinado (~ 2e9 em vez de ~ 4e9), mas isso raramente é um problema significativo (se é provável que você precise vários valores-chave dessa magnitude, você provavelmente optou por um tipo de 64 bits, especialmente se estiver usando uma arquitetura de 64 bits em que esses valores são processados ​​com menos eficiência do que os de 32 bits), se você quiser a gama completa e a necessidade para manter 32 bits por motivos de espaço, você pode iniciar o incremento em -2.147.483.647.

David Spillett
fonte
Sim, acho que já cobrimos esse assunto antes;) tehehe dba.stackexchange.com/questions/983/…
jcolebrand
tinyint está sem sinal (0 .. 255). Eu costumo criar uma restrição de verificação em colunas inteiras para garantir valores são não negativos, já que inevitavelmente código será escrita que assume implicitamente e bugs estranhos surgirão se de alguma forma um valor negativo se arrasta no.
Ed Avis