Чи варто використовувати тип даних дати або часових позначок у MySQL?


2685

Чи рекомендуєте ви використовувати дату або поле часової позначки , і чому (використовуючи MySQL)?

Я працюю з PHP на стороні сервера.


1
тут є відповідна інформація codeproject.com/Tips/1215635/MySQL-DATETIME-vs-TIMESTAMP
Waqleh

Якщо ви хочете, щоб ваша програма була порушена в лютому, 2038 року використовуйте часову позначку. Перевірте діапазон дат.
Вілсон Хоук

Відповіді:


1829

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

Якщо ви мали на увазі, що ви хочете вирішити між використанням часової позначки UNIX або власного поля дати часу MySQL, перейдіть з нативним форматом. Ви можете робити обчислення в MySQL таким чином, ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")і просто змінити формат значення на часову позначку UNIX, ("SELECT UNIX_TIMESTAMP(my_datetime)")коли ви запитуєте запис, чи хочете ви працювати на ньому з PHP.


981
Важливою відмінністю є те, що DATETIMEпредставляє дату (як це знайдено в календарі) та час (як це можна спостерігати на настінному годиннику), в той час як TIMESTAMPявляє собою чітко визначений момент часу. Це може бути дуже важливо, якщо ваша програма обробляє часові пояси. Як давно було "2010-09-01 16:31:00"? Це залежить від того, в якому часовому поясі ви знаходитесь. Для мене це було всього кілька секунд тому, для вас це може означати час у майбутньому. Якщо я скажу 1283351460 секунд з '1970-01-01 00:00:00 UTC', ви точно знаєте, про який момент часу я говорю. (Дивіться відмінну відповідь Ніра нижче). [Нижня сторона: допустимий діапазон].
MattBianco

121
Ще одна відмінність: запити з "рідним" часом не кешуватимуться, а запити із позначкою часу - будуть.
OZ_

39
"Мітки часу в MySQL зазвичай використовуються для відстеження змін у записах" Не вважайте, що це хороша відповідь. Тайм-метс набагато потужніший і складніший, ніж той, про що говорять МетБянко та Нір. Хоча, друга частина відповіді дуже хороша. Це правда, що сказав Блавет, і це хороша порада.
Сантьягобасульто

10
Також 1 важлива примітка, DATETIME та TIMESTAMP можуть з повагою використовувати CURRENT_TIMESTAMP, NOW (), оскільки це значення за замовчуванням, але DATE, наприклад, не може, оскільки за замовчуванням використовується '0000-00-00', тому для вирішення цього питання U слід писати Ваш власний тригер до цієї таблиці, щоб вставити поточну дату (без часу) у поле / коло типу DATE mysql.
Артур Кушман

14
@DavidHarkness: Документація говорить "Щоб вказати автоматичні властивості, використовуйте пункти DEFAULT CURRENT_TIMESTAMP та ON UPDATE CURRENT_TIMESTAMP" dev.mysql.com/doc/refman/5.0/uk/timestamp-initialization.html
13:30

917

У MySQL 5 і вище значення TIMESTAMP конвертуються з поточного часового поясу в UTC для зберігання і перетворюються назад з UTC в поточний часовий пояс для пошуку. (Це відбувається лише для типу даних TIMESTAMP, а не для інших типів, таких як DATETIME.)

За замовчуванням поточний часовий пояс для кожного з'єднання - це час сервера. Часовий пояс можна встановити на основі підключення, як описано в службі підтримки часових поясів MySQL Server .


11
ця презентація OReilly дуже хороша для цієї теми (PDF вибачте) cdn.oreillystatic.com/en/assets/1/event/36/…
gcb

13
Також про характер події: - відеоконференція (TIMESTAMP). Усі відвідувачі повинні бачити посилання на абсолютний момент часу, адаптований до його часового поясу. - Місцевий час (DATETIME), я повинен виконати це завдання в 31.03.2014 9:00, не важливо, чи в цей день я працюю в Нью-Йорку чи Парижі. Я почну працювати о 8:00 за місцевим часом, коли я буду в цей день.
Юсер

1
Отже, якщо я ЗМІНУЙТЕ часовий пояс сервера, то значення TIMESTAMP залишиться колишнім або воно теж зміниться ??
Андрій

3
@Andrew, оскільки це UTC, він залишиться UTC. Однак зворотна конверсія зміниться на "новий" часовий пояс сервера.
nembleton

