This is a read-only copy of the MariaDB Knowledgebase generated on 2024-12-26. For the latest, interactive version please visit https://mariadb.com/kb/.

Sequence 存储引擎

本文介绍了 Sequence 存储引擎。有关序列对象的详细信息,请参阅序列

Sequence 引擎允许创建具有给定起始值、结束值和增量的升序或降序数字序列(正整数)。

当您需要时,它会自动创建完全虚拟的、短暂的表。没有办法显式地创建 Sequence 表。它们也不会写入磁盘或创建 .frm 文件。它们是只读的,支持事务,并且支持 XA

安装

Sequence 引擎默认安装,SHOW ENGINES 将列出支持的 Sequence 存储引擎:

SHOW ENGINES\G
...
*************************** 5. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: SEQUENCE
     Support: YES
     Comment: Generated tables filled with sequential values
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 7. row ***************************
      Engine: MRG_MyISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO

...

用法和示例

要使用 Sequence 表,您只需从中进行选择,如下所示

SELECT * FROM seq_1_to_5;
+-----+
| seq |
+-----+
|   1 |
|   2 |
|   3 |
|   4 |
|   5 |
+-----+

要在语句中使用序列,您需要从以模式 seq_FROM_to_TOseq_FROM_to_TO_step_STEP 命名的表中进行选择。

对于奇数步长,序列将从 FROM 开始,并在达到 TO 前的最终结果结束。

SELECT * FROM seq_1_to_15_step_3;
+-----+
| seq |
+-----+
|   1 |
|   4 |
|   7 |
|  10 |
|  13 |
+-----+

序列也可以向后移动。在这种情况下,最终值将始终是 TO 值,因此降序序列与升序序列具有相同的值:

SELECT * FROM seq_5_to_1_step_2;
+-----+
| seq |
+-----+
|   5 |
|   3 |
|   1 |
+-----+
SELECT * FROM seq_15_to_1_step_3;
+-----+
| seq |
+-----+
|  13 |
|  10 |
|   7 |
|   4 |
|   1 |
+-----+
SELECT * FROM seq_15_to_2_step_3;
+-----+
| seq |
+-----+
|  14 |
|  11 |
|   8 |
|   5 |
|   2 |
+-----+

这个引擎在连接和子查询中特别有用。例如,此查询查找所有小于50的素数:

SELECT seq FROM seq_2_to_50 s1 WHERE 0 NOT IN
     (SELECT s1.seq % s2.seq FROM seq_2_to_50 s2 WHERE s2.seq <= sqrt(s1.seq));
+-----+
| seq |
+-----+
|   2 |
|   3 |
|   5 |
|   7 |
|  11 |
|  13 |
|  17 |
|  19 |
|  23 |
|  29 |
|  31 |
|  37 |
|  41 |
|  43 |
|  47 |
+-----+

并且几乎(除了2,唯一的偶素数)使用连接得到相同的结果:

SELECT s1.seq FROM seq_2_to_50 s1 JOIN seq_2_to_50 s2 
  WHERE s1.seq > s2.seq AND s1.seq % s2.seq <> 0 
  GROUP BY s1.seq HAVING s1.seq - COUNT(*) = 2;
+-----+
| seq |
+-----+
|   3 |
|   5 |
|   7 |
|  11 |
|  13 |
|  17 |
|  19 |
|  23 |
|  29 |
|  31 |
|  37 |
|  41 |
|  43 |
|  47 |
+-----+

序列表在日期计算中也很有用。例如,要查找在40年期间特定日期所在的星期几(也许是为了提前计划生日!):

SELECT DAYNAME('1980-12-05' + INTERVAL (seq) YEAR) day,
    '1980-12-05' + INTERVAL (seq) YEAR date FROM seq_0_to_40;
+-----------+------------+
| day       | date       |
+-----------+------------+
| Friday    | 1980-12-05 |
| Saturday  | 1981-12-05 |
| Sunday    | 1982-12-05 |
...
| Friday    | 2014-12-05 |
| Saturday  | 2015-12-05 |
| Monday    | 2016-12-05 |
| Tuesday   | 2017-12-05 |
| Wednesday | 2018-12-05 |
| Thursday  | 2019-12-05 |
| Saturday  | 2020-12-05 |
+-----------+------------+

虽然序列表只能直接使用正整数,但它们可以间接地利用 CAST 语句返回负结果。例如:

SELECT CAST(seq AS INT) - 5 x FROM seq_5_to_1;
+----+
| x  |
+----+
|  0 |
| -1 |
| -2 |
| -3 |
| -4 |
+----+

需要使用 CAST 来避免出现 BIGINT UNSIGNED value is out of range 错误。

虽然序列表是虚拟的,但它们仍然是表,因此它们必须在数据库中。这意味着必须选择默认数据库(例如,通过 USE 命令)才能查询序列表。不能将 information_schema 数据库用作序列表的默认值。

表名冲突

如果安装了 SEQUENCE 存储引擎,则不可能创建一个遵循 SEQUENCE 模式命名的表:

CREATE TABLE seq_1_to_100 (col INT) ENGINE = InnoDB;
ERROR 1050 (42S01): Table 'seq_1_to_100' already exists

但是,SEQUENCE 表可以转换为另一个引擎,并且可以在任何语句中引用新表:

ALTER TABLE seq_1_to_100 ENGINE = BLACKHOLE;

SELECT * FROM seq_1_to_100;
Empty set (0.00 sec)

虽然无法删除 SEQUENCE 表,但是可以删除转换后的表。具有相同名称的 SEQUENCE 表仍将存在:

DROP TABLE seq_1_to_100;

SELECT COUNT(*) FROM seq_1_to_100;
+----------+
| COUNT(*) |
+----------+
|      100 |
+----------+
1 row in set (0.00 sec)

始终可以创建并使用类似于 SEQUENCE 的临时表:

CREATE TEMPORARY TABLE seq_1_to_100 (col INT) ENGINE = InnoDB;

SELECT * FROM seq_1_to_100;
Empty set (0.00 sec)

资源

Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.