Ho bisogno di ID nel mio database se i record potrebbero essere identificati dalla data?


17

Sto scrivendo la mia prima applicazione per Android e userò il database SQLite, quindi cercherò di limitare le dimensioni il più possibile, ma penso che la domanda si applichi in generale alla progettazione del database.

Sto programmando di archiviare i record che avranno il testo e la data di creazione. L'app è un'app autonoma, ovvero non si collegherà a Internet e solo un utente la aggiornerà, quindi non è possibile che ci sia più di una voce con una determinata data.

La mia tabella ha ancora bisogno di una colonna ID? In tal caso, quali sono i vantaggi dell'utilizzo dell'ID come identificativo del record rispetto alla data?


SQLite creerà sempre una colonna intera per rowid se non si specifica un PK intero. Quindi non contare sul non avere una colonna "ID" come un modo per risparmiare spazio.
Codismo

Aggiungerò che in Android alcune classi hanno bisogno di tabelle per avere una colonna _id per funzionare. Maggiori informazioni su questa risposta SO .
Pietre preziose,

5
Se stai ricevendo la data dal telefono stesso e l'utente viaggia verso un fuso orario precedente (e il suo telefono aggiorna automaticamente l'ora), allora c'è una leggera possibilità che tu possa ottenere lo stesso timestamp più di una volta.
Eugene,

Risposte:


22

IMHO, è meglio evitare di utilizzare una colonna della data come chiave primaria.

Ho lavorato su sistemi in cui un campo data è usato come chiave primaria e scrivere query per ritirare sottoinsiemi di dati è un po 'trascinante se stai lavorando con campi data.

Alcuni altri punti che potresti voler considerare:

Potresti pensare che un punto nel tempo sia unico, ma ciò dipende piuttosto dalla granularità della colonna della data. Sono minuti, secondi, millisecondi ecc. Puoi essere assolutamente sicuro di non avere mai una violazione della chiave primaria?

Infine, se si desidera migrare il database su un'altra piattaforma, è possibile che si verifichino nuovamente problemi in cui la granularità dei dati della data differisce tra le piattaforme.

Ovviamente devi bilanciare l'ideale con ciò con cui devi lavorare. Se lo spazio è davvero così preoccupante, l'uso della colonna della data potrebbe essere il minore dei due mali. Questa è una decisione di progettazione che dovrai prendere.

Modificare:

Devo sottolineare che ciò non indica in alcun modo che si tratti di una cattiva decisione di progettazione. Solo che potrebbero esserci problemi con le funzionalità del RDBMS in questione.


è passato un po 'di tempo da quando ho scritto una query SQLite, ma il filtro per date non è identico al filtro per numeri interi, a parte la dichiarazione più dettagliata dei valori di associazione?
DougM,

È solo più dettagliato e anche su alcuni RDBMS si ottiene quel problema in cui l'elemento giorno e mese è invertito se il DB è stato impostato nel formato USA.
Robbie Dee,

Grazie, queste sono tutte buone risposte, ma la tua esperienza sul lavoro ha definitivamente concluso l'affare.
Nieszka,

Come post script per questo: solo oggi mi è stato consegnato un problema di supporto per una tabella di controllo delle applicazioni in cui stanno ricevendo una violazione della chiave primaria per un numero di dipendente e accesso a data / ora PK a causa di una differenza di orario tra 2 dispositivi client. ..
Robbie Dee,

13

No, non è strettamente necessaria una colonna ID definita nel tuo schema se puoi garantire che non ci sarà mai una data duplicata.

MA ...

... Detto questo, potresti anche usarlo comunque. Il piccolo segreto qui è che SQLite ha già un ID univoco e auto-incrementante per ogni tabella chiamata ROWID. Se si dichiara una colonna intera a incremento automatico nella tabella come PK, SQLite non creerà una nuova colonna, ma semplicemente alias quella colonna ROWID preesistente.

In SQLite, ogni riga di ogni tabella ha un intero ROWID con segno a 64 bit. Il ROWID per ogni riga è unico tra tutte le righe nella stessa tabella.

È possibile accedere al ROWID di una tabella SQLite utilizzando uno dei nomi di colonna speciali ROWID, ROWID o OID. Tranne se si dichiara una colonna di tabella ordinaria per utilizzare uno di quei nomi speciali, l'uso di quel nome farà riferimento alla colonna dichiarata e non al ROWID interno.

Se una tabella contiene una colonna di tipo INTEGER PRIMARY KEY, quella colonna diventa un alias per ROWID. È quindi possibile accedere a ROWID utilizzando uno dei quattro nomi diversi, i tre nomi originali sopra descritti o il nome assegnato alla colonna INTEGER PRIMARY KEY. Tutti questi nomi sono alias l'uno per l'altro e funzionano ugualmente bene in qualsiasi contesto.

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

Quindi, non risparmierai spazio non usando una colonna ID poiché ne ottieni una per tabella, che tu lo voglia o no!


9

Utilizzare un campo ID se si verifica una delle seguenti condizioni:

  1. Non esiste una chiave naturale (la data non sarà unica)
  2. Il campo della data cambierà spesso
  3. La data potrebbe non essere nota al momento dell'inserimento.
  4. Un identificatore a più colonne supera le tre colonne, il che renderebbe i join troppo dettagliati.

Leggi questa domanda: esiste una fonte canonica che supporta "tutti i surrogati"?

Modificare:

Dal momento che, a mio avviso, sembra che nessuna delle precedenti sia vera, non è necessario utilizzare il campo ID e, se si desidera, è possibile utilizzarne uno.


1
Le colonne ID +1 sono un odore di codice dello schema, a indicare che i tuoi dati non si adattano realmente al modello relazionale.
Ross Patterson,

10
@RossPatterson non ne sono così sicuro. Mi viene in mente un numero di casi in cui non potrebbe esistere una chiave naturale, ma i dati possono ancora adattarsi al modello relazionale. Solo un caso sulla cima della mia testa: la memorizzazione di informazioni su persone viventi. Molti paesi ( non tutti! ) Assegnano identificatori univoci a ciascun cittadino, ma ciò non significa che l'utilizzo di tale identificativo sia appropriato o addirittura possibile (potrebbe non essere noto al momento della creazione del record, potrebbe non essere assegnato o il suo utilizzo può essere vietato, ad esempio, dalle normative applicabili). Ciò significa che i dati non si adattano al modello relazionale? Io non la penso così.
un CVn

E c'è il piccolo fatto strano che laddove esiste un identificatore così unico, la polizia (ecc.) A volte usa i duplicati per i loro documenti di identità falsi. E quando non è intenzionale, l'errore clericale garantirà comunque delle duplicazioni.
user470365

4
Che siano integrati (come Oracle) o aggiunti come una colonna in buona fede, sono molto utili. Come qualcuno che è stato su entrambi i lati del recinto (DBA e sviluppatore) è molto più facile dedicare un tavolo con un ID che puoi garantire sarà unico.
Robbie Dee,

1
@RobbieDee Hai ragione. È fuori tema.
Tulains Córdova,

2

Tenete a mente che si potrebbe anche voler cambiare significato della colonna "data" da created_ata updated_ato qualsiasi altro cambiamento in questo senso, che trovo essere caso molto comune.

L'aggiunta della colonna ID in alcuni casi ti darà maggiore flessibilità quando il tuo progetto cambia.


+1 l'aggiunta di date_created e date_modified alle tabelle è molto utile per tenere traccia delle righe create e aggiornate. Questo vale il suo peso in oro quando si esaminano i problemi di aggiornamento del repository / data warehouse.
Robbie Dee,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.