@yucer - я не рекомендую так думати про це. Найбільш послідовне використання в глобальній економіці - це перетворення всіх дат у UTC для зберігання. За умовами, розгляньте Datetime як поле UTC. Це накладає навантаження на всі завдання, які вводять дати, щоб здійснити перехід на UTC, але це більш чистий дизайн довгостроковий. Звичайно, представити інформацію користувачеві, виходячи з їх поточних налаштувань. Якщо користувач бажає ввести "09:00 в Парижі", то нехай він встановить паризький час, а потім введіть 09:00. Тоді той , хто знаходиться в Нью - Йорку можна легко знайти те , що їм потрібно часу , щоб не спати в свій час, щоб телеконференції в.
ToolmakerSteve

524

Я завжди використовую поля DATETIME для будь-якого іншого, крім метаданих рядків (дата створена або змінена).

Як зазначено в документації на MySQL:

Тип DATETIME використовується, коли потрібні значення, що містять інформацію про дату та час. MySQL отримує та відображає значення DATETIME у форматі "РРРР-MM-DD HH: MM: SS". Підтримується діапазон від "1000-01-01 00:00:00" до "9999-12-31 23:59:59".

...

Тип даних TIMESTAMP має діапазон від '1970-01-01 00:00:01' UTC до '2038-01-09 03:14:07 UTC. Він має різні властивості, залежно від версії MySQL та режиму SQL, на якому працює сервер.

Ви, швидше за все, підпадаєте під нижню межу для TIMESTAMP в загальному користуванні - наприклад, зберігання дати народження.


195
Ви також можете легко досягти верхньої межі, якщо ви займаєтесь банківською справою чи нерухомістю ... 30-річна іпотека перевищує 2038 рік
Kip

16
Звичайно, використовуйте 64-бітні часові позначки Unix. Наприклад, в Java new Date().getTime()вже дає 64-бітове значення.
osa

5
+1 для DATETIME: У нашому потоці даних із SQL-сервера Фізичного магазину для придбання та виставлення рахунків-фактур, переданого на MySQL Server для віртуального магазину на веб-сторінці, DATETIME краще для модифікації дата-час, оскільки цей тип даних існує також у Transact -SQL. Але TIMESTAMP означає Transact-SQL інше, це Binary, як ROWVERSION, хоча MySQL TIMESTAMP схожий на DateTime. Тож ми уникаємо використання TIMESTAMP для сумісності двох БД.
jacouh

10
Не маю уявлення. Це набагато більша проблема, ніж просто MySQL, і немає простого виправлення: en.wikipedia.org/wiki/Year_2038_problem Я не вірю, що MySQL може просто оголосити часові позначки, тепер 64-бітні, і припускати, що все буде добре. Вони не контролюють обладнання.
скронід

5
Дата народження може бути ДАТЕТИМОЮ, якщо ви знаєте час народження, як я роблю для мого.
Кріс Крейг

322

Наведені нижче приклади показують, як TIMESTAMPтип дати змінив значення після зміни місця, time-zone to 'america/new_york'де DATETIMEне змінюється.

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

Я перетворив свою відповідь у статтю, щоб більше людей могли вважати це корисним MySQL: Datetime Versus Timestamp Типи даних .


55
Ну, насправді DATETIMEефективний час змінився зі зміною часового поясу, TIMESTAMPне змінився, але представництво людини зробило.
фліндеберг

3
Схоже, що ця команда не працює в MySQL 5.6 set time_zone="america/new_york";
Манджунат Редді

Ось відповідь на встановлену проблему time_zone. stackoverflow.com/questions/3451847/mysql-timezone-change
Манджунат Редді

2
Погодьтеся з @flindeberg. Мітка часу відображає правильний час, а не час, після зміни часового поясу
Нітін Бансал

193

Основна відмінність полягає в тому, що DATETIME є постійним, тоді як TIMESTAMP впливає на time_zoneналаштування.

Отже, це важливо лише тоді, коли у вас є - або, можливо, у майбутньому - синхронізовані кластери через часові пояси.

Простішими словами: Якщо я маю базу даних в Австралії і займуся дапом цієї бази даних для синхронізації / заповнення бази даних в Америці, то TIMESTAMP буде оновлений, щоб відобразити реальний час події в новому часовому поясі, тоді як DATETIME буде як і раніше відображають час події у часовому поясі au .

Чудовий приклад використання DATETIME там, де слід було використовувати TIMESTAMP, - це Facebook, де їх сервери ніколи не знають, який час відбувся в часових поясах. Одного разу в мене була розмова, в якій час говорив, що я відповідаю на повідомлення, перш ніж повідомлення було фактично надіслане. (Звичайно, це також може бути спричинене поганим перекладом часового поясу в програмному забезпеченні для обміну повідомленнями, якби час був розміщений, а не синхронізований.)


