Preciso de IDs no meu banco de dados se os registros puderem ser identificados até a data?

17

Como estou escrevendo meu primeiro aplicativo para Android e utilizarei o banco de dados SQLite, tentarei limitar o tamanho o máximo possível, mas acho que a pergunta se aplica em geral ao design do banco de dados.

Estou planejando armazenar registros que terão texto e a data de criação. O aplicativo é um aplicativo independente, ou seja, não será vinculado à Internet e apenas um usuário o atualizará; portanto, não há chance de que haja mais de uma entrada em uma determinada data.

Minha tabela ainda precisa de uma coluna de ID? Em caso afirmativo, quais são as vantagens de usar o ID como um identificador de registro em oposição à Data?

Nieszka
fonte
O SQLite sempre criará uma coluna inteira para rowid se você não especificar uma PK inteira. Portanto, não conte com uma coluna "ID" como forma de economizar espaço.
Codism 9/08/13
Acrescentarei que no Android algumas classes precisam de tabelas para que uma coluna _id funcione. Mais informações nesta resposta SO .
Bigstones
5
Se você está obtendo a data do próprio telefone e o usuário viaja para um fuso horário anterior (e o telefone atualiza a hora automaticamente), há uma pequena chance de que você possa obter o mesmo carimbo de data e hora mais de uma vez.
915 Eugene

Respostas:

22

IMHO, é melhor evitar a utilização de uma coluna de data como chave primária.

Trabalhei em sistemas nos quais um campo de data é usado como chave primária e escrever consultas para recuperar subconjuntos de dados é um pouco difícil, se você estiver trabalhando com campos de data.

Alguns outros pontos que você pode querer considerar:

Você pode pensar que um ponto no tempo é único, mas isso depende da granularidade da coluna de data. Minutos, segundos, milissegundos, etc. Você pode ter certeza absoluta de que nunca obterá uma violação da chave primária?

Finalmente, se você desejar migrar o banco de dados para outra plataforma, poderá encontrar novamente problemas em que a granularidade dos dados da data difere entre as plataformas.

É claro que você precisa equilibrar o ideal com o que precisa trabalhar. Se o espaço é realmente uma preocupação, usar a coluna de data pode ser o menor dos dois males. Essa é uma decisão de design que você terá que tomar.

Editar:

Devo salientar que de forma alguma isso indica que é uma decisão de projeto. Só que pode haver problemas com os aspectos práticos do RDBMS em questão.

Robbie Dee
fonte
faz algum tempo desde que escrevi uma consulta SQLite, mas a filtragem por datas não é idêntica à filtragem por números inteiros, além da declaração mais detalhada dos valores de ligação?
DougM
É apenas mais detalhado e também em alguns RDBMSs você obtém o problema em que o elemento dia e mês é revertido se o banco de dados tiver sido configurado no formato dos EUA.
Robbie Dee
Obrigado, essas são todas boas respostas, mas sua experiência no trabalho definitivamente selou o acordo.
Nieszka
Como um pós-escrito para isso: só hoje recebi um problema de suporte para uma tabela de auditoria de aplicativos em que eles estão recebendo uma violação de chave primária para um número de funcionário e acessam a data / hora da PK devido a uma diferença de horário entre dois dispositivos clientes. .. #
22613 Robbie Dee
13

Não, você não precisa estritamente de uma coluna de ID definida em seu esquema se puder garantir que nunca haverá uma data duplicada.

MAS ...

... Dito isto, você também pode usá-lo de qualquer maneira. O pequeno segredo aqui é que o SQLite já possui um ID exclusivo de incremento automático para cada tabela chamada ROWID. Se você declarar uma coluna inteira de incremento automático em sua tabela como PK, o SQLite não criará uma nova coluna - simplesmente aliasará a coluna ROWID preexistente.

No SQLite, todas as linhas de todas as tabelas possuem um número inteiro assinado de 64 bits, ROWID. O ROWID para cada linha é exclusivo entre todas as linhas na mesma tabela.

Você pode acessar o ROWID de uma tabela SQLite usando um dos nomes de coluna especiais ROWID, ROWID ou OID. Exceto se você declarar uma coluna de tabela comum para usar um desses nomes especiais, o uso desse nome fará referência à coluna declarada e não ao ROWID interno.

Se uma tabela contiver uma coluna do tipo INTEGER PRIMARY KEY, essa coluna se tornará um alias para o ROWID. Você pode acessar o ROWID usando qualquer um dos quatro nomes diferentes, os três nomes originais descritos acima ou o nome dado à coluna INTEGER PRIMARY KEY. Todos esses nomes são aliases um para o outro e funcionam igualmente bem em qualquer contexto.

http://www.sqlite.org/autoinc.html

Portanto, você não estará economizando espaço ao não usar uma coluna de ID, pois está recebendo uma por tabela, queira ou não!

GrandmasterB
fonte
9

Use um campo de ID se alguma das seguintes situações for verdadeira:

  1. Não existe chave natural (a data não será exclusiva)
  2. O campo da data mudará frequentemente
  3. A data pode não ser conhecida no momento da inserção.
  4. Um identificador de várias colunas excede três colunas, o que tornaria as junções muito detalhadas.

Leia esta pergunta: Existe uma fonte canônica apoiando “todos os substitutos”?

Editar:

Como, na minha opinião, parece que nenhuma das opções acima é verdadeira, você não precisa usar o campo ID, mas pode usar um, se quiser.

Tulains Córdova
fonte
1
As colunas de código +1 são um cheiro de código de esquema, indicando que seus dados não se encaixam realmente no modelo relacional.
Ross Patterson
10
@ RossPatterson Não tenho tanta certeza. Posso pensar em vários casos em que nenhuma chave natural pode existir, mas os dados ainda podem se encaixar no modelo relacional. Apenas um caso em cima da minha cabeça: armazenar informações sobre pessoas vivas. Muitos países ( nem todos! ) Atribuem identificadores exclusivos para cada cidadão, mas isso não significa que o uso desse identificador seja apropriado ou até possível (talvez não seja conhecido no momento da criação do registro, talvez não seja atribuído ou seu uso pode ser proibido, por exemplo, pelos regulamentos aplicáveis). Isso significa que os dados não se encaixam no modelo relacional? Acho que não.
um CVn 09/08/13
E existe o pequeno fato engraçado de que, onde existe um identificador único, a polícia (etc.) às vezes usa duplicatas para suas identificações falsas. E quando não for intencional, o erro administrativo garantirá duplicidades de qualquer maneira.
user470365
4
Seja ele incorporado (à la Oracle) ou adicionado como uma coluna de boa-fé, eles são muito úteis. Como alguém que esteve nos dois lados da barreira (DBA e desenvolvedor), é muito mais fácil deduzir uma tabela com um ID que você pode garantir que será único.
Robbie Dee
1
@RobbieDee Você está certo. Está fora de questão.
Tulains Córdova
2

Lembre-se de que você também pode alterar o significado da coluna "data" de created_atpara updated_atou qualquer outra alteração nessas linhas, o que considero um caso muito comum.

A adição da coluna id em alguns casos fornecerá mais flexibilidade quando o design for alterado.

wlk
fonte
+1 adicionando date_created e date_modified às tabelas é muito útil para acompanhar quando as linhas foram criadas e atualizadas. Isso vale seu peso em ouro ao investigar problemas de atualização do repositório / armazém de dados.
Robbie Dee