Mysql
 sql >> база данни >  >> RDS >> Mysql

PHP и mySQL:Бъг от 2038 г.:Какво е това? Как да го реша?

Означил съм това като уики на общността, така че не се колебайте да редактирате в свободното си време.

Какъв точно е проблемът за 2038 г.?

„Проблемът от 2038 г. (известен също като Unix Millennium Bug, Y2K38 по аналогия с проблема Y2K) може да причини неуспех на някои компютърни софтуери преди или през 2038 г. Проблемът засяга всички софтуери и системи, които съхраняват системното време като подписано 32 -битово цяло число и интерпретирайте това число като броя на секундите от 00:00:00 UTC на 1 януари 1970 г."

Защо се случва и какво се случва, когато се случи?

Часове след 03:14:07 UTC във вторник, 19 януари 2038 г. ще се „обвие“ и ще се съхранява вътрешно като отрицателно число, което тези системи ще интерпретират като време на 13 декември 1901 г., а не през 2038 г. Това се дължи на факта, че броят на секундите от епохата на UNIX (1 януари 1970 00:00:00 GMT) ще е надвишил максималната стойност на компютъра за 32-битово цяло число със знак.

Как да го решим?

  • Използвайте дълги типове данни (64 бита са достатъчни)
  • За MySQL (или MariaDB), ако не се нуждаете от информация за времето, помислете за използването на DATE тип колона. Ако имате нужда от по-висока точност, използвайте DATETIME вместо TIMESTAMP . Внимавайте, че DATETIME колоните не съхраняват информация за часовата зона, така че приложението ви ще трябва да знае коя часова зона е била използвана.
  • Други възможни решения, описани в Wikipedia
  • Изчакайте разработчиците на MySQL да коригират тази грешка докладвано преди повече от десетилетие.

Има ли възможни алтернативи за използването му, които не представляват подобен проблем?

Опитайте, когато е възможно, да използвате големи типове за съхраняване на дати в бази данни:64-бита са достатъчни - дълъг дълъг тип в GNU C и POSIX/SuS, или sprintf('%u'...) в PHP или разширението BCmath.

Какви са някои потенциално нарушаващи случаи на употреба, въпреки че все още не сме в 2038 г.?

Така че MySQL DATETIME има диапазон от 1000-9999, но TIMESTAMP има само диапазон от 1970-2038. Ако вашата система съхранява рождени дати, бъдещи бъдещи дати (например 30-годишни ипотеки) или подобни, вече ще се сблъскате с тази грешка. Отново, не използвайте TIMESTAMP, ако това ще е проблем.

Какво можем да направим със съществуващите приложения, които използват TIMESTAMP, за да избегнем така наречения проблем, когато наистина се появи?

Малко PHP приложения все още ще съществуват през 2038 г., въпреки че е трудно да се предвиди, тъй като мрежата все още едва ли е наследена платформа.

Ето процес за промяна на колона на таблица на база данни за преобразуване на TIMESTAMP до DATETIME . Започва със създаване на временна колона:

# rename the old TIMESTAMP field
ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;

# create a new DATETIME column of the same name as your old column
ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;

# update all rows by populating your new DATETIME field
UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);

# remove the temporary column
ALTER TABLE `myTable` DROP `temp_myTimestamp`

Ресурси



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Какво прави DELIMITER // в тригер?

  2. В SQL / MySQL каква е разликата между ON и WHERE в изявление за присъединяване?

  3. Съображения за целостта на данните и производителността в полусинхронната репликация на MySQL

  4. WAMP Няма достъп в локална мрежа 403 Забранено

  5. Проблем с Java + Mysql UTF8