83
Я не думаю, що це хороший спосіб мислення. Я б просто зберігав і обробляв усі дати в UTC і переконуюсь, що фронт відображає його відповідно до заданого часового поясу. Цей підхід простий і передбачуваний.
Кос

8
@Kos: Чи не зберігає та обробляє всі дати в UTC точно те, що робить TIMESTAMP внутрішньо? (Потім перетворити його для відображення локального часового поясу?)
карбокація

10
мій місцевий часовий пояс? Як ваш БД знає мій часовий пояс? ;-) Зазвичай існує досить обробка між базою даних та інтерфейсом користувача. Я роблю локалізацію лише після всієї обробки.
Кос

3
@Koz: моя база даних не знає часових поясів ваших баз даних:! Але він знає часові позначки. Ваша база даних знає власні налаштування часового поясу і застосовує це під час інтерпретації / представлення часової позначки. 1:01 ранку 11 грудня 2013 року в Пекіні Китай не той самий момент часу, як 1:01 ранку 11 грудня 2013 року в Сіднеї, Австралія. Google: "часові пояси" та "меридіан".
екернер

2
MySQL перетворює значення TIMESTAMP з поточного часового поясу в UTC для зберігання і назад з UTC у поточний часовий пояс для пошуку. (Це не трапляється для інших типів, таких як DATETIME.) Dev.mysql.com/doc/refman/5.5/uk/datetime.html
Mahdyfo

124

Я приймаю це рішення на смисловій основі.

Я використовую часову позначку, коли мені потрібно записати (більш-менш) фіксований момент у часі. Наприклад, коли в базу даних було вставлено запис або коли відбулися певні дії користувача.

Я використовую поле дати, коли дата / час можна встановити і змінити довільно. Наприклад, коли користувач може зберегти пізніше змінити зустрічі.


часова мітка - фіксований момент часу, координований час універсального часу - відносно точки зору, до часового відліку (ej часовий пояс місцевий час), може бути .. Координований місцевий час?
Юсер

110

Я не рекомендую використовувати ні DATETIME, ні TIMESTAMP. Якщо ви хочете представити конкретний день у цілому (наприклад, день народження), тоді використовуйте тип DATE, але якщо ви більш конкретні, ніж це, вам, ймовірно, цікаво записати фактичний момент на відміну від одиниці час (день, тиждень, місяць, рік). Замість використання DATETIME або TIMESTAMP використовуйте BIGINT і просто зберігайте кількість мілісекунд з епохи (System.currentTimeMillis (), якщо ви використовуєте Java). Це має ряд переваг:

  1. Ви уникаєте блокування постачальника. Практично кожна база даних підтримує цілі числа відносно подібним чином. Припустимо, ви хочете перейти до іншої бази даних. Ви хочете турбуватися про відмінності між значеннями DATETIME MySQL і тим, як Oracle визначає їх? Навіть серед різних версій MySQL TIMESTAMPS мають різний рівень точності. Лише недавно MySQL підтримував мілісекунди в часових позначках.
  2. Немає проблем із часовим поясом. Тут було зроблено кілька проникливих коментарів щодо того, що відбувається з часовими поясами з різними типами даних. Але це загальновідоме значення, і чи всі ваші колеги знайдуть час, щоб його вивчити? З іншого боку, досить важко зіпсувати зміну BigINT на java.util.Date. Використання BIGINT призводить до безлічі проблем із часовими поясами.
  3. Не хвилюйтеся щодо дальності чи точності. Вам не потрібно турбуватися про те, що скорочується майбутніми датами (TIMESTAMP йде лише до 2038 року).
  4. Інтеграція сторонніх інструментів. Використовуючи ціле число, для інструментів сторонніх виробників (наприклад, EclipseLink) тривіально взаємодіяти з базою даних. Не кожен сторонній інструмент матиме те саме розуміння "дати", як і MySQL. Хочете спробувати з’ясувати, чи слід використовувати об’єкт java.sql.TimeStamp або java.util.Date, якщо ви використовуєте ці власні типи даних? Використання базових типів даних використовує сторонні інструменти тривіально.

