Why are date fields stored as integer in SQLite/MySQL databases? - mysql

I've noticed sometimes dates are stored as an integer instead of datetime in database. Why to choose Int while we have datetime data type?

SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values.
For other databases you have wrong impression. Dates are usually stored as Timestamp or Datetime. Sometimes there are cases when people store UNIX Time defined as the number of seconds that have elapsed since 00:00:00 (UTC), 1970-01-01.
People tend to use UNIX time as it is usually easier to do time calculations/comparison, as you can apply usual mathematical operations to compare them. While with Timestamp/Datetime you might need to use time related functions.
What you mention regarding SQLite, it does not have a special datetime datatype.

Related

Date vs Strings in MySQL [duplicate]

I have to allow my users to make an update with 24 hours of delay from their previous update, so because date operations in this case are going to be on the backend, but in the web server, i can store Javascript Date as a string in the database and when i have to calculate the difference between 2 dates i can query the lastUpdateDate from the database and parse it to a JS Date Object, is this safe to do?
Is it safe to store dates as a string in mysql?
It is safe as long as the format that you use to represent your dates is unambiguous (that is, each value maps to a unique date).
But it is always inefficient not to use the proper datatype to store a value. Sooner or later, you will face the need to do some date computation in the database (sorting, filtering, adding, ...): storing your dates as strings will make such operation more complex that it has to (the overhead varies depending on the format your choose), and much less efficient (you would typically need to translate all the strings to dates before you can operate on them).
On the other hand, using the proper datatype from the start does not makes things more complicated on the frontend - especially in MySQL. You just need to format your strings properly ('YYYY-MM-DD HH:MI:SS') before passing them to the database, and MySQL will happily treat them as dates.
It is, unless your date strings are unique. You can specify UNIQUE clause for it. But there is no reason to do so, because MySql provides 5 built-in Date/Time data types(DATE, DATETIME, TIMESTAMP, TIME, YEAR(M)). Still if you save dates as a string, you might face problems later in extracting dates in right format.
I usually store date and time in both formats, as a string and in the native database format. Despite the disadvantages of some extra processing and extra storage space, I find it useful because all my search and reporting queries are based on the text format. This makes my application database-agnostic since text comparisons are the same across all major databases, whereas date and time formats vary significantly across different databases. I use the native database format stored dates and times for date-based calculations.

Is it safe to store dates as a string in mysql?

I have to allow my users to make an update with 24 hours of delay from their previous update, so because date operations in this case are going to be on the backend, but in the web server, i can store Javascript Date as a string in the database and when i have to calculate the difference between 2 dates i can query the lastUpdateDate from the database and parse it to a JS Date Object, is this safe to do?
Is it safe to store dates as a string in mysql?
It is safe as long as the format that you use to represent your dates is unambiguous (that is, each value maps to a unique date).
But it is always inefficient not to use the proper datatype to store a value. Sooner or later, you will face the need to do some date computation in the database (sorting, filtering, adding, ...): storing your dates as strings will make such operation more complex that it has to (the overhead varies depending on the format your choose), and much less efficient (you would typically need to translate all the strings to dates before you can operate on them).
On the other hand, using the proper datatype from the start does not makes things more complicated on the frontend - especially in MySQL. You just need to format your strings properly ('YYYY-MM-DD HH:MI:SS') before passing them to the database, and MySQL will happily treat them as dates.
It is, unless your date strings are unique. You can specify UNIQUE clause for it. But there is no reason to do so, because MySql provides 5 built-in Date/Time data types(DATE, DATETIME, TIMESTAMP, TIME, YEAR(M)). Still if you save dates as a string, you might face problems later in extracting dates in right format.
I usually store date and time in both formats, as a string and in the native database format. Despite the disadvantages of some extra processing and extra storage space, I find it useful because all my search and reporting queries are based on the text format. This makes my application database-agnostic since text comparisons are the same across all major databases, whereas date and time formats vary significantly across different databases. I use the native database format stored dates and times for date-based calculations.

Storing date as integer

