【永久保存版】MariaDB/MySQL で「更新日時」を触らずに「作成日時」を設定する方法

2024-04-27

MariaDB/MySQL: CURRENT_TIMESTAMP を CREATE で設定し、UPDATE で変更しないように設定する

CURRENT_TIMESTAMP オプションを使用すると、列に挿入されるたびに自動的に現在の日付と時刻が設定されます。さらに、DEFAULT NULL オプションを組み合わせて、列に値が設定されていない場合にのみ CURRENT_TIMESTAMP を設定するようにすることができます。

CREATE TABLE mytable (
  id INT PRIMARY KEY AUTO_INCREMENT,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP NOT NULL DEFAULT NULL
);

この例では、created_at 列には常に現在の日付と時刻が設定されます。一方、updated_at 列は NULL のままになります。

ON UPDATE CURRENT_TIMESTAMP オプションを使用すると、行が更新されるたびに updated_at 列に現在の日付と時刻が自動的に設定されます。

CREATE TABLE mytable (
  id INT PRIMARY KEY AUTO_INCREMENT,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP NOT NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP
);

トリガーを使用すると、行が挿入または更新されたときにカスタムロジックを実行することができます。このロジックを使用して、updated_at 列を手動で更新することができます。

CREATE TRIGGER update_timestamp BEFORE UPDATE ON mytable
FOR EACH ROW
BEGIN
  SET NEW.updated_at = CURRENT_TIMESTAMP;
END;

この例では、mytable テーブルの行が更新される前にトリガーが実行されます。トリガーは、updated_at 列を現在の日付と時刻に設定します。

ストアドプロシージャを使用すると、データベースとのやり取りをカプセル化することができます。ストアドプロシージャを使用して、行を挿入または更新し、updated_at 列を手動で更新することができます。

CREATE PROCEDURE update_record(id INT)
BEGIN
  UPDATE mytable
  SET updated_at = CURRENT_TIMESTAMP
  WHERE id = id;
END;

この例では、update_record というストアドプロシージャが作成されます。このプロシージャは、id パラメータで指定された行の updated_at 列を更新します。

  • シンプルさを求める場合は、CURRENT_TIMESTAMP オプションを使用するのが最適です。
  • updated_at 列をより細かく制御したい場合は、ON UPDATE CURRENT_TIMESTAMP オプション、トリガー、またはストアドプロシージャを使用する必要があります。

注意事項

  • CURRENT_TIMESTAMP オプションを使用すると、updated_at 列の値がミリ秒単位で精度が制限されます。
  • トリガーとストアドプロシージャを使用すると、パフォーマンスに影響を与える可能性があります。



CREATE TABLE mytable (
  id INT PRIMARY KEY AUTO_INCREMENT,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP NOT NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP
);

このコードは、次の操作を実行します。

  1. mytable という名前のテーブルを作成します。
  2. id という名前の列を作成します。この列は主キーであり、自動的にインクリメントされます。
  3. created_at という名前の列を作成します。この列は、行が挿入されたときに現在の日付と時刻に自動的に設定されます。

このテーブルを使用するには、次のステートメントを実行できます。

INSERT INTO mytable (name, email)
VALUES ('John Doe', '[email protected]');

このステートメントは、次の行を mytable テーブルに挿入します。

id | created_at           | updated_at           | name      | email
---+----------------------+----------------------+-----------+------------------
1  | 2024-04-26 16:44:00 | 2024-04-26 16:44:00 | John Doe  | [email protected]

次に、次のステートメントを実行して行を更新できます。

UPDATE mytable
SET name = 'Jane Doe'
WHERE id = 1;

このステートメントは、mytable テーブルの id が 1 の行を更新します。更新された行は次のようになります。

id | created_at           | updated_at           | name      | email
---+----------------------+----------------------+-----------+------------------
1  | 2024-04-26 16:44:00 | 2024-04-26 16:44:00 | Jane Doe  | [email protected]

ご覧のとおり、created_at 列は変更されませんが、updated_at 列は更新されました。

以下の追加例では、トリガーストアドプロシージャ を使用して updated_at 列を更新する方法を示します。

トリガーを使用する場合

CREATE TRIGGER update_timestamp BEFORE UPDATE ON mytable
FOR EACH ROW
BEGIN
  SET NEW.updated_at = CURRENT_TIMESTAMP;
END;

ストアドプロシージャを使用する場合

CREATE PROCEDURE update_record(id INT)
BEGIN
  UPDATE mytable
  SET updated_at = CURRENT_TIMESTAMP
  WHERE id = id;
END;

このストアドプロシージャは、id パラメータで指定された行の updated_at 列を更新します。

CALL update_record(1);