Це питання тісно пов’язане з тим, як слід зберігати цінність грошей (тобто 1,99 долара) у базі даних. Чи варто використовувати десятковий або тип грошей у базі даних чи найгірше подвійний? Всі 3 з цих варіантів жахливі з багатьох тих самих причин, які були перераховані вище. Рішення полягає в тому, щоб зберігати вартість грошей у копіях за допомогою BIGINT, а потім конвертувати центи в долари, коли ви показуєте цінність для користувача. Завдання бази даних - зберігати дані, а НЕ вводити ці дані в інтерпретацію. Усі ці фантазійні типи даних, які ви бачите в базах даних (особливо Oracle), додають мало, і починають вас в дорогу до блокування постачальників.


12
Мені подобається це рішення. TIMESTAMP, який закінчився в 2038 році, є головною проблемою. Це насправді не так далеко!
Чарлі Далсасс

4
@CharlieDalsass Ви думаєте, що того часу буде присутнє поточне програмне забезпечення :-P
Habeeb Perwad

13
Це важко запитувати дані за датою, якщо вони зберігаються як кількість мілісекунд
Алі Саїд,

4
Це дійсно найкраще рішення, якщо ви дбаєте про портативність та обробку користувачів у декількох часових поясах або базу даних в іншому часовому поясі, ніж користувачі. TIMESTAMP може бути дорогою, якщо вона не має недоліків у дизайні. Шкода, що розбиті рішення отримали більше голосів, оскільки вони були розміщені достроково (років!).
Німецький

4
Відмінне рішення! І ви абсолютно праві, бо "заблоковані". Коли ви звикли дозволяти іншим «робити роботу за вас», тоді ви починаєте втрачати шматочки та шматки, які роблять ВАС програмістом.
fmc

98

TIMESTAMP - 4 байти Vs 8 байт для DATETIME.

http://dev.mysql.com/doc/refman/5.0/uk/storage-requirements.html

Але, як і скронід, він сказав, що у нього є нижня межа 1970 року. Це чудово для всього, що може статися в майбутньому;)


185
Майбутнє закінчується о 2038-01-19 03:14:07 UTC.
MattBianco

5
Це нерозумно. Я думав, що тип TIMESTAMP буде "готовим до майбутнього", оскільки він відносно новий. Ви не можете перешкоджати перетворенню дати в UTC та назад кожного разу, коли ви працюєте з різними часовими поясами. Вони повинні були зробити TIMESTAMP більшим .. принаймні на 1 байт більшим. це додасть 68 * 255 = 17340 років більше, хоча це не буде 32-бітним вирівнюванням.
NickSoft

10
Чи знаєте ви, чому закінчується TIMESTAMP в 2038 році? Тому що це ціле число, а цілі числа мають обмеження, яке становить 2147483647. Я думаю, що це причина. Можливо, якщо вони змінять його тип на варчар і змінять спосіб маніпулювання ним, він буде "готовий до майбутнього".
vinsa

6
@vinsa, я не думаю, що до цього часу воно буде готове до майбутнього. Ще пам’ятаєте помилку Y2K? 2038 рік наближається.
Пейсьєр

2
До 2038 року MySQL (якщо він все ще існує) просто оновить поле TIMESTAMP, щоб використовувати більше 4-х байт і дозволити ширший діапазон
the_nuts

95
  1. TIMESTAMP - чотири байти проти восьми байтів для DATETIME.

  2. Тимчасові позначки також легші на базі даних та індексуються швидше.

  3. Тип DATETIME використовується, коли потрібні значення, що містять інформацію про дату та час. MySQL отримує та відображає значення DATETIME у форматі "РРРР-MM-DD HH: MM: SS". Підтримується діапазон '1000-01-01 00:00:00' до '9999-12-31 23:59:59'.

Тип даних TIMESTAMP має діапазон від '1970-01-01 00:00:01' UTC до '2038-01-09 03:14:07' UTC. Він має різні властивості, залежно від версії MySQL та режиму SQL, на якому працює сервер.

  1. DATETIME є постійним, тоді як TIMESTAMP впливає на налаштування часової зони.

6
Вам потрібно уточнити №4: Позначення часу як збережене є постійним і не відносним (повністю агностично) до часового поясу, тоді як на відображення результатів на пошук впливає часовий пояс сеансу запиту. DATETIME завжди стосується часового поясу, в якому він був записаний, і завжди повинен вважатися в цьому контексті відповідальністю, яка тепер покладається на додаток.
Крістофер МакГоуан

1
Чудова відповідь. Щоб додати цю відповідь, якщо ми намагаємось зберігати значення, що перевищують "2038-01-09 03:14:07", ми або отримуємо помилку, або вона зберігається як "0000-00-00 00:00:00". Я отримував цю помилку для моєї бази даних, оскільки вона змінює значення (для цілей шифрування).
KarthikS

