¿Necesito identificadores en mi base de datos si los registros pueden identificarse por la fecha?

17

Estoy escribiendo mi primera aplicación para Android y usaré la base de datos SQLite, así que intentaré limitar el tamaño tanto como sea posible, pero creo que la pregunta se aplica en general al diseño de la base de datos.

Estoy planeando almacenar registros que tendrán texto y la fecha de creación. La aplicación es una aplicación independiente, es decir, no se vinculará a Internet y solo un usuario la actualizará, por lo que no hay posibilidad de que haya más de una entrada con una fecha determinada.

¿Mi mesa todavía necesita una columna de ID? Si es así, ¿cuáles son las ventajas de usar la ID como un identificador de registro en lugar de la Fecha?

Nieszka
fuente
SQLite siempre creará una columna entera para rowid si no especifica una PK entera. Por lo tanto, no cuente con no tener una columna "ID" como una forma de ahorrar espacio.
Codismo
Agregaré que en Android algunas clases necesitan tablas para tener una columna _id para funcionar. Más información en esta respuesta SO .
Bigstones
55
Si obtiene la fecha del propio teléfono y el usuario viaja a una zona horaria anterior (y su teléfono actualiza la hora automáticamente), entonces existe una pequeña posibilidad de que pueda obtener la misma marca de tiempo más de una vez.
Eugene

Respuestas:

22

En mi humilde opinión, lo mejor es evitar el uso de una columna de fecha como clave principal.

He trabajado en sistemas en los que se utiliza un campo de fecha como clave principal y escribir consultas para recuperar subconjuntos de datos es un poco pesado si está trabajando con campos de fecha.

Algunos otros puntos que puede considerar:

Puede pensar que un punto en el tiempo es único, pero eso depende de la granularidad de la columna de fecha. ¿Son minutos, segundos, milisegundos, etc.? ¿Puede estar absolutamente seguro de que nunca obtendrá una violación de clave principal?

Finalmente, si desea migrar la base de datos a otra plataforma, puede volver a encontrar problemas en los que la granularidad de los datos de fecha difiere entre las plataformas.

Por supuesto, tiene que equilibrar el ideal con lo que tiene que trabajar. Si el espacio es realmente una gran preocupación, usar la columna de fecha podría ser el menor de dos males. Esa es una decisión de diseño que tendrá que tomar.

Editar:

Debo señalar que de ninguna manera esto indica que es una mala decisión de diseño. Solo que podría haber problemas con los aspectos prácticos del RDBMS en cuestión.

Robbie Dee
fuente
ha pasado un tiempo desde que escribí una consulta SQLite, pero ¿no está filtrando por fechas idénticas al filtrado por enteros, aparte de la declaración más detallada de los valores de enlace?
DougM
Es simplemente más detallado y también en algunos RDBMS se obtiene ese problema en el que el elemento día y mes se invierte si la base de datos se ha configurado en formato estadounidense.
Robbie Dee
Gracias, todas estas son buenas respuestas, pero su experiencia en el trabajo definitivamente cerró el trato.
Nieszka
Como una posdata a esto: solo hoy recibí un problema de soporte para una tabla de auditoría de aplicaciones donde obtienen una violación de clave principal para un número de empleado y PK de fecha / hora de acceso debido a una diferencia horaria entre 2 dispositivos de cliente. ..
Robbie Dee
13

No, no necesita estrictamente una columna de ID definida en su esquema si puede garantizar que nunca habrá una fecha duplicada.

PERO ...

... Dicho esto, también podrías usarlo de todos modos. El pequeño secreto aquí es que SQLite ya tiene una ID única de incremento automático para cada tabla llamada ROWID. Si declara una columna entera de incremento automático en su tabla como PK, SQLite no creará una nueva columna, simplemente alias esa columna ROWID preexistente.

En SQLite, cada fila de cada tabla tiene un ROWID entero con signo de 64 bits. El ROWID para cada fila es único entre todas las filas de la misma tabla.

Puede acceder al ROWID de una tabla SQLite utilizando uno de los nombres de columna especiales ROWID, ROWID u OID. Excepto si declara que una columna de tabla ordinaria usa uno de esos nombres especiales, el uso de ese nombre se referirá a la columna declarada y no al ROWID interno.

Si una tabla contiene una columna de tipo INTEGER PRIMARY KEY, esa columna se convierte en un alias para el ROWID. Luego puede acceder al ROWID utilizando cualquiera de los cuatro nombres diferentes, los tres nombres originales descritos anteriormente o el nombre dado a la columna INTEGER PRIMARY KEY. Todos estos nombres son alias entre sí y funcionan igualmente bien en cualquier contexto.

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

Por lo tanto, no ahorrará espacio al no usar una columna de ID, ya que obtendrá una por tabla, lo quiera o no.

Gran maestro B
fuente
9

Utilice un campo de ID si se cumple alguna de las siguientes condiciones:

  1. No existe una clave natural (la fecha no será única)
  2. El campo de fecha cambiará con frecuencia.
  3. La fecha puede no ser conocida en el momento de la inserción.
  4. Un identificador de varias columnas supera las tres columnas, lo que haría que las uniones fueran demasiado detalladas.

Lea esta pregunta: ¿Existe una fuente canónica que respalde a "todos los sustitutos"?

Editar:

Dado que, en mi opinión, parece que nada de lo anterior es cierto, no necesita usar un campo ID, pero puede usar uno si lo desea.

Tulains Córdova
fuente
1
Las columnas de ID de +1 son un olor de código de esquema, lo que indica que sus datos realmente no se ajustan al modelo relacional.
Ross Patterson el
10
@RossPatterson No estoy tan seguro. Se me ocurren varios casos en los que no existe una clave natural, pero los datos aún pueden ajustarse al modelo relacional. Solo un caso fuera de mi cabeza: almacenar información sobre personas vivas. Muchos países (¡ no todos! ) Asignan identificadores únicos a cada ciudadano, pero eso no significa que usar ese identificador sea apropiado o incluso posible (puede que no se conozca en el momento de la creación del registro, puede que no se asigne o su uso puede estar prohibido, por ejemplo, por la normativa aplicable). ¿Eso significa que los datos no se ajustan al modelo relacional? No lo creo.
un CVn
Y existe el pequeño hecho curioso de que, donde hay un identificador único, la policía (etc.) a veces usa duplicits para sus identificaciones falsas. Y cuando no es intencional, el error administrativo garantizará duplicidades de todos modos.
user470365
44
Ya sea que esté integrado (a la Oracle) o agregado como una columna de buena fe, son muy útiles. Como alguien que ha estado en ambos lados de la cerca (DBA y desarrollador), es mucho más fácil deducir una tabla con una identificación que puede garantizar que será única.
Robbie Dee el
1
@RobbieDee Tienes razón. Está fuera del tema.
Tulains Córdova
2

Tenga en cuenta que es posible que también desee cambiar el significado de la columna "fecha" de created_ata updated_ato cualquier otro cambio en ese sentido, que me parece ser el caso muy común.

Agregar columna de identificación en algunos casos le dará más flexibilidad cuando cambie su diseño.

wlk
fuente
+1 agregar date_created y date_modified a las tablas es muy útil para rastrear cuándo se crearon y actualizaron las filas. Esto vale su peso en oro cuando se investigan problemas de actualización del depósito / depósito de datos.
Robbie Dee