I came across a database schema (instant messaging, http://www.9lessons.info/2013/05/message-conversation-database-design.html) where message's date + time is stored not as timestamp, but with an integer, like 123984347439.
What's the point of this?
I found a couple of resources which store dates as integers, like 20151009. What are pros and cons of this approach in comparison native date + time specific formats of databases?
When stored as integer, the timestamp is not reliant on any time zone settings of the server. When you send a date to MySQL server, it will try to convert it to UTC for storage, if the column type is timestamp. It will perform the same conversion when it pulls the date out.
You can read about it in the manual, 5th paragraph.
MySQL converts TIMESTAMP values from the current time zone to UTC for
storage, and back from UTC to the current time zone for retrieval.
(This does not occur for other types such as DATETIME.) By default,
the current time zone for each connection is the server's time.
With integer saved, this doesn't happen.
Pros:
you are not reliant on the server's time zone
Cons:
you can't use date functions easily, without performing conversions first using FROM_UNIXTIME()
when reading the data manually, numbers don't tell you what date is in question. The timestamp column formats it so you can understand the date without problems
Update: I don't know what's the benefit of storing an integer that isn't unix timestamp. Storing the date such as 20151009 corresponds to 10.09.2015 - I don't see any kind of use for this without further information so my personal opinion boils down to that the person who designed such a system either didn't know much about dates and handling them or there's some kind of awkward business logic in the app itself that requires dates formatted like that in order to work. Bottom line is that I personally wouldn't use it. I'd stick to proven standards that work for everyone.
From the post that you linked it appears that the row is storing a Unix timestamp.
This allows you store the value as an integer while also allowing for method calls to retrieve as human readable date using from_unixtime() So if need be you can call SELECT from_unixtime(time) ASdateFROM conversation where user_id_fk = '3' and retrieve a value like 2007-11-30 10:30:19 from the result.
To answer your question about pros and cons, the biggest pro for storing as an integer is that comparing integers is a lot faster than datetimes. However, when stored as a Unix timestamp, there are some caveats(cons). Integers are factually faster when comparing unix_time = '1106475000' vs date_field = '2005-01-23 10:10:00; However, the problem arises when you need to compare an integer(Unix timestamp) to a human readable timestamp. Because you will need to convert the value to a Unix timestamp ahead of time in code or in the query, it will take some extra resources, or in case of in query it is much slower than native date comparison. So now this int comparison unix_time = UNIX_TIMESTAMP('2005-01-23 10:10:00') is a lot slower than date_field = '2005-01-23 10:10:00.
So it really depends on how your server side code is done to either leverage the speed of storing as an integer. As well it is up to the developer to decide if this speed is worth the extra abstraction between the sql server and the application.
Here is some more information on date/integer comparisons in innodb.
Here is some more information on date/integer comparisons in myisam.
That is most likely a timestamp expressed in seconds from a chosen epoch (starting date and time). There are a few standard timestamps out there, such as Unix timestamps
Storing dates as integers may speed up date calculations / comparisons in certain simple cases, since neither mysql, nor the processing application need to convert the underlying data to a date format. It also saves some space on your HD. The drawback is that you can't use the built-in date management functions. So, if you want to perform complex calculations, then either you write your own functions to do those or you need to convert the integer back to a date format.
The benefit is when you dont actually need the date or time - such as when you are storing peoples birthdates and are just using them as a matching value - not actually using them as dates and you dont want to store strings.

Store date as unix timestamp or TIMESTAMP data type in MySQL?

I need to store dates (with time) in a MySQL database. I want to be able to format these how I like. Then what is the best way to store dates in a MySQL database? The DATETIME type, the TIMESTAMP type or simply a unix timestamp in a numeric data type? I will be retrieving the dates using PHP.
Usually it does not matter whether you use TIMESTAMP or DATETIME datatype.
In older versions, TIMESTAMP was 4 bytes and DATETIME was 8.
Think of DATETIME as a picture of a clock; think of TIMESTAMP as an instant in time, worldwide. That is, if you connect to the same database, but from a different timezone, a DATETIME will look the the same, but a TIMESTAMP will be adjusted for timezone.
NOW(), SELECTing into PHP, etc, are compatible with both.
Both are externally seen as a string, such as '2015-04-25 17:09:01'.
Since TIMESTAMP is stored as a 32-bit integer (but you don't see that), it is limited to ~1970-2038.
Since DATETIME is clock time, there will be a missing/extra hour twice a year if you switch to/from daylight savings time.
Yes, you could use UNIX_TIMESTAMP() and have an INT UNSIGNED, but wouldn't it be better to see '2015-...'? (That would be 4 bytes.)
You can use DateTime type to store timestamp & insert current timestamp using now() in mysql or get dates/timestamps via any methods you find suitable.
I prefer storing it as long which is always from epoch and represent UTC. This helps when we have to cater to different localization and timezone aspect -other wise we would end up storing values in either DB server default or JVM default locale.

How best to store date/time in MySql?

Should I be storing a Delphi TDateTIme, or perhaps convert to Unix timestamp first? Or mayeb eeven as a string?
How should I declare the column in MySql? As a Double, or DateTime (or Integer if I use Unix timestamp)?
Whta is "correct", or what is easiest if I want to be able to display a string with "yyyy mm dd hh:mm:ss" (or similar) and also to be able to get an elapsed time from comparing two values?
Btw, the program will only ever be used in one tiemzone - which does not have daylight savings time.
I am confused and can't seem to find this discussed anywhere. Any helpful URLs?
Should I be storing a Delphi TDateTIme, or perhaps convert to Unix timestamp first?
Typically, you should do neither: the data types in the database layer ought to be meaningful (as possible) on their own and not depend on your application to interpret them. As #Jim DeLaHunt says, this enables the database to easily manipulate/interpret them from SQL as required (and also enables you to easily access the same data from another application codebase in the future).
MySQL has five temporal types, only two of which store both a date and a time: DATETIME and TIMESTAMP.
As others have alluded, the difference comes down to whether you wish to store the timezone - although I find that quite a confusing way of looking at it:
TIMESTAMP uses the session's time_zone variable to convert input into a UTC timestamp and then back again for output: it's useful for specifying an exact moment in time;
DATETIME simply stores the date and time without regard to timezone, much like taking a photograph of a calendar and clock: it's useful for specifying an event that occurs in the same local time globally.
How should I declare the column in MySql? As a Double, or DateTime (or Integer if I use Unix timestamp)?
Just as you would declare any other column, you specify the relevant data type after the column name.
Beware that TIMESTAMP has additional features, such as automatic update, which you may wish to disable in your column declaration if so desired.
Whta is "correct", or what is easiest if I want to be able to display a string with "yyyy mm dd hh:mm:ss" (or similar) and also to be able to get an elapsed time from comparing two values?
Using one of the above temporal types, you will be able to do all of this (using date functions as required). The default output of TIMESTAMP and DATETIME types is a string in 'YYYY-MM-DD HH:MM:SS' format.
In particular, the "elapsed time" from comparing two values could for example be obtained with MySQL's TIMEDIFF() function:
SELECT TIMEDIFF(end, start) AS elapsed
FROM my_table
WHERE ...
MySQL should have a native date format which is to be preferred as this allows one to use the SQL date functions (year, month, etc).
I have in one of my database tables a field which is defined as a Delphi datetime - in retrospect this was a mistake as it is very difficult to filter on this field or display the values. Both these actions require special handling in the calling program as opposed to in the database.
I'd let MySQL handle date/times as it wants to, i.e. as a datetime field. It has a huge range (not epoch limited).
See here : http://dev.mysql.com/doc/refman/5.0/en/datetime.html
This link might be useful to you. It depends whether you want to use timezones, but even you don't need them now, reconsider if it is not possible to use them in the future.
I would use DATETIME. It is easier to read by human.
You can read all about the MySQL Date and Time types in the MySQL Reference Manual, 11.3. Date and Time Types and about functions in 12.7. Date and Time Functions.
My experience, with MySQL and SQL Server, though not with Delphi per se, is that you are well served to store date and time values in the database's date and time format. This lets you use the database's date and time functions, and take advantage of its optimised implementation of date and time features. If you store datetime values as something generic like a Double or an Integer Unix timestamp, you'll lack the optimisations and have to implement your own equivalent of date and time functions.
Update based on OP's edited question:
The DateFormat() function can give you strings like "yyyy mm dd hh:mm:ss" using a format string like "%Y %m %d %k:%i:%s".
The TimeDiff() function will give you a time interval type giving the difference between two datetime values.
There are a number of post describing the best way to save the datetime in mysql such as
MySQL Integer vs DateTime index and
MySQL DATETIME vs TIMESTAMP vs INT performance and benchmarking with MyISAM
If you decided convert your datetime into a Unix timestamp and save it as a integer
Look out for the following:
The Delphi function DateTimeToUnix( StrToDateTime('2013-11-22 16:34:45'));
Uses the LOCAL TIME ZONE for the conversation
The MYSQL function UNIX_TIMESTAMP('2013-11-22 16:34:45')
Uses the GMT TIME ZONE for the conversation