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_TO
或 seq_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)
资源
- Sometimes its the little things - Dean Ellis 尝试使用 Sequence 引擎。
- MariaDB 的 Sequence 存储引擎 - Federico Razzoli 对该引擎进行了更深入的介绍。