1

質問フィールドのデフォルト値が関数の出力になるように、MySQL テーブルを作成するにはどうすればよいですか。

挿入トリガーなしで実行できますか?

背景:一部のエンティティとそれらが属するグループは、日常的に観察する必要があります。

そのために、次の MySQL テーブルを作成しました。

CREATE TABLE entity (
    entity_id  VARCHAR(10) NOT NULL,
    group_id   VARCHAR(10) NOT NULL,
    first_seen DATE        NOT NULL,
    last_seen  DATE        NOT NULL,
    PRIMARY KEY (entity_id,group_id)
)

スクリプトはエンティティ ログを毎日解析し、entity_raw に書き込みます。次に、次を使用してテーブルを更新します。

REPLACE INTO entity (entity_id,group_id,last_seen) 
SELECT entity_id,group_id,record_date 
  FROM entity_raw 
 WHERE (record_date = DATE(DATE_SUB(NOW(),INTERVAL 1 DAY))

first_seen が NULL でない可能性があるため、当然、新しい (entity_id,group_id) ペアを挿入するとエラーが発生します...

トリガーを使用せずに、これを1つのステートメントで実行できますか(私はそれらが嫌いです。メンテナンスにはあまりにも驚くべきことです)

または、最初に存在を選択してから、それに応じて挿入/更新する必要がありますか?

4

4 に答える 4

2

いいえ、あなたが求めていることは、トリガーなしでは不可能です。関数からフィールドにデフォルト値を割り当てることができる MySQL の唯一の例は、デフォルトとして CURRENT_TIMESTAMP を持つことができる TIMESTAMP タイプです。

于 2009-07-17T09:51:44.510 に答える
1

TIMESTAMPのデフォルト値を許可するデータ型を使用できますが、それは 1 日前ではなく 1 日前にCURRENT_TIMESTAMP設定されます。NOW()

INSERT... ON DUPLICATE KEY UPDATEしたがって、私はステートメントを使用したいと思います。

INSERT INTO entity (entity_id,group_id,first_seen,last_seen) 
SELECT entity_id,group_id,record_date, record_date 
    FROM entity_raw 
    WHERE (record_date = DATE(DATE_SUB(NOW(),INTERVAL 1 DAY))
ON DUPLICATE KEY UPDATE last_seen = VALUES(last_seen)

一意のインデックス enentity_idおよび/またはgroup_id. last_seenこれは、既存の行が見つかった場合にのみ上書きされます。

于 2009-07-17T09:56:47.433 に答える
1

正直なところ、更新または挿入を 1 つのステートメントに結合することはほとんど不可能です。

スクリプトを使用している場合は、あなたが提案したとおりにします。最初に存在を確認してから、それに応じて更新または挿入します。

それ以外の場合は、トリガーまたはストアド プロシージャがその役割を果たします。

于 2009-07-17T09:45:36.597 に答える
0

いくつかの検索の後、私はこれを思いつきました..それは私の「問題」を解決しますが、私が尋ねた質問ではありません:-(

REPLACE INTO entity (entity_id,group_id,first_seen,last_seen) 
SELECT r.entity_id              AS entity_id
     , r.group_id               AS group_id
     , ISNULL( e.first_seen
              ,r.record_date
             )                  AS first_seen
     , r.record_date            AS last_seen
  FROM entity_raw r
  LEFT OUTER JOIN entity e ON (    r.entity_id=e.entity_id 
                               AND r.group_id=e.group_id
                              )
 WHERE (record_date = DATE(DATE_SUB(NOW(),INTERVAL 1 DAY))

最初の挿入は、where 句を無効にして行う必要があります (entity_raw テーブルには既に 5 週間のデータがありました)。

于 2009-07-17T09:57:57.477 に答える