Крім того, виникає проблема з DATETIME зі значенням DEFAULT у версіях mysql нижче 5,5. dba.stackexchange.com/questions/132951 / ...
Velaro

47

Насправді залежить від застосування.

Подумайте про встановлення часової позначки користувачем на сервері в Нью-Йорку для зустрічі в Сангхаї. Тепер, коли користувач підключається до Сангхая, він отримує таку ж мітку часу призначення з дзеркального сервера в Токіо. Він побачить зустріч у токійський час, компенсований від початкового нью-йоркського часу.

Тож для значень, які представляють час користувача, як зустріч або графік, час дати краще. Це дозволяє користувачеві контролювати потрібну дату та час, незалежно від налаштувань сервера. Встановлений час - це встановлений час, на який не впливає часовий пояс сервера, часовий пояс користувача або зміни способу обчислення літнього часу (так, він змінюється).

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

Тимчасові позначки також легші на базі даних та індексуються швидше.


Ваша програма не повинна покладатися на часовий пояс сервера. Додаток повинен ЗАВЖДИ обрати часовий пояс у сеансі з'єднання з базою даних, який він використовує, перш ніж надсилати будь-який запит. Якщо з'єднання поділяється між кількома користувачами (наприклад: webapp), використовуйте UTC та робіть перетворення часових поясів на стороні візуалізації.
дольмен

42

2016 + : радимо встановити часовий пояс Mysql на UTC та використовувати DATETIME:

Будь-який останній фронтальний фреймворк (кутовий 1/2, реагувати, Vue, ...) може легко і автоматично перетворити ваш дату UTC в місцевий час

Додатково:

(Якщо ви, швидше за все, не зміните часовий пояс ваших серверів)


Приклад з AngularJs

// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}

Весь локалізований формат часу доступний тут: https://docs.angularjs.org/api/ng/filter/date


8
Ваші дані не повинні додаватися до налаштувань часового поясу ваших серверів. Можливо, це працює для вашого, якщо у вас є один ящик MySql під робочим столом
Джин

@Jin UTC означає відсутність часового поясу типу TIMESTAMP. Якщо всі ваші сервери знаходяться в UTC, проблем немає. Можливо, це не працює для вас, якщо у вас є конфігурація 2000.
Себастьєн Хорін

У майбутньому TIMESTAMP може бути оновлено до 64-бітного значення. Тоді проблем більше немає.
doublejr

Завантаження цілих сторонніх бібліотек, щоб схопити щось подібне, теж не може бути чудовим для продуктивності, чи не так? Зважаючи на те, що це клієнт і не впливає на вашу базу даних ... І все-таки все, що ви робите на передньому рівні, вимагатиме перевірки на сервері. Отже, думаючи про повну картину, чи справді це допомагає у питанні швидкості? - Мені здається, ці орієнтири трохи дивні. Використання рядка в запиті для порівняння полів часових позначок також виглядає досить дивним. Це також повинно завдати шкоди продуктивності, правда?
NoobishPro

1
Не покладайтесь у своїй програмі на часову зону сервера. Замість цього визначте часову зону, яку потрібно використовувати для кожного підключення до бази даних: SET time_zone = '+0:00';для UTC.
дольмен

37

timestampПоле є окремим випадком datetimeполя. Ви можете створювати timestampстовпці, щоб мати спеціальні властивості; його можна встановити для оновлення як при створенні, так і / або оновленні.

У "більших" умовах бази даних, timestampє кілька тригерів спеціального випадку.

Те, що є правильним, повністю залежить від того, що ви хочете зробити.


6
Ні, різниця - це не просто "особливий випадок". Оскільки часові пояси сеансу, які встановлюють / запитують, значення включаються по-різному.
дольмен

Я радий, що ти вкладаєш у те, "що є правильним, повністю залежить від того, що ти хочеш зробити". На SE є занадто багато відповідей, які стверджують, що без достатнього обґрунтування "Ви ніколи не повинні робити X" або "Ви завжди повинні робити Y".
Agi Hammerthief

37

TIMESTAMP завжди знаходиться в UTC (тобто минуло секунд з 1970-01-01, у UTC), і ваш сервер MySQL автоматично перетворює його на дату / час для часового поясу підключення. В довгостроковій перспективі TIMESTAMP - це шлях, оскільки ви знаєте, що ваші тимчасові дані завжди будуть у UTC. Наприклад, ви не будете накручувати дати, якщо ви переходите на інший сервер або змінюєте налаштування часового поясу на своєму сервері.

