Нужны ли идентификаторы в моей базе данных, если записи могут быть идентифицированы по дате?

17

Я пишу свое первое приложение для Android и буду использовать базу данных SQLite, поэтому постараюсь максимально ограничить размер, но я думаю, что вопрос в целом относится к дизайну базы данных.

Я планирую хранить записи, которые будут иметь текст и дату создания. Приложение является автономным приложением, т. Е. Оно не будет ссылаться на Интернет, и только один пользователь будет обновлять его, поэтому нет никаких шансов, что будет иметься более одной записи с определенной датой.

Моя таблица все еще нуждается в столбце идентификатора? Если да, каковы преимущества использования идентификатора в качестве идентификатора записи по сравнению с датой?

Nieszka
источник
SQLite всегда будет создавать целочисленный столбец для rowid, если вы не укажете целочисленный PK. Поэтому не рассчитывайте на отсутствие столбца «ID» в качестве способа экономии места.
Кодизм
Я добавлю, что в Android некоторым классам нужны таблицы для работы столбца _id. Больше информации на этот так ответ .
большие камни
5
Если вы получаете дату с самого телефона и пользователь перемещается в более ранний часовой пояс (и его / ее телефон обновляет время автоматически), есть небольшая вероятность, что вы можете получить одну и ту же отметку времени более одного раза.
Евгений

Ответы:

22

ИМХО, лучше избегать использования столбца даты в качестве первичного ключа.

Я работал над системами, в которых поле даты используется в качестве первичного ключа, и написание запросов для извлечения подмножеств данных является проблемой, если вы работаете с полями даты.

Некоторые другие моменты, которые вы можете рассмотреть:

Вы можете подумать, что момент времени уникален, но это скорее зависит от гранулярности столбца даты. Это минуты, секунды, миллисекунды и т. Д. Можете ли вы быть абсолютно уверены, что никогда не получите нарушение первичного ключа?

Наконец, если вы захотите перенести базу данных на другую платформу, вы можете снова столкнуться с проблемами, когда детализация данных о дате отличается между платформами.

Вы, конечно, должны сбалансировать идеал с тем, с чем вам нужно работать. Если пространство действительно так важно, использование столбца даты может быть меньшим из двух зол. Это дизайнерское решение, которое вам придется принять.

Редактировать:

Я должен отметить, что это никоим образом не означает, что это плохое дизайнерское решение. Просто могут быть проблемы с практичностью рассматриваемой СУБД.

Робби Ди
источник
Прошло некоторое время с тех пор, как я написал запрос SQLite, но разве не происходит фильтрация по датам, идентичным фильтрации по целым числам, кроме более подробного объявления значений привязки?
DougM
Это просто более многословно, а также в некоторых СУБД возникает проблема, при которой элемент день и месяц переворачивается, если БД была настроена в формате США.
Робби Ди
Спасибо, это все хорошие ответы, но ваш опыт работы определенно закрепил сделку.
Nieszka
В качестве постскриптума к этому: только сегодня мне передали проблему поддержки для таблицы аудита приложений, где они получают нарушение первичного ключа для номера сотрудника и PK даты / времени доступа из-за разницы во времени между двумя клиентскими устройствами. ..
Робби Ди
13

Нет, вам не нужен столбец идентификатора, определенный в вашей схеме, если вы можете гарантировать, что никогда не будет повторяющейся даты.

НО ...

... тем не менее, вы могли бы использовать его в любом случае. Небольшой секрет здесь заключается в том, что SQLite уже имеет уникальный, автоматически увеличивающийся идентификатор для каждой таблицы с именем ROWID. Если вы объявите в своей таблице автоматически увеличивающийся столбец целых чисел в качестве PK, SQLite не создаст новый столбец - он просто создаст псевдоним этого ранее существующего столбца ROWID.

В SQLite каждая строка каждой таблицы имеет 64-битное целое число со знаком ROWID. ROWID для каждой строки уникален среди всех строк в одной таблице.

Вы можете получить доступ к ROWID таблицы SQLite, используя один из специальных имен столбцов ROWID, ROWID или OID. За исключением случаев, когда вы объявляете обычный столбец таблицы для использования одного из этих специальных имен, использование этого имени будет ссылаться на объявленный столбец, а не на внутренний ROWID.

Если таблица содержит столбец типа INTEGER PRIMARY KEY, этот столбец становится псевдонимом для ROWID. Затем вы можете получить доступ к ROWID, используя любое из четырех разных имен, три оригинальные имена, описанные выше, или имя, указанное в столбце INTEGER PRIMARY KEY. Все эти имена являются псевдонимами друг для друга и одинаково хорошо работают в любом контексте.

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

Таким образом, вы не будете экономить место, не используя столбец ID, поскольку вы получаете по одному на таблицу, хотите вы этого или нет!

GrandmasterB
источник
9

Используйте поле идентификатора, если выполняется одно из следующих условий:

  1. Не существует естественного ключа (дата не будет уникальной)
  2. Поле даты будет часто меняться
  3. Дата может быть неизвестна на момент вставки.
  4. Многоколонный идентификатор превышает три столбца, что делает соединения слишком многословными.

Прочитайте этот вопрос: существует ли канонический источник, поддерживающий «всех суррогатов»?

Редактировать:

Так как, на мой взгляд, кажется, что ничего из вышеперечисленного не выполняется, вам не нужно использовать поле идентификатора, но вы можете использовать его, если хотите.

Тулаинс Кордова
источник
1
Столбцы +1 ID - это запах кода схемы, указывающий, что ваши данные не соответствуют реляционной модели.
Росс Паттерсон
10
@ RossPatterson Я не так уверен. Я могу вспомнить ряд случаев, когда не существует естественного ключа, но данные все еще могут соответствовать реляционной модели. Только один случай с моей головы: хранение информации о живых людях. Многие ( не все! ) Страны присваивают уникальные идентификаторы каждому гражданину, но это не означает, что использование этого идентификатора является уместным или даже возможным (он может быть неизвестен во время создания записи, может не назначаться или его использование). может быть запрещено, например, применимыми правилами). Означает ли это, что данные не соответствуют реляционной модели? Я так не думаю.
CVN
И есть маленький забавный факт, что там, где есть такой уникальный идентификатор, полиция (и т. Д.) Иногда использует дубликаты для своих поддельных идентификаторов. И когда это не преднамеренно, канцелярская ошибка все равно обеспечит дубликаты.
user470365
4
Независимо от того, встроен ли он (в виде Oracle) или добавлен в качестве добросовестного столбца, они очень полезны. Как человек, который был с обеих сторон (администратор базы данных и разработчик), гораздо проще дедуплицировать таблицу с идентификатором, который, как вы можете гарантировать, будет уникальным.
Робби Ди
1
@RobbieDee Вы правы. Это не по теме.
Тулаинс Кордова
2

Имейте в виду, что вы также можете изменить значение столбца «дата» created_atна updated_atили любое другое изменение в том же духе, что, на мой взгляд, является очень распространенным случаем.

Добавление столбца id в некоторых случаях даст вам больше гибкости при изменении дизайна.

WLK
источник
+1 добавление date_created и date_modified в таблицы очень полезно для отслеживания того, когда строки были созданы и обновлены. Это ценится на вес золота при расследовании проблем с обновлением хранилища / хранилища данных.
Робби Ди