これらの例は、MariaDB または MySQLCREATE 時に CURRENT_TIMESTAMP を設定し、UPDATE 操作で変更されないようにする方法をいくつか示しています。




MariaDB/MySQL で CURRENT_TIMESTAMP を CREATE 時に設定し、UPDATE で変更しないように設定するその他の方法

列属性の変更

既存のテーブルを変更して、updated_at 列の属性を更新することもできます。

ALTER TABLE mytable
MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

このコマンドは、mytable テーブルの updated_at 列を、NULL を許さず、挿入時に現在の日付と時刻に自動的に設定され、更新時に自動的に更新されるように変更します。

ビューを使用する

仮想テーブルであるビューを使用して、updated_at 列を常に現在の日付と時刻に表示することができます。

CREATE VIEW mytable_view AS
SELECT id, created_at, CURRENT_TIMESTAMP AS updated_at
FROM mytable;

このビューを使用すると、updated_at 列は常に現在の日付と時刻が表示されますが、実際の updated_at 列は変更されません。

アプリケーションロジックを使用して、updated_at 列を手動で更新することもできます。これは、よりきめ細かい制御が必要な場合に役立ちます。

import datetime

def update_record(id, connection):
  # 行をデータベースから取得
  cursor = connection.cursor()
  cursor.execute('SELECT * FROM mytable WHERE id = ?', (id,))
  row = cursor.fetchone()

  # updated_at 列を現在の日付と時刻に設定
  row['updated_at'] = datetime.datetime.now()

  # 行を更新
  cursor.execute('UPDATE mytable SET created_at = ?, updated_at = ? WHERE id = ?', (row['created_at'], row['updated_at'], id))
  connection.commit()

# 例の使い方
connection = connect_to_database()
update_record(1, connection)
connection.close()

この例では、update_record 関数は id で指定された行の updated_at 列を現在の日付と時刻に更新します。

最適な方法の選択

使用する方法は、特定のニーズによって異なります。

  • updated_at 列をより細かく制御したい場合は、トリガー、ストアドプロシージャ、ビュー、またはアプリケーションロジックを使用する必要があります。
  • アプリケーションロジックを使用すると、開発とメンテナンスのコストがかかります。

mysql mariadb


【MySQL TIPS】フィールドの長さを取得して文字数制限のある処理に役立てる

MySQL において、フィールドの長さが 1 文字を超える場合、その長さ (文字数) を取得するには、いくつかの方法があります。 以下では、代表的な 2 つの方法について、詳細な解説と例を交えてご紹介します。方法 1: LENGTH() 関数を使用する...


PHPでMySQLのIN句を使って効率的にデータを更新する方法とは?サンプルコード付き

MySQL において、IN 句を用いた UPDATE ステートメントで更新できる行数に 理論的な制限はありません。しかし、実用的な観点 からは、以下の要素によって制限が生じる可能性があります。インデックスの有無と種類IN 句に含まれる値の個数...


知っておけばよかった!MySQL/MariaDBでInnoDBテーブルからレコードを削除する際の注意点とトラブルシューティング

DELETE ステートメントを使用するこれは、シンプルで基本的な方法です。長所:理解しやすい構文特定の条件に基づいてレコードを削除できる大量のレコードを削除する場合、処理が遅くなる可能性があるロック競合が発生する可能性があるTRUNCATE TABLEを使用する...


【保存版】Dockerコンテナ内のMariaDBにデータをスムーズに投入

Dockerfileは、Dockerイメージを構築する際に使用する設定ファイルです。このファイル内に CMD や ENTRYPOINT を用いて、MariaDB起動時にデータ投入スクリプトを実行するコマンドを記述できます。メリット:シンプルで分かりやすい...


SQL SQL SQL SQL Amazon で見る



【MySQLエラー1293徹底解説】CURRENT_TIMESTAMPを複数列で使いたい?5つの解決策&サンプルコード

MySQLでテーブルを作成する際、列のデフォルト値として現在時刻を自動的に挿入したい場合があります。その場合、TIMESTAMPデータ型とCURRENT_TIMESTAMPキーワードを使用します。しかし、DEFAULT句でCURRENT_TIMESTAMPを指定できるTIMESTAMP列は1つだけという制約があります。これが原因で、以下のエラーが発生することがあります。


MariaDB CURRENT_TIMESTAMP デフォルト値を使いこなして、タイムスタンプ管理をマスターしよう

MariaDB の CURRENT_TIMESTAMP は、現在の日時を返す関数です。デフォルト値は、レコードが作成されたときと更新されたときの両方で、現在のタイムスタンプになります。デフォルト値の動作新しいレコードを作成すると、CURRENT_TIMESTAMP を使用して TIMESTAMP または DATETIME 型の列に自動的に値が挿入されます。