MYSQL:如何创建 MySQL 表,以便字段的默认值是函数的输出

发布于 2024-07-26 19:32:04 字数 786 浏览 6 评论 0原文

问题 如何创建 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...

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

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

QUESTION How can I create a MySQL table so, that a field's default value is the output of a function.

Can it be done without an insert trigger?

BACKGROUND: Some entities and the groups they belong to need to be observed on a daily basis.

To do that I created the following MySQL table:

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

A script parses the entity logs on a daily basis and writes to to entity_raw, I then want to update the tables using

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

Naturally I get an error when inserting new (entity_id,group_id) pairs, since first_seen may not be NULL...

Can this be done in one statement, short of using a trigger (I dislike them, too surprising for maintenance)

or do I need to select for existance first, then insert/update accordingly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

疯狂的代价 2024-08-02 19:32:04

不,如果没有触发器,您所问的问题是不可能的。 MySQL 中唯一可以通过函数为字段分配默认值的示例是 TIMESTAMP 类型,该类型可以将 CURRENT_TIMESTAMP 作为默认值。

No, what you're asking isn't possible without triggers. The only example in MySQL where a field can be assigned a default value from a function is the TIMESTAMP type that can have CURRENT_TIMESTAMP as default.

可是我不能没有你 2024-08-02 19:32:04

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

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

否则触发器或存储过程就可以完成这项工作。

To be honest it's pretty much impossible to combine an update or insert into one statement.

If you are using a script, I would do as you suggested. First check for existence, then update or insert accordingly.

Otherwise a trigger or stored procedure would do the job.

朮生 2024-08-02 19:32:04

您可以使用 TIMESTAMP 数据类型,它允许默认值为 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)

使用唯一索引 en entity_id 和/或 group_id。 当找到现有行时,这只会覆盖 last_seen

You could use the TIMESTAMP data type, which allows a default value of CURRENT_TIMESTAMP, but that would set it to NOW() and not to a day ago.

So, I would rather use use an INSERT... ON DUPLICATE KEY UPDATE statement:

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)

with a unique index en entity_id and/or group_id. This will overwrite only last_seen when an existing row is found.

魂牵梦绕锁你心扉 2024-08-02 19:32:04

经过一番搜索后,我想出了这个..它解决了我的“问题”,但不是我问的问题:-(

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 周的数据)

After some searching I came up with this .. it solves my "problem", but not the question I asked :-(

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

The initial insert needs to be done with the where clause disabled (there were already 5weeks of data in the entity_raw table)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文