sqlite используя blob для эпохи datetime - PullRequest
1 голос
/ 16 октября 2019

Я пытаюсь решить, как лучше хранить дату и время в sqlite. Дата будет в эпоху. Я читал в вики о проблеме 2038 года (это очень похоже на проблему 2000 года). Учитывая это с тем, что я читал на уроках:

От https://www.tutorialspoint.com/sqlite/sqlite_data_types.htm

Tutorialspoint предлагает использовать следующие типы данных в форме datetime.

SQLite не имеет отдельного класса хранения для хранения дат и / или времени, но SQLite способен хранить датыи иногда в качестве значений TEXT, REAL или INTEGER.

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

BLOB Значение представляет собой большой двоичный объект данных, которые хранятся в точности так, как они были введены.

INTEGER Значением является целое число со знаком, сохраненное в 1, 2, 3, 4, 6 или8 байтов в зависимости от величины значения.

Я видел в уроках, что они предлагают использовать sqlite тип INTEGER для даты и времени. Но, учитывая проблему 2038, я думаю, что использование BLOB - лучший выбор, если я сосредоточен на проверке будущего, потому что BLOB не зависит от определенного количества байтов, как INTEGER.

Я новичок в проектировании баз данных, поэтому мне интересно, что лучше делать?

1 Ответ

1 голос
/ 16 октября 2019

INTEGER, как он говорит, может быть до 8 байтов, то есть 64-битное целое число со знаком . Ваша проблема не в том, что SQLite может хранить 32-битные значения, не относящиеся к проблеме 2038. Ваша проблема заключается в получении времени от чего-то, что не является предметом проблемы, то есть, если вы не пытаетесь защитить от проблемы 292,277,026,596 года.

Нет необходимости использовать BLOB и дополнительную сложностьи дополнительная обработка преобразования между BLOB и временем.

Может даже случиться так, что вы можете использовать сам SQLite для извлечения подходящих значений, если вы хотите сохранить текущее время или время, основанное на текущем времени, то есть now .

Возможно, рассмотрим следующее: -

DROP TABLE IF EXISTS timevalues;
/* Create the table with 1 column with a weird type and a default value as now (seconds since Jan 1st 1970)*/
CREATE TABLE IF NOT EXISTS timevalues (dt typedoesnotmatterthtamuch DEFAULT (strftime('%s','now')));
/* INSERT 2 rows with dates of 1000 years from now */
INSERT INTO timevalues  VALUES 
    (strftime('%s','now','+1000 years')), 
    ((julianday('now','+1000 years') - 2440587.5)*86400.0);
/* INSERT a row using the DEFAULT */ 
INSERT INTO timevalues (rowid) /* specify the rowid column so there is no need to supply value for the dt column */
    VALUES ((SELECT count() FROM timevalues)+1 /* get the highest rowid + 1 */);
/* Retrieve the data rowid, the value as stored in the dt column and the dt column converted to a user friendly format */ 
SELECT rowid,*, datetime(dt,'unixepoch') AS userfriendly FROM timevalues;
/* Cleanup the Environment */
DROP TABLE IF EXISTS timevalues;

Что приводит к: -

enter image description here

  • Возможно, вы захотите прочитать Функции даты и времени , например, strftime , julianday и сейчас
  • rowid - это специальный обычно скрытый столбец, который существует для всей таблицы, если только он не является таблицей ROWID. Как правило, он не будет использоваться, или если так псевдоним используется INTEGER PRIMARY KEY
    • см. SQLite Autoincrement , чтобы узнать о rowid и его псевдониме, и почему бы неиспользуйте AUTOINCREMENT.
  • тип столбца typedoesnotmatterthtamuch см. типы данных в SQLite версии 3 , почему это может быть.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...