sql >> Databasteknik >  >> RDS >> Mysql

PHP &mySQL:År 2038 Bug:Vad är det? Hur löser man det?

Jag har markerat detta som en community-wiki så redigera gärna när du vill.

Vad är egentligen år 2038-problemet?

"År 2038-problemet (även känt som Unix Millennium Bug, Y2K38 i analogi med Y2K-problemet) kan göra att viss datorprogram misslyckas före eller år 2038. Problemet påverkar all programvara och system som lagrar systemtid som en signerad 32 -bit heltal och tolka detta tal som antalet sekunder sedan 00:00:00 UTC den 1 januari 1970."

Varför uppstår det och vad händer när det inträffar?

Tider efter 03:14:07 UTC tisdag 19 januari 2038 kommer att "omslutas" och lagras internt som ett negativt tal, vilket dessa system kommer att tolka som en tid den 13 december 1901 snarare än 2038. Detta beror på det faktum att antalet sekunder sedan UNIX-epoken (1 januari 1970 00:00:00 GMT) kommer att ha överskridit en dators maximala värde för ett 32-bitars signerat heltal.

Hur löser vi det?

  • Använd långa datatyper (64 bitar är tillräckligt)
  • För MySQL (eller MariaDB), om du inte behöver tidsinformationen, överväg att använda DATE kolumntyp. Om du behöver högre noggrannhet, använd DATETIME istället för TIMESTAMP . Tänk på att DATETIME kolumner lagrar inte information om tidszonen, så din applikation måste veta vilken tidszon som användes.
  • Andra möjliga lösningar som beskrivs på Wikipedia
  • Vänta på att MySQL-utvecklare ska fixa det här felet rapporterades för över ett decennium sedan.

Finns det några möjliga alternativ till att använda den, som inte utgör ett liknande problem?

Försök när det är möjligt att använda stora typer för att lagra datum i databaser:64-bitar är tillräckligt - en lång lång typ i GNU C och POSIX/SuS, eller sprintf('%u'...) i PHP eller tillägget BCmath.

Vilka är några potentiellt brytande användningsfall även om vi inte är i 2038 ännu?

Så en MySQL DATETIME har ett intervall på 1000-9999, men TIMESTAMP har bara ett intervall på 1970-2038. Om ditt system lagrar födelsedatum, framtida framtidsdatum (t.ex. 30-åriga bolån) eller liknande, kommer du redan att stöta på det här felet. Återigen, använd inte TIMESTAMP om detta kommer att bli ett problem.

Vad kan vi göra med de befintliga applikationerna som använder TIMESTAMP, för att undvika det så kallade problemet, när det verkligen inträffar?

Få PHP-applikationer kommer fortfarande att finnas kvar 2038, även om det är svårt att förutse eftersom webben knappast är en äldre plattform ännu.

Här är en process för att ändra en databastabellkolumn för att konvertera TIMESTAMP till DATETIME . Det börjar med att skapa en tillfällig kolumn:

# 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`

Resurser



  1. Hur man lagrar Emoji-tecken i MySQL-databasen

  2. SQL Server 2016:Spara frågeresultat till en CSV-fil

  3. Massinlägg med SQLAlchemy ORM

  4. Skillnaden mellan SET autocommit=1 och START TRANSACTION i mysql (har jag missat något?)