Heim  >  Artikel  >  Datenbank  >  So lösen Sie das Zeitstempel-2038-Problem von MySQL

So lösen Sie das Zeitstempel-2038-Problem von MySQL

WBOY
WBOYnach vorne
2023-06-02 10:13:272104Durchsuche

Der Zeitstempel bezieht sich auf die Gesamtzahl der Sekunden von 00:00:00 GMT am 1. Januar 1970 (08:00:00 am 1. Januar 1970 Pekinger Zeit) bis heute.
In der Produktionsumgebung werden verschiedene Versionen von MySQL bereitgestellt, darunter drei Hauptversionen von MySQL 5.5/5.6/5.7 und N-Nebenversionen. Aufgrund der schlechten Aufwärtskompatibilität von MySQL verhält sich dasselbe SQL in verschiedenen Versionen unterschiedlich, wie folgt Der Zeitstempel Der Datentyp wird unter verschiedenen Aspekten detailliert vorgestellt.

Zeitstempel-Datenzugriff

In den oben genannten drei Hauptversionen von MySQL reicht der Wertebereich des Standard-Zeitstempeltyps (Timestamp) von „1970-01-01 00:00:01“ UTC bis „2038-01 – 19 03:14:07 UTC, die Daten sind auf die zweite Ebene genau, daher wird in MySQL der 4-Byte-INT-Typ zum Speichern der Zeit verwendet Konvertieren Sie beim Stempeln von Daten zunächst die lokale Zeitzonenzeit in die UTC-Zeitzonenzeit, konvertieren Sie dann die UTC-Zeitzonenzeit in einen Millisekundenwert im INT-Format (mit der Funktion UNIX_TIMESTAMP) und speichern Sie ihn dann in der Datenbank.
2. Konvertieren Sie beim Lesen von Zeitstempeldaten zunächst den Millisekundenwert im INT-Format in die UTC-Zeitzonenzeit (mit der Funktion FROM_UNIXTIME), konvertieren Sie ihn dann in die lokale Zeitzonenzeit und geben Sie ihn schließlich an den Client zurück.

In MySQL 5.6.4 und späteren Versionen können Daten vom Typ Zeitstempel mit der höchsten Genauigkeit in Mikrosekunden (Millionstelsekunden) gespeichert werden. Der Wertebereich von N ist 0-6 . Der Standardwert ist 0. Wenn eine Genauigkeit im Millisekundenbereich erforderlich ist, stellen Sie ihn auf Timestamp(3) ein. Wenn eine Genauigkeit im Mikrosekundenbereich erforderlich ist, erhöhen Sie den Wert sein interner Speicherplatz, aber der Zeitstempeltyp bleibt unverändert. Der minimale und maximale Wertebereich von .

Zeitstempelfelddefinition

Die Zeitstempelfelddefinition betrifft hauptsächlich zwei Arten von Vorgängen:

  • Beim Einfügen eines Datensatzes enthält das Zeitstempelfeld DEFAULT CURRENT_TIMESTAMP. Wenn beim Einfügen eines Datensatzes keine spezifischen Zeitdaten angegeben werden, enthält das Zeitstempelfeld Beim Aktualisieren eines Datensatzes für die aktuelle Zeit

  • enthält das Zeitstempelfeld ON UPDATE CURRENT_TIMESTAMP. Wenn beim Aktualisieren des Datensatzes keine spezifischen Zeitdaten angegeben werden, wird der Zeitstempelfeldwert auf die aktuelle Zeit gesetzt

    PS1: CURRENT_TIMESTAMP bedeutet, die Funktion CURRENT_TIMESTAMP( ) zu verwenden, um die aktuelle Zeit zu erhalten, ähnlich der Funktion NOW()
Gemäß den beiden oben genannten Operationstypen kann die Zeitstempelspalte vier Kombinationsdefinitionen haben, ihre Bedeutung ist:

Wenn das Feld als Zeitstempel definiert ist, bedeutet dies, dass das Feld weder beim Einfügen noch beim Aktualisieren automatisch auf die aktuelle Zeit eingestellt ist.
  • Wenn ein Feld als Zeitstempel DEFAULT CURRENT_TIMESTAMP definiert ist, bedeutet dies, dass dem Feld nur die aktuelle Zeit zugewiesen wird, wenn es eingefügt wird und kein Wert angegeben wird, und dass es nicht geändert wird, wenn es aktualisiert wird und kein Wert angegeben wird.
  • Wenn ein Feld als Zeitstempel ON UPDATE CURRENT_TIMESTAMP definiert ist, bedeutet dies, dass dem Feld beim Einfügen der Wert „0000-00-00 00:00:00“ zugewiesen wird, ohne dass ein Wert angegeben ist, und auf die aktuelle Zeit aktualisiert wird wenn aktualisiert und kein Wert angegeben ist.
  • Wenn das Feld als Zeitstempel DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP definiert ist, bedeutet dies, dass das Feld beim Einfügen oder Aktualisieren keinen Wert angibt und ihm die aktuelle Zeit zugewiesen wird.
  • PS1: Es gibt Unterschiede zwischen der in MySQL ausgeführten Tabellenerstellungsanweisung und der endgültigen Tabellenerstellungsanweisung. Es wird empfohlen, SHOW CREATE TABLE TB_XXX zu verwenden, um die Tabellenerstellungsanweisung der erstellten Tabelle abzurufen.
