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))

插入新的 (entity_id,group_id) 对时我自然会收到错误,因为 first_seen 可能不是 NULL ...

这可以在一个语句中完成,而不是使用触发器(我不喜欢它们,对于维护来说太令人惊讶了)

还是我需要先选择存在,然后相应地插入/更新?

4

4 回答 4

2

不,如果没有触发器,您的要求是不可能的。在 MySQL 中,可以从函数中为字段分配默认值的唯一示例是 TIMESTAMP 类型,它可以将 CURRENT_TIMESTAMP 作为默认值。

于 2009-07-17T09:51:44.510 回答
1

老实说,几乎不可能将更新或插入合并到一个语句中。

如果您使用的是脚本,我会按照您的建议进行操作。首先检查是否存在,然后相应地更新或插入。

否则,触发器或存储过程将完成这项工作。

于 2009-07-17T09:45:36.597 回答
1

您可以使用TIMESTAMP数据类型,它允许默认值为CURRENT_TIMESTAMP,但这会将其设置为NOW()而不是一天前。

所以,我宁愿使用 useINSERT... 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 回答
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 回答