Примітка: часовий пояс підключення за замовчуванням - це часовий пояс сервера, але це можна (слід) змінити за сеанс (див. SET time_zone = ...).


29

Порівняння DATETIME, TIMESTAMP та DATE

введіть тут опис зображення

Що це [.фракція]?

  • Значення DATETIME або TIMESTAMP може включати в себе детальну частку часткових секунд з точністю до мікросекунд (6 цифр). Зокрема, будь-яка дробова частина у значенні, вставленому в стовпець DATETIME або TIMESTAMP, зберігається, а не відкидається. Звичайно, це необов’язково.

Джерела:


24

Варто зауважити, що в MySQL ви можете використовувати щось відповідно до наведених нижче під час створення стовпців таблиці:

on update CURRENT_TIMESTAMP

Це оновлює час у кожному випадку, коли ви змінюєте рядок, а іноді дуже корисно для збереження інформації про останнє редагування. Це працює лише з позначкою часу, але не з датою.


23

Я завжди використовуватиму часову позначку Unix під час роботи з MySQL та PHP. Основною причиною цього є метод дати за замовчуванням у PHP, використовуючи часовий позначку як параметр, тому не було б необхідного аналізу.

Щоб отримати поточну мітку часу Unix в PHP, просто зробіть time();
і в MySQL зробіть SELECT UNIX_TIMESTAMP();.


6
-1 Насправді я вважаю, що відповідь, подана нижче, - краща - використання datetime дозволяє підсилити більше логіки для обробки дат у MySQL, що може бути дуже корисно.
Тобі Хеде

Хіба не було еталонів, які б показували, що сортування в MySQL відбувається повільніше, ніж у php?
sdkfasldf

ну це залежить, іноді добре його використовувати, коли ми любимо не використовувати strtotime. (php5.3 dep)
Адам Рамадхан

ви можете натиснути логіку на mysql, просто скориставшись FROM_UNIXTIME, якщо потрібно
inarilo

Раніше я використовував усі часові позначки Unix у своїх PHP-програмах і в MySQL, однак я виявив, що набагато зручніше зберігати дати та часи в MySQL як рідні типи дати / часу. Це особливо корисно для цілей звітності та просто перегляду наборів даних. З часом, коли мені стало неприємно копіювати / минулі часові позначки Unix, я почав перемикатися. Я впевнений, що є ефективність та інші плюси / мінуси, але залежно від використання зручності використання може бути важливішим, ніж досить мікрооптимізація.
DavidScherer

17

З мого досвіду, якщо ви хочете поле дати, в яке вставлення відбувається лише один раз, і ви не хочете жодних оновлень чи будь-яких інших дій у цьому конкретному полі, перейдіть із часом дати .

Наприклад, розгляньте userтаблицю з полем ДАТА РЕЄСТРАЦІЇ . У цій userтаблиці, якщо ви хочете дізнатися про останній час входу конкретного користувача, перейдіть із полем часової позначки щоб поле оновлювалося.

Якщо ви створюєте таблицю з phpMyAdmin, налаштування за замовчуванням оновить поле часової позначки, коли відбудеться оновлення рядків. Якщо подана вами часова марка не оновлюється оновленням рядків, ви можете скористатись наступним запитом, щоб зробити поле часу мітки автоматично оновленим.

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

15

Тип даних часових позначок зберігає дату та час, але у форматі UTC, а не у поточному форматі часового поясу, як це відбувається. А коли ви отримуєте дані, часова марка знову перетворює це в поточний час часового поясу.

Тож припустимо, що ви перебуваєте в США та отримуєте дані з сервера, який має часовий пояс США. Тоді ви отримаєте дату та час відповідно до часового поясу в США. Стовпчик даних про часові позначки завжди оновлюється автоматично, коли його рядок оновлюється. Тож може бути корисно відстежувати, коли певний рядок було оновлено востаннє.

Більш детальну інформацію можна прочитати в блозі Timestamp Vs Datetime .


Ви завжди можете (слід) визначати часовий пояс на рівні сеансу за допомогою SET time_zone = '+0:00';(UTC тут), щоб бути впевненим у тому, що ви отримуєте / встановлюєте від TIMESTAMPзначень, а також уникати залежно від типових часових зон сервера, які можуть змінюватися.
дольмен

14

Я завжди використовую часову позначку Unix, просто для забезпечення розумності при роботі з великою кількістю інформації про дату, особливо під час коригування часових поясів, додавання / віднімання дат тощо. Якщо порівнювати часові позначки, це виключає ускладнюючі фактори часового поясу і дозволяє економити ресурси на вашій серверній обробці (будь то код програми або запити до бази даних), якщо ви використовуєте невелику арифметику, а не важче додавання / віднімання дати / часу. функції.