Unterschiede bei der Verwendung von Zeitstempelfeldern in verschiedenen Versionen von MySQL

In MySQL 5.5 und früheren Versionen kann nur DEFUALT CURRENT_TIMESTAMP oder ON UPDATE CURRENT_TIMESTAMP für ein Zeitstempelfeld definiert werden, dies wurde jedoch in MySQL 5.6 und MySQL aufgehoben 5.7. Diese Einschränkung;
  • In der MySQL 5.6-Version ist der Standardwert des Parameters „explicit_defaults_for_timestamp“ 1, in der MySQL 5.7-Version ist der Standardwert des Parameters „explicit_defaults_for_timestamp“ 0; Der Zeitstempeltyp ist standardmäßig NICHT NULL. In der MySQL 5.6-Version ist der Zeitstempeltyp standardmäßig NULL.
  • Wenn c1-Zeitstempel in der Tabellenerstellungsanweisung festgelegt ist, entspricht
  • dem c1-Zeitstempel NICHT NULL in MySQL 5.5 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

  • Entspricht c1-Zeitstempel NULL DEFAULT NULL in MySQL 5.6;
  • Entspricht c1-Zeitstempel NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP in MySQL. 5 .7;
  • Bei c1-Zeitstempel-Standardeinstellung 0 wird in der Tabellenerstellungsanweisung verwendet,

