MySQLで数値シーケンス(データ)を生成する方法

プロジェクトを開発するときは、定期的にテーブル内のデータを生成する必要があります。これにより、後でテストに従って実行して作業パフォーマンスを評価できます(インデックスが使用されているかどうか、クエリが大きなサンプルで実行するのにかかる時間など)。 このために、通常、プロジェクトの実装されたAPI機能(関数)(php、node.jsなど)が取得され、CLIを介して実行され、テーブルデータが挿入されます(挿入)。 短所は、すぐにできないことです。



特に数千万行のデータを生成する必要がある場合。 PostgreSQLデータベースを調べると、テーブル返す既成の関数generate_series()が既にあることがわかりました。この関数は、簡単にリダイレクトして別のテーブルにデータを挿入できます。 使い方は非常に簡単で便利で、値を生成する間隔を指定できます。 MySQLデータベースでの同様の実装を検討するために、いくつかの例を示します。



数値シーケンスを生成する例。



postgres=# SELECT * FROM generate_series(1,10); generate_series ----------------- 1 2 3 4 5 6 7 8 9 10 (10 rows)
      
      





情報の追加説明を行う場合。



 postgres=# explain SELECT * FROM generate_series(1,10); QUERY PLAN ------------------------------------------------------------------------ Function Scan on generate_series (cost=0.00..10.00 rows=1000 width=4) (1 row)
      
      







数値シーケンスとそれに続くテーブルでのベットを生成する例。



 postgres=# create table test (number int); CREATE TABLE postgres=# \d List of relations Schema | Name | Type | Owner --------+------+-------+---------- public | test | table | postgres (1 row)
      
      





 postgres=# insert into test select * from generate_series(1,10); INSERT 0 10 postgres=# select * from test; number -------- 1 2 3 4 5 6 7 8 9 10 (10 rows)
      
      





SQLレベルでPostgreSQLに同様の関数を自分で記述し、それに応じて必要なシーケンスを記述することができます。 たとえば、車のナンバープレート、書類、現金領収書。 ドキュメントは、テキスト、日付のリストなどを生成するための興味深いオプションを提供します。



MySQLデータベースに戻ります。 同様の機能はありますか?



インターネットでの検索の結果、この機能はバージョン10以降のMariaDBデータベース(MySQL応答)に登場しました。 実装は関数としてではなく、別の追加データベースエンジンとして実行されました。innodb、myisamと同様です。 使用方法も興味深く、非常に便利です。



1から5までの数値シーケンスの生成。



 MariaDB [metemplate]> SELECT * FROM seq_1_to_5; +-----+ | seq | +-----+ | 1 | | 2 | | 3 | | 4 | | 5 | +-----+ 5 rows in set (0.00 sec)
      
      





間隔が2の1〜15の数値シーケンスの生成。



 MariaDB [metemplate]> SELECT * FROM seq_1_to_15_step_2; +-----+ | seq | +-----+ | 1 | | 3 | | 5 | | 7 | | 9 | | 11 | | 13 | | 15 | +-----+ 8 rows in set (0.00 sec)
      
      





おそらく既に推測したように、最初の数値は初期値、2番目の最大値、3番目の反復ステップを示しています。 whileの最も単純なループの類似物。 たとえば、PHPの場合。



 <?php function seq($start, $stop, $step) { $iter = 0; while($start <= $stop) { echo "{$iter} => {$start} \n"; $start += $step; $iter += 1; } } seq(1,15,2); ?>
      
      





 [root@localhost ~]# php while.php 0 => 1 1 => 3 2 => 5 3 => 7 4 => 9 5 => 11 6 => 13 7 => 15
      
      





機能は生成のみに限定されません。 通常の通常のテーブルのように、結合を実行できます。



 MariaDB [metemplate]> desc example; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | a | int(11) | YES | MUL | NULL | | | b | int(11) | YES | MUL | NULL | | +-------+---------+------+-----+---------+-------+ 2 rows in set (0.01 sec)
      
      





 MariaDB [metemplate]> select example.a, example.b from example inner join (select seq from seq_1_to_15) as generate on generate.seq = example.a; +------+------+ | a | b | +------+------+ | 1 | 2 | | 4 | 1 | | 2 | 7 | | 9 | 9 | | 1 | 19 | | 11 | 12 | +------+------+ 6 rows in set (0.00 sec)
      
      







より詳細な例は、 ドキュメントに記載されていますデフォルトでは、このエンジンは接続されていないため、コマンドを実行する必要があります。



 INSTALL SONAME "ha_sequence";
      
      







楽しみのために、シーケンスをエンジンとして指定するExplainを使用して表を表示することもできます。



 MariaDB [metemplate]> show create table seq_1_to_15\G; *************************** 1. row *************************** Table: seq_1_to_15 Create Table: CREATE TABLE `seq_1_to_15` ( `seq` bigint(20) unsigned NOT NULL, PRIMARY KEY (`seq`) ) ENGINE=SEQUENCE DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
      
      







 MariaDB [metemplate]> show index from seq_1_to_15\G; *************************** 1. row *************************** Table: seq_1_to_15 Non_unique: 0 Key_name: PRIMARY Seq_in_index: 1 Column_name: seq Collation: A Cardinality: NULL Sub_part: NULL Packed: NULL Null: Index_type: Comment: Index_comment: 1 row in set (0.01 sec)
      
      





 MariaDB [metemplate]> desc seq_1_to_15; +-------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------------+------+-----+---------+-------+ | seq | bigint(20) unsigned | NO | PRI | NULL | | +-------+---------------------+------+-----+---------+-------+ 1 row in set (0.00 sec)
      
      





以前のバージョンのMySQL(MariaDB)で何をすべきですか? この場合、この問題をほぼ何らかの形で解決する一種の松葉杖ソリューションがありますが、実際にはそうではありません。



例1



 MariaDB [metemplate]> create table two select null foo union all select null; MariaDB [metemplate]> create temporary table seq ( foo int primary key auto_increment ) auto_increment=1 select a.foo from two a, two b, two c, two d; Query OK, 16 rows affected (0.08 sec) Records: 16 Duplicates: 0 Warnings: 0
      
      





 MariaDB [metemplate]> select * from seq where foo <= 23; +-----+ | foo | +-----+ | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | | 15 | | 16 | | 17 | | 18 | | 19 | | 20 | | 21 | | 22 | | 23 | +-----+ 15 rows in set (0.00 sec)
      
      





例2



 MariaDB [metemplate]> CREATE OR REPLACE VIEW generator_16 -> AS SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL -> SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL -> SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL -> SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL -> SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL -> SELECT 15; Query OK, 0 rows affected (0.09 sec)
      
      





 MariaDB [metemplate]> select * from generator_16; +----+ | n | +----+ | 0 | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | | 15 | +----+ 16 rows in set (0.01 sec)
      
      






All Articles