Ще одна річ, яку варто врахувати:

Якщо ви створюєте додаток, ви ніколи не знаєте, як ваші дані можуть бути використані внизу. Якщо вам доведеться, скажімо, порівняти купу записів у вашому наборі даних, скажімо, з купою елементів із стороннього API та скажіть, поставте їх у хронологічному порядку, ви будете раді Часові позначки Unix для ваших рядків. Навіть якщо ви вирішили використовувати часові позначки MySQL, зберігайте часові позначки Unix як страховку.


14

У моєму випадку я встановлюю UTC як часовий пояс для всього: системи, сервера баз даних і т. Д. Кожного разу, коли можу. Якщо мій клієнт вимагає іншого часового поясу, я налаштовую його в додатку.

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

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

Отже, підсумовуючи, я ціную ці переваги часової позначки:

  • готовий до використання в міжнародних додатках (багато часовий пояс)
  • легкі міграції між часовими поясами
  • досить легко обчислити різниці (просто відняти обидві часові позначки)
  • не хвилюйтеся щодо дат у літній часовий період

З усіх цих причин я вибираю поля UTC та часові позначки, де це можливо. І я уникаю головних болів;)


Дані про часові позначки будуть цікавими для особи, яка підтримує вашу заявку, коли приїде 20 січня 2038 року. tick tock tick tock
Wilson Hauck

Потім тип часової позначки можна збільшити на трохи та подвоїти можливі значення.
Роджер Кампанера

Перевірте свою теорію на «збільшення на трохи» і перевірте, чи зможете ви успішно зберігати 1 лютого 2038 року та отримувати її за допомогою MySQL. Давайте подивимось ваше визначення таблиці, коли закінчите, будь ласка. Ви, мабуть, матимете багато нещасних минулих знайомств у лютому 2038 року.
Вілсон Хоук

1
@WilsonHauck Вам доведеться оновити версію MySQL задовго до 2038 року. І ця розширена TIMESTAMP буде оброблятися міграцією. Крім того, мало хто з додатків, окрім обробки іпотечних кредитів, справді потребує опіки щодо 2038 року.
дольмен

@dolmen багато інструментів та матеріалів професійного класу мають 20-річну гарантію. Тож щось подібне warranties.expires_atне може бути сьогодні часовою міткою MySQL.
alexw

13

Остерігайтеся зміни часової позначки, коли ви робите оператор UPDATE на таблиці. Якщо у вас є таблиця зі стовпцями "Ім'я" (varchar), "Age" (int) та "Date_Added" (мітка часу), і ви запускаєте наступний оператор DML

UPDATE table
SET age = 30

то кожне значення у стовпці "Дата_Додано" буде змінено на поточну часову позначку.


3
виходячи з того, як ви налаштовуєте свою таблицю, ви можете контролювати цю поведінку. дивіться на dev.mysql.com/doc/refman/5.5/uk/timestamp-initialization.html
Чарльз Файга

5
@CharlesFaiga Поведінка за замовчуванням позначається тим, що часова марка оновлюється при оновленні будь-якого іншого стовпця. Вам потрібно явно вимкнути це, якщо ви хочете, щоб часова марка зберегла своє первісне значення
Lloyd Banks

Що це ?! ви повинні встановити стовпець тимчасової марки наON UPDATE CURRENT_TIMESTAMP
Бухгалтер

Це особливість , яку потрібно чітко ввімкнути під час створення таблиці.
дольмен

13

Довідка, взята з цієї статті:

Основні відмінності:

TIMESTAMP використовується для відстеження змін у записах та оновлення кожного разу, коли запис змінюється. DATETIME використовується для зберігання конкретного та статичного значення, на яке ніякі зміни в записах не впливають.

TIMESTAMP також впливає на різні параметри, пов'язані з TIME ZONE. DATETIME є постійним.

TIMESTAMP внутрішньо перетворив поточний часовий пояс у UTC для зберігання, а під час пошуку перетворив назад у поточний часовий пояс. DATETIME не може цього зробити.

TIMESTAMP підтримується діапазон: '1970-01-01 00:00:01' UTC до '2038-01-19 03:14:07' UTC DATETIME підтримується діапазон: '1000-01-01 00:00:00' до '9999 -12-31 23:59:59 ′