Entspricht c1-Zeitstempel NICHT NULL STANDARD ‘0000-00-00 00:00:00’ in MySQL 5.5 00:00’;
  • entspricht c1-Zeitstempel NOT NULL DEFAULT „0000-00-00 00:00:00’;
  • in MySQL 5.7 Betroffen vom Standardwert des Parameters explizit_defaults_for_timestamp.
  • PS2: Wenn der Standardwert der Zeitstempelspalte „0000-00-00 00:00:00“ lautet, wird bei Verwendung des Standardwerts „nicht im Zeitstempel-Wertebereich“ keine Warnung generiert.

    Ausnahme durch Zeitstempeltyp

    Wenn der MySQL-Parameter time_zone=system ist, wird beim Abfragen des Zeitstempelfelds die Systemzeitzone für die Zeitzonenkonvertierung aufgerufen. Aufgrund des globalen Sperrproblems in der Systemzeit Zone, in Multi-Parallelitätsszenarien Der Zugriff auf eine große Datenmenge führt dazu, dass der Thread-Kontext häufig wechselt, die CPU-Auslastung in die Höhe schnellt, die Systemreaktion langsamer wird und angehaltene Animationen auftreten.

    Zeitstempeltyp und Zeittypauswahl

    In einigen „Datenbankanleitungen“ wird empfohlen, den Zeitstempeltyp anstelle des Datums-/Uhrzeitfelds zu verwenden Der Zeitstempeltyp verwendet 4 Bytes und das Datum/Uhrzeit-Feld verwendet 8 Bytes. Aufgrund der Verbesserung der Festplattenleistung und der Reduzierung der Speicherkosten führt die Verwendung des Zeitstempeltyps jedoch möglicherweise nicht zu einer großen Leistungsverbesserung von der Definition und dem Wertebereich des Zeitstempeltyps beeinflusst werden. Beschränken Sie die geschäftliche Nutzung und wirken Sie sich darauf aus.

    In MySQL 5.6.4 und späteren Versionen können Sie Daten vom Zeitstempeltyp (Zeitstempel) in Mikrosekunden mit der höchsten Genauigkeit konvertieren, und Sie können auch Daten vom Zeittyp (Datum/Uhrzeit) in Mikrosekunden mit der höchsten Genauigkeit konvertieren type (datetime) ) kann auch den gleichen Effekt wie der Zeitstempeltyp erzielen, z. B. die Definition des Felds als dt1 DATETIME(3) NOT NULL DEFAULT NOW(3) ON UPDATE NOW(3); Der Zugriffsbereich des Zeittyps (datetime) ist „1000-01-01 00:00:00.000000“ bis „9999-12-31 23:59:59.999999“, wodurch die Daten jedes Zeitraums besser gespeichert werden können.

    Verwendungsvorschläge für Zeitstempeltypen

    Wenn Sie sich nur für die letzte Aktualisierungszeit der Daten interessieren, wird empfohlen, die Zeitstempelspalte als TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE zu definieren CURRENT_TIMESTAMP;#🎜 🎜#

    Wenn Ihnen die Erstellungszeit und Aktualisierungszeit wichtig ist, wird empfohlen, die Aktualisierungszeit als Zeitstempelfeld festzulegen und die Erstellungszeit als DAETIME oder TIMESTAMP DEFAULT ‘0000-00-00 zu definieren 00:00:00’, Und geben Sie beim Einfügen von Datensätzen explizit die Erstellungszeit an. Es wird empfohlen, nur eine einzige Zeitstempelspalte in der Tabelle zu definieren und die Attribute DEFAULT und ON UPDATE explizit zu definieren. 🎜🎜#

    Obwohl Zeitstempelfelder in MySQL zugewiesen oder aktualisiert werden können, wird empfohlen, Zeitstempelspalten nur bei Bedarf explizit einzufügen und zu aktualisieren auf einen Wert außerhalb des Systems, z. B. Die Servereinstellung in China ist ’+8:00’; Es wird empfohlen, die MySQL-Offline-Testversion und die Online-Produktionsversion konsistent zu halten.

    Ähnlichkeiten und Unterschiede zwischen Zeitstempel und Datum/Uhrzeit

    Gleiche Punkte:

    kann automatisch aktualisiert und initialisiert werden, und Das Standardanzeigeformat ist das gleiche JJJJ-MM-TT HH:mm:ss

    Unterschied:

    • #🎜🎜 #Zeitstempel-Zeitbereich: „1970-01-01 00:00:01“ UTC bis „2038-01-19 03:14:07“ UTC, automatische Zeitzonenkonvertierung, tatsächliche Speicherung von Millisekunden, 4 Bytes Speicher# 🎜🎜##🎜 🎜#

      Der Zeitbereich von datetime: ‘1000-01-01 00:00:00’ bis ‘9999-12-31 23:59:59’, Zeit Zone wird nicht unterstützt, 8 Bytes Speicher

    Stellen Sie die automatische Aktualisierungszeit von Zeitstempel und Datum ein
    • Beim Aktualisieren eines Datenelements oder Einfügen eines Neue Daten ohne Zuweisen von Werten zu Datum und MyDatum Die beiden Felder Datum und MyDatum werden automatisch auf die aktuelle Uhrzeit 19 03:14:07 UTC eingestellt, da dies ein Problem von MySQL ist selbst, das heißt, der Zeitstempel hat eine Obergrenze. Wenn diese überschritten wird, wird natürlich ein Fehler gemeldet. Einige Screenshots sind wie folgt:

    • Lösung

    • timestamp Obwohl es eine Obergrenze gibt, wird der Zeitstempel gespeichert und nicht muss verwendet werden Um das Zeitzonenproblem zu berücksichtigen, wird empfohlen, den Zeitstempel in einen Ganzzahltyp zu ändern, um den Zeitstempel zu speichern und ihn dann im Programm zu konvertieren, wenn Sie sich mit Zeitzonenanforderungen befassen und die 2038-Einschränkung lösen müssen (Diese Lösung wurde nicht implementiert, sie ist nur ein Vorschlag, verwenden Sie sie mit Vorsicht!)
    Wenn Sie das Zeitzonenproblem nicht berücksichtigen müssen, ersetzen Sie einfach den Zeitstempel durch den Datenzeittyp, da der Wertebereich von datatime ist viel größer, siehe Bild oben;

    1. Ändern Sie den Namen des ursprünglichen Feldes neues Datenzeittypfeld (erstellen Sie eine neue Spalte, um die ursprüngliche zu ersetzen);

    CREATE TABLE `mytime` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `date` timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
      `mydate` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

    Kopieren Sie die Daten der ursprünglichen Feldspalte in die neue Feldspalte; Originalspalte;

    ALTER TABLE `student` CHANGE `entry_date` `temp_entry_date` timestamp NOT NULL default '0000-00-00 00:00:00';

    Die vollständige SQL lautet wie folgt: (Beachten Sie, dass der ursprüngliche Standardwert des Zeitstempels ebenfalls hinzugefügt werden muss)

    ALTER TABLE `student` ADD `entry_date` DATETIME NOT NULL default '0000-00-00 00:00:00';

Das obige ist der detaillierte Inhalt vonSo lösen Sie das Zeitstempel-2038-Problem von MySQL. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen