我可以为MySQL的每一行定义一个生命周期吗?

时间:2016-06-27 22:38:20

标签: mysql sql database

我有一张这样的表:

// banned
+----+---------+---------------+
| id | user_id |   unix_time   |
+----+---------+---------------+
| 1  | 32534   | 1467066745524 |
| 2  | 43535   | 1467066745541 |
| 3  | 24352   | 1467066745618 |
| 4  | 88734   | 1467066746093 |
+----+---------+---------------+

实际上我需要在插入时为每行定义一个到期时间。这在MySQL可能吗? (我听说Redis有可能,那么MySQL呢?)

所以我想要这样的事情:

// banned
+----+---------+---------------+
| id | user_id |   unix_time   |
+----+---------+---------------+
| 1  | 32534   | 1467066745524 | -- removing this row automatically in 10 min
| 2  | 43535   | 1467066745541 | -- removing this row automatically in 1 hour
| 3  | 24352   | 1467066745618 | -- removing this row automatically 2 day
| 4  | 88734   | 1467066746093 | -- removing this row automatically 8 hours min
+----+---------+---------------+

如您所见,每一行都有一个任意的生命周期。

2 个答案:

答案 0 :(得分:4)

你可以创建一个每分钟运行的EVENT并删除这样的旧记录:

启用调度程序

SET GLOBAL event_scheduler = ON;

每分钟创建一次EVENT

CREATE EVENT cleanup
ON SCHEDULE EVERY 1 MINUTE
DO 
 DELETE
  FROM yourTable
  WHERE unix_time < UNIX_TIMESTAMP();

<强>示例

MariaDB [yourschema]> SET GLOBAL event_scheduler = ON;
Query OK, 0 rows affected (0.00 sec)

MariaDB [yourschema]> SHOW GLOBAL VARIABLES LIKE 'event_scheduler';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | ON    |
+-----------------+-------+
1 row in set (0.00 sec)

MariaDB [yourschema]> SHOW PROCESSLIST;
+-----+-----------------+-----------------+------------+---------+------+-----------------------------+------------------+----------+
| Id  | User            | Host            | db         | Command | Time | State                       | Info             | Progress |
+-----+-----------------+-----------------+------------+---------+------+-----------------------------+------------------+----------+
|  28 | root            | localhost:53255 | yourSchema | Sleep   |   11 |                             | NULL             |    0.000 |
|  29 | root            | localhost:53256 | NULL       | Sleep   |   28 |                             | NULL             |    0.000 |
|  34 | event_scheduler | localhost       | NULL       | Daemon  | 6603 | Waiting for next activation | NULL             |    0.000 |
| 316 | root            | localhost       | yourschema | Query   |    0 | init                        | SHOW PROCESSLIST |    0.000 |
+-----+-----------------+-----------------+------------+---------+------+-----------------------------+------------------+----------+
4 rows in set (0.00 sec)

MariaDB [yourschema]>
MariaDB [yourschema]> SHOW events;
Empty set (0.01 sec)

MariaDB [yourschema]> DROP EVENT IF EXISTS cleanup;
Query OK, 0 rows affected, 1 warning (0.00 sec)

MariaDB [yourschema]> CREATE EVENT cleanup
    -> ON SCHEDULE EVERY 5 SECOND  ON COMPLETION PRESERVE ENABLE
    -> DO
    ->  DELETE
    ->   FROM schedulerTable
    ->   WHERE expire_unix_time < UNIX_TIMESTAMP() LIMIT 10;
Query OK, 0 rows affected (0.00 sec)

MariaDB [yourschema]> INSERT INTO schedulerTable VALUES
    -> (NULL,100,UNIX_TIMESTAMP(now() + INTERVAL 30 SECOND)),
    -> (NULL,101,UNIX_TIMESTAMP(now() + INTERVAL 40 SECOND)),
    -> (NULL,111,UNIX_TIMESTAMP(now() + INTERVAL  1 MINUTE));
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

MariaDB [yourschema]> SELECT * FROM schedulerTable;SELECT SLEEP(20);
+-------------+---------+------------------+
| id_rubrique | id_stat | expire_unix_time |
+-------------+---------+------------------+
|           1 |     100 |       1467074632 |
|           2 |     101 |       1467074642 |
|           3 |     111 |       1467074662 |
+-------------+---------+------------------+
3 rows in set (0.00 sec)

+-----------+
| SLEEP(20) |
+-----------+
|         0 |
+-----------+
1 row in set (20.00 sec)

MariaDB [yourschema]> SELECT * FROM schedulerTable;SELECT SLEEP(20);
+-------------+---------+------------------+
| id_rubrique | id_stat | expire_unix_time |
+-------------+---------+------------------+
|           2 |     101 |       1467074642 |
|           3 |     111 |       1467074662 |
+-------------+---------+------------------+
2 rows in set (0.00 sec)

+-----------+
| SLEEP(20) |
+-----------+
|         0 |
+-----------+
1 row in set (20.01 sec)

MariaDB [yourschema]> SELECT * FROM schedulerTable;SELECT SLEEP(20);
+-------------+---------+------------------+
| id_rubrique | id_stat | expire_unix_time |
+-------------+---------+------------------+
|           3 |     111 |       1467074662 |
+-------------+---------+------------------+
1 row in set (0.00 sec)


+-----------+
| SLEEP(20) |
+-----------+
|         0 |
+-----------+
1 row in set (20.01 sec)

MariaDB [yourschema]> SELECT * FROM schedulerTable;
Empty set (0.00 sec)

MariaDB [yourschema]>

答案 1 :(得分:3)

可以创建一个视图,如下所示:

int

或者:

create view v_table as
    select (case when unix_time < UNIX_TIMESTAMP() then id end) as id,
           (case when unix_time < UNIX_TIMESTAMP() then user_id end) as user_id
    from banned;

在时间戳之后不返回有关用户的信息。然后,您可以安排事件定期删除包含过期信息的行。