11
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       TIMESTAMP                                       |                                 DATETIME                                 |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes.                                                           | DATETIME requires 8 bytes.                                               |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format.                |
| TIMESTAMP supported range: 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC.    | DATETIME supported range: 1000-01-01 00:00:00 to 9999-12-31 23:59:59 |
| TIMESTAMP during retrieval converted back to the current time zone.                   | DATETIME can not do this.                                                |
| TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose.    | DATETIME is used mostly for user-data.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

10

Ще одна різниця між Timestamp і Datetime полягає в Timestamp, за замовчуванням ви не можете встановити значення NULL.


8
Очевидно, це неправильно. Ось приклад: CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); Перший стовпець може приймати значення NULL.
Ормоз

10

Я виявив неперевершену корисність у можливості TIMESTAMP автоматично оновлюватись на основі поточного часу без використання зайвих тригерів. Це тільки я, хоча TIMESTAMP - це UTC, як це було сказано.

Він може відслідковувати різні часові пояси, тому, якщо вам потрібно відобразити відносний час, наприклад, час UTC - це саме те, що ви хотіли б.


9

Основна різниця

перегляньте цю публікацію, щоб побачити проблеми з індексуванням дати


6
Обидва мають однакову проблему, якщо ви вибираєте функцію на основі значення стовпця, і обидва можуть бути індексовані.
Маркус Адамс

4
Індекс працює на часовій позначці і не працює на дату? Ви зробили неправильні висновки з цих постів.
Салман

9

Я перестав використовуватись datetimeу своїх додатках після багатьох проблем та помилок, пов’язаних із часовими поясами. Використання IMHO timestampкраще, ніж datetimeу більшості випадків .

Коли ви запитуєте, який час? і відповідь приходить як щось на кшталт "2019-02-05 21:18:30", тобто не завершена, не визначена відповідь, оскільки в ній часовій зоні відсутня інша частина? Вашингтон? Москва? Пекін?

Використання дат без часового поясу означає, що ваша програма має лише один часовий пояс, проте часові позначки дають вам переваги datetimeплюс гнучкість показу однакового точного моменту часу в різних часових поясах.

Ось декілька випадків, які змусять вас пошкодувати про використання datetimeта побажання зберегти свої дані у часових позначках.

  1. Для комфорту своїх клієнтів ви хочете показувати їм час на основі їх бажаних часових поясів, не змушуючи їх робити математику та перетворювати час на їхній змістовний часовий пояс. все, що вам потрібно, це змінити часовий пояс, і весь код вашої програми буде однаковим. (Насправді ви завжди повинні визначати часовий пояс на початку програми або обробляти запит у випадку PHP-програм)

    SET time_zone = '+2:00';
  2. ви змінили країну, в якій ви перебуваєте, і продовжуєте роботу над збереженням даних, переглядаючи їх в іншому часовому поясі (без зміни фактичних даних).

  3. ви приймаєте дані від різних клієнтів у всьому світі, кожен з них вставляє час у свій часовий пояс.

Коротко

datetime = програма підтримує 1 часовий пояс (і для вставки, і для вибору)

timestamp = програма підтримує будь-який часовий пояс (і для вставки, і для вибору)


Ця відповідь призначена лише для того, щоб виділити деяку увагу на гнучкість та простоту часових позначок, коли мова йде про часові пояси, вона не охоплює будь-яких інших відмінностей, таких як розмір стовпця або діапазон чи частка .


що робити, якщо в одній таблиці є поля, які використовують date, та інші сфери використання timestamp. Я думаю, це спричинить нову проблему, оскільки дані, відфільтровані whereне відповідають змінам Часової зони.
Erlang P

@ErlangP У цьому випадку ваша програма повинна виправити проблему часового поясу на dateстовпці перед надсиланням запиту.
Бухгалтер

7

Я вважаю за краще використовувати часову позначку, щоб зберегти все в одному загальному сировинному форматі та відформатувати дані у PHP-коді або у вашому SQL-запиті. Є випадки, коли у вашому коді стане в нагоді, щоб тримати все в простоті секунд.



6

Мені подобається часова мітка Unix, тому що ви можете конвертувати в цифри і просто турбуватися про число. Крім того, ви додаєте / віднімаєте та отримуєте тривалість тощо. Потім конвертуйте результат у Date в будь-якому форматі. Цей код визначає, скільки часу в хвилинах пройшло між часовою позначкою документа та поточним часом.

$date  = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now  - $result) / 60);
$min = round($unix_diff_min);

4
Або використовуйте людський читаний та рідний MySQL дату, а також використовуйте нативні функції MySQL для додавання / підстрахування дат.
Жульєн Палард
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.