COUNT()関数の中身の書き方による動作の違い

 自分では「知っている」と思っていても、会話の中でふと自信がなくなることってありますよね。 自分の知識として「常識」になっているけど、気づけば10年以上も意識して試したことのないものとか。
表題のテーマが、今回の私のソレです。

 ということで、COUNT(*) とか COUNT(カラム名) とかの書き方で動作がどう変わるのか改めて試した結果を整理してみた、という、初心者向きの内容です。


どんな書き方があるか

COUNT(*)      
COUNT(カラム名)  
COUNT(DISTINCT カラム名)

 これらはそのカラムが NULL の行が存在するか否かで結果が変わります。


サンプルデータ

CREATE TABLE sample01 (id integer primary key, code char(2), name varchar(20));

INSERT INTO sample01 VALUES (1, '21', '名前1');
INSERT INTO sample01 VALUES (2, '22', '名前2');
INSERT INTO sample01 VALUES (3, null, '名前3');
INSERT INTO sample01 VALUES (4, '22', '名前4');
INSERT INTO sample01 VALUES (5, '22', '名前5');
INSERT INTO sample01 VALUES (6, '21', '名前6');
INSERT INTO sample01 VALUES (7, null, '名前7');
mysql> SELECT * FROM sample01;
+----+------+---------+
| id | code | name    |
+----+------+---------+
|  1 | 21   | 名前1   |
|  2 | 22   | 名前2   |
|  3 | NULL | 名前3   |
|  4 | 22   | 名前4   |
|  5 | 22   | 名前5   |
|  6 | 21   | 名前6   |
|  7 | NULL | 名前7   |
+----+------+---------+
7 rows in set (0.01 sec)

COUNT(*)

 COUNT(*) は、条件に該当する全行の数を返します。今回はWHEREを指定していないのでテーブル全件の7件が返ります。もちろん WHERE を指定すればそれに合致する行の数が返ります。

mysql> SELECT COUNT(*) FROM sample01;
+----------+
| COUNT(*) |
+----------+
|        7 |
+----------+
1 row in set (0.00 sec)

COUNT(カラム名)

 COUNT()の中にカラム名を指定した場合、そのカラムに有効な値がセットされているものの行数が返ります。もう少し具体的に言うと「NULLでないものの行数」が返ります。

mysql> SELECT COUNT(code) FROM sample01;
+-------------+
| COUNT(code) |
+-------------+
|           5 |
+-------------+
1 row in set (0.00 sec)

 このことは、もちろんちゃんと知っていればこのような動作であることを見ただけで理解できるのですが、一般には直感的だとは私は思えません。
NULLを除外した件数を取得したい場合は、私ならまず以下のように条件として明示することを勧めたいところです。
(他の取得カラムや抽出条件との関係で、意図して COUNT(カラム名)を使う場合もあります)

mysql> SELECT COUNT(*) FROM sample01 WHERE code IS NOT NULL;
+----------+
| COUNT(*) |
+----------+
|        5 |
+----------+
1 row in set (0.00 sec)

COUNT(DISTINCT カラム名)

 COUNT()の中に DISTINCT カラム名 を指定した場合は、指定されたカラムのユニーク項目数を返します。NULLは含まれません。
以下のとおり「2」(codeの値が 21 と 22の2種類あるので)と返ってくることが確認できました。

mysql> SELECT COUNT(DISTINCT code) FROM sample01;
+----------------------+
| COUNT(distinct code) |
+----------------------+
|                    2 |
+----------------------+
1 row in set (0.00 sec)

余談

 実は「*」には "その行がある"、という程度の意味しかなくて(私の理解が間違っていたらご指摘ください>ガチ勢のみまさま)、つまり行に相当する何かあればカウント対象になるわけです。ですから、固定文字列だったり適当な数字だったりを指定しても COUNT(*) と同様の動作をします。誰も何の得もしないので、よい子はまねをしないように。

mysql> SELECT COUNT('test') FROM sample01;
+---------------+
| COUNT('test') |
+---------------+
|             7 |
+---------------+
1 row in set (0.00 sec)

mysql> SELECT COUNT(3.141592) FROM sample01;
+-----------------+
| COUNT(3.141592) |
+-----------------+
|               7 |
+-----------------+
1 row in set (0.00 sec)

.



.

追記(2022/07/20 00:15)

 さっそく yoku0825さんからツッコミをいただきました。

EXPLAIN(5.6とそれ以前はEXTENDED)からのSHOW WARNINGSで見ると、COUNT(*)はCOUNT(1)にオプティマイズされてるっぽいですよね


 確かに、EXPLAIN 取ってみると、warning が1件出ている! 
(関係ないけど Extra 列に最近マイブームのUsingが出ています。本当に関係ない)

mysql> explain SELECT COUNT(*) FROM sample01;
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | sample01 | NULL       | index | NULL          | PRIMARY | 4       | NULL |    7 |   100.00 | Using index |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)


 warningの中身を見てみると・・・・・・

mysql> show warnings;
+-------+------+---------------------------------------------------------------------+
| Level | Code | Message                                                             |
+-------+------+---------------------------------------------------------------------+
| Note  | 1003 | /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`sample01` |
+-------+------+---------------------------------------------------------------------+
1 row in set (0.00 sec)

COUNT(*) が COUNT(0)になってるー!!!!


一方の COUNT('TEST') (よい子はまねしちゃいけないやつ)は、、、、、

mysql> desc SELECT COUNT('TEST') FROM sample01;
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | sample01 | NULL       | index | NULL          | PRIMARY | 4       | NULL |    7 |   100.00 | Using index |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+-------+------+-------------------------------------------------------------------------------+
| Level | Code | Message                                                                       |
+-------+------+-------------------------------------------------------------------------------+
| Note  | 1003 | /* select#1 */ select count('TEST') AS `COUNT('TEST')` from `test`.`sample01` |
+-------+------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)


・・・そのまま(笑)。

.


.

追記(2022/07/20 09:00)

 とみたまさひろさんから、COUNT()の引数は「式」であるとの指摘をいただきました。なるほど!

 なんか面白いことできないかと試みたのですが、以下、code列の値が21であるものの件数を得る試みですが、マッチしない場合の結果は NULL ではなく false(というか0) になるだけなので、意図失敗。

mysql> SELECT COUNT(code=21) FROM sample01;
+----------------+
| COUNT(code=21) |
+----------------+
|              5 |
+----------------+
1 row in set (0.01 sec)

 やりたければ、こうなんだろうけど、ここまでやらなくてもねぇ(笑)。

mysql> SELECT COUNT(CASE code WHEN 21 THEN true ELSE null END) FROM sample01;
+--------------------------------------------------+
| COUNT(CASE code WHEN 21 THEN true ELSE null END) |
+--------------------------------------------------+
|                                                2 |
+--------------------------------------------------+
1 row in set (0.00 sec)

TiDB User Day 2022に参加してきた話

 開催から2週間近くが経ってしまいましたが、「TiDB User Day」が開催され、参加してきました。非常に有意義かつ楽しい時間だったので、日記にしたためておきたいと思います。なお、当方、分散DBについてはまだよく分かっていないので、技術的な詳しい内容は書きません。「感想文」または「日記」としてご覧いただければと思います。


 当日の模様については、以下のリンク先に動画および講演資料が公開されているので、私の日記なんかよりもこちらを参考にしてください。
pingcap.co.jp



 さて、今回の TiDB User Day 2002。私にとって2つの視点で、興奮する時間となりました。それぞれ書きます。

久々のオフラインで楽しかった

 小学生の作文みたいなタイトルですが、正直な心境も、小学生のように純粋にただただ楽しい空間に身を置くことができた喜びから出た言葉です。
この2年間、一切参加することができなかった「オフライン会場」でのセミナー参加。 待ち焦がれたこの時間。 この日記を書いている時点では第七波が急激に進行中でもうオフライン開催できる状況でなく、結果としてまさにギリギリの開催タイミングとなりました。
 会場内で聞こえてくる検証状況の会話、疑問点を述べる人とそれに対して自分の知っている知識を披露する会話。各自が試した結果の情報を交換しあう会話。それらが会場のあちらこちらで同時多発で繰り広げられる空間。私自身はまだ検証もしておらず、どちらかというとアウェー気味な中にポツンと居りましたが、この空間の中に居られるだけで、言いようのない幸せを感じました。 やっぱり私はオフラインの会合が好きです。 久々の感覚に「これだよ!これ!!!!」と何度も心の中で叫んでおりました。
 2年間ほど、オンラインでこの雰囲気を作れないかと模索してきたけど、やはりオフラインにかなう空間は、ありませんね。開催ありがとうございました。

TiDB 面白いかも

 今年に入ってから「何かおもしろそうなモノだ」という嗅覚が反応したので注目していましたが、正直なところ、使いどころや特徴など、今ひとつよく分かっていませんでした。今回のイベントで、そのあたりを登壇者の皆さんから聞かせていただき、朧気ながらイメージがわいてきました。まだ出たての、これから時間をかけて検証して、その後に実戦投入していくツール、くらいに感じていたのが、各社さんともかなり検証は進んでいて実戦投入も始まっているということで、自分の情報感覚のニブさを恥じ入る次第。
 勝手に「シャーディング疲れのあなたに」というキャッチコピーを思いついたとおり、データ量が非常に多くてシャーディングなどのテクニックを駆使ししてなんとか速度低下を抑えていたものが、TiDBをうまく使えばもう少しシンプルに解決できる、と理解しました。もちろん分散DBであるが故のコツ(たとえば auto_increment は無理なので別の方法に置き換える必要があるなど)があり、その辺りのノウハウがこれから出そろってくると、(今使っている先進ユーザの次に来る)後追いユーザたちも安心して検討を始められるようになるのかなと感じました。

 お話を聞いて、とにかくこれは楽しそうだなと強烈に感じていることを自覚できたのも、今回の参加で得たものです。 一部の先進ユーザを除けば、全体としてはまだツールのクセを見抜き、ノウハウを交換しながら自社に最適な導入を目指しているフェーズですから、この楽しそうな中に身を置きたい!と、かなり本気で感じました。 導入を検討の会社様、検証チームのメンバをお探しの会社様、坂井を呼んでもいいなと思われましたら、ぜひお声がけください! 私自身も現時点では TiDBのノウハウを持つものではありませんが、一緒に検証、検討していければと思います。絶対、いま一番楽しいフェーズなので、ご一緒できましたら幸いです。

少しは具体的な内容も書く

 冒頭で述べた「2つの視点で」は書き切ったのですが、あまりに内容に関する内容がないので(笑)、少しだけ印象に残った話題を。

 まず、イベント冒頭の CTOのEdさんのお話に引き込まれました。ビデオメッセージだったので、当たり障りのない社交辞令的ご挨拶をされるだけかと思っていたら、本当に楽しそうに自分たちの歩んできた道や目指している世界などを語ってくれたのが印象的でした。司会者の説明によると、「10分枠なのに、最初は20分以上も生き生きと技術話をされて、録り直しになった」とか。 フルバージョンも聞いてみたいところです。
 あとは、「INSERTが速い」という評価をされている方がいる一方で、分散DBであるが故にすべての処理にレイテンシが乗っかる(10-20ms)ことを気にする発言もありました。今MySQLで動作しているものすべてを TiDB化するのではなく、特に低レイテンシが重要である部分はMySQLが最適であり、使い分けをしていくとのことです。
 それから、「TiDB」が何を指しているのか、あるいは、どういう環境で動作しているのかが、ようやく今回分かりました。OSSとして公開されていて、自分のサーバ群にインストールして使える「TiDB」と、AWSなどの上でマネジドで動作している「TiDB Cloud」の2本があると。 この2つの話を混ぜて理解していたので「自前でインストールできるのにマネジド???」と、ずっと混乱していました。 



 ということで、改めましてコロナギリギリのタイミングの中、オフラインを含むイベントを開催してくださり、また素晴らしい講演者のみなさまにお話をしていただく場を作っていただきありがとうございました。 イベントの運営進行、そして会場全体に亘って配慮の行き届いた、素晴らしいイベントに参加させていただけたと感じています。
そして、自分自身の力及ぶか及ばずかは分かりませんが、久々に「案件に関わってみたい」とワクワクするものに出会えた気がします。「これやってみたい!」とアツアツの人がチームに居ることは大きいと思いますので、ご興味の会社さん、ご検討中の会社さん、ぜひお引き合いをお待ちしております!

オンラインでMySQLとかの話をわいわいする「今夜も生でMySQL(仮題)」を開催しました

長らくオフラインのイベントを開催できないと、ざっくばらんにわいわいと語り合うあの雰囲気を忘れそうにもなり、また、恋しくもなります。
オンラインで、何か少しでもあの雰囲気を作ることはできないか、と悩んだ結果、こんなイベントをやってみています。

mysql.connpass.com


Discordを使って、みんなで集まる時間を決めて、あとは話題もなにも事前には決めない。 集まった人で、たまたまそのときに話題になったもので盛り上がったり盛り下がったりする、飲み会のあの雰囲気になれたらいいなぁと、先月から開催してみています。 まずは月1回ずつ、少なくとも3回は続けてみるつもりでやっていますが、意外と盛り上がらないなー、案外つまんないなーと思ったらやめてしまうかもしれません(笑)。 それくらい緩い感じで、「時間と場所だけを案内、提供する」イベントが果たして成立するのか、試みているところです。

なので「いつか参加してみようかなー」と思っている方は、「いつか」が来たときにはもうやめているかもしれませんので、ぜひ来月は覗きに来ていただけたら嬉しいです。


ここまで2回、ぽつぽつとお集まりいただき、それなりに話題は尽きずに盛り上がっているかなと思います。ただ、やっぱり幹事として話題フリをしなきゃ!とちょっと頑張っているところはあるので、どうしても私が話している時間が長くなっちゃうし、目指しているのは、幹事が離席していても気づかれないくらいに勝手に盛り上がっている場なので、まだまだ遠いなぁと頭を悩ませている次第です。


と言いながら、私自身は私が聞きたい話をいっぱい聞けて、とても楽しんでいるのですが、参加されていた皆さんそれで良かったのかなー、他の話題をしたいのに言い出しにくかったりしないかなーと、幹事として悩んだりもしています。



第2回はこんな話が展開されました。雰囲気で会話して、雰囲気で記憶しているので、ちょっと違うところもあるかもしれません。

MySQL Reference Manual 差分ウォッチによる未来先取り(8.0.30や8.0.31での変更予定を見てわいわい)
Software Design 誌へのとみたさんの「MySQLで学ぶ文字コード」を基にした話題(異字体セレクタセレクタ便利!)
・立ち上げたMySQLサーバにリモートから接続できない、とお悩みの参加者の問題解決にわいわい
MySQL関係ないけど、ニューノートPC買ったよからセットアップの話題とか


なんだか悩みだらけの日記ですが、オフラインで一緒に過ごす時間を作りにくい今の時代、情報交換の場が激減している、少し固い言葉で言うと情報流通が止まってしまっていることを憂いています。 できることを少しでも、と色々試みていますので、共感してくださる方はぜひ手伝ってください!



「生マイ」は8月もたぶんやりますので、興味もたれた方の参加をお待ちしています!
8月にはおそらく「MySQL 8.0.30のリリースノートでわいわい言う勉強会」も開催されると思います。
セミナー系イベントも全然できておらず、できることならそろそろやりたいので、スピーカー絶賛募集です。

MySQLのLIMIT句の入れ子による面白い挙動と将来リリースでの修正予定

とみたさんから、MySQLの次の次のバージョンで挙動が変更になる話を教えてもらったので、記録。

mysql> use mysql
mysql> SELECT user FROM user LIMIT 2;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
+------------------+
2 rows in set (0.00 sec)

 適当なテーブルから LIMIT句を使って2件のデータを取得したもの。これはまぁ普通の挙動。
次に、これを入れ子にしてみる。

mysql> (SELECT user FROM user LIMIT 2) LIMIT 3;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
+------------------+
3 rows in set (0.00 sec)

 こんな記述方法があるのか、という驚きはとりあえず横に置いておいて、いったん内側で 2件に絞ったものを、さらに3件に絞ろうとする、という指示に対して、内側の指示が無視されて3件返ってくる動作。
 この動作がMySQL 8.0.31 で変更される(ちゃんと(?) 2件のみが返ってくるようになる)というのが、リリースノート差分ウォッチャーとしての ご情報でした。

 ちなみに、私が「普通の書き方」だと考える、サブクエリを明示した記述方法なら、入れ子にしても2件のみが「正しく」返ってくる。

mysql> SELECT * FROM (SELECT user FROM user LIMIT 2) t LIMIT 3;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
+------------------+
2 rows in set (0.00 sec)


 以下は、お遊び。

もっと入れ子にしてみたり、

mysql> ((SELECT user FROM user LIMIT 2) LIMIT 3) LIMIT 4;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
| root             |
+------------------+
4 rows in set (0.00 sec)


内側にORDER BY をつけても変わらないことを確認したり、

mysql> (SELECT user FROM user ORDER BY user LIMIT 2) LIMIT 3;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
+------------------+
3 rows in set (0.00 sec)


内側と外側に ORDER BY をつけると、2件のみになることを確認したり、

mysql> (SELECT user FROM user ORDER BY user LIMIT 2) ORDER BY user DESC LIMIT 3;
+------------------+
| user             |
+------------------+
| mysql.session    |
| mysql.infoschema |
+------------------+
2 rows in set (0.00 sec)

いやそもそも、ORDER BY は外側だけでも2件になってくれることを確認したり、

mysql> (SELECT user FROM user LIMIT 2) ORDER BY user DESC LIMIT 3;
+------------------+
| user             |
+------------------+
| mysql.session    |
| mysql.infoschema |
+------------------+
2 rows in set (0.00 sec)


入れ子は少なくとも20個程度はちょろいもんらしい、ということを確認したり、

mysql> ((((((((((((((((((SELECT priv FROM global_grants LIMIT 2) LIMIT 3) LIMIT 4) LIMIT 5) LIMIT 6) LIMIT 7) LIMIT 8) LIMIT 9) LIMIT 10) LIMIT 11) LIMIT 12) LIMIT 13) LIMIT 14) LIMIT 15) LIMIT 16) LIMIT 17) LIMIT 18) LIMIT 19) LIMIT 20;
+----------------------------+
| priv                       |
+----------------------------+
| SYSTEM_USER                |
| AUDIT_ADMIN                |
| BACKUP_ADMIN               |
| BINLOG_ENCRYPTION_ADMIN    |
| CLONE_ADMIN                |
| CONNECTION_ADMIN           |
| INNODB_REDO_LOG_ENABLE     |
| PERSIST_RO_VARIABLES_ADMIN |
| REPLICATION_APPLIER        |
| SERVICE_CONNECTION_ADMIN   |
| SESSION_VARIABLES_ADMIN    |
| SYSTEM_USER                |
| SYSTEM_VARIABLES_ADMIN     |
| SYSTEM_USER                |
| APPLICATION_PASSWORD_ADMIN |
| AUDIT_ADMIN                |
| BACKUP_ADMIN               |
| BINLOG_ADMIN               |
| BINLOG_ENCRYPTION_ADMIN    |
| CLONE_ADMIN                |
+----------------------------+
20 rows in set (0.00 sec)

いろいろと遊びましたとさ。
MySQL 8.0.31 (順当にいけば 2022年10月リリース)でこれらがどう変化するのか、リリースされたら試してみたいと思います(覚えていたら)。

MySQLリリースノート勉強会8.0.28開催しました

MySQL リリースノートでわいわい言う勉強会 8.0.28 を開催しました。
今年は、今までの常識に囚われずに色々試していこうということで、平日18時からの開催という変則的なトライアルでしたが、たくさんの人に参加していただき、ありがとうございました。主に喋っていたのは6人くらいだったでしょうか。たくさんの事を教えていただき、とても勉強になりました。

mysql.connpass.com


 今回は、何はなくともコレを世間に広く知らしめるべし、と感じたので、最初に貼っておきます。@yyamasaki1 さんがプレゼン資料の中で紹介してくれていた1ページです。要約すると、「MySQL配布ファイルの署名用GPGキーの有効期限が切れて、リポジトリからのアップデートに失敗します。最新に更新してね」というものです。

f:id:sakaik:20220223005833p:plain
MySQL8.0.28以降へのリポジトリからのアップデートでエラーが発生したら?

※資料配付元:公開資料・出展レポート - オープンソースカンファレンス2022 Osaka

今回の主なテーマ

 今回は、幹事がピックアップしたテーマを中心に進めました。あまりリリースノートの一言一句を読むという感じではなく。 リリースから1ヶ月以上も経過していることもあってか、各テーマに対してそれぞれの知っていることや体験などを聞かせていただきました。私が用意したテーマは、こんな感じ。
f:id:sakaik:20220223010610p:plain

主な話題(私が興味を持ったもの)

 今回は、会の中で教えてもらったり後で試してみたりしたことなどをTwitterに書いたので、ツイートを貼っておきます。



MySQL2021~地理情報(spatial)機能の進化

この記事は、『RDBMS-GIS(MySQL,PostgreSQLなど) Advent Calendar 2021』の1日目のエントリーです。


2021年のMySQLは、以下の5つのバージョンがリリースされました。

MySQL 8.0.23 (2021/01 リリース)
MySQL 8.0.24 (2021/04 リリース)
MySQL 8.0.25 (2021/05 リリース)
MySQL 8.0.26 (2021/07 リリース)
MySQL 8.0.27 (2021/10 リリース)

全体として、地理情報機能(spatial/GIS)の観点からは、どちらかというと地味な進化の一年だったという印象でした。各バージョンでの進化を以下にまとめます。


MySQL 8.0.23 (2021/01 リリース)

ST_HausdorffDistance() 関数と、ST_FrechetDistance() 関数が追加されました。
それぞれ、ハウスドルフ距離とフレシェ距離を求める関数なのですが、正直なところ私も使い所がよくわかっていません。わからないなりに調べながら、とりあえず挙動を紹介してみたのが、本ブログの以下の記事になります。

https://sakaik.hateblo.jp/entry/20210227/try_mysql_frechetdistance_and_haussdorffdistance

MySQL 8.0.24 (2021/04 リリース)

 GIS的には、今年最大の進化となったバージョンです。4つの関数の追加と、既存関数のGISへの拡張が行われました。

 追加されたのは以下の4つの関数。

ST_LineInterpolatePoint()
ST_LineInterpolatePoints()
ST_PointAtDistance()
ST_Collect()

最初の3つは、指定した条件に従ってLINESTRING上の経過点を返す関数です。本ブログでは以下の記事で紹介しました。
https://sakaik.hateblo.jp/entry/20210501/mysql_spatial_new_functions_8024_1

ST_Collect() は、POINTなどの単一型を、MULTIPOINTなどのマルチ型へとまとめる集約関数です。以下の記事で紹介しました。
https://sakaik.hateblo.jp/entry/20210512/mysql_spatial_new_functions_8024_3_ST_Collect


 さらに、MySQL 8.0.24では、CAST()、CONVERT()の2つの既存関数が、Spatial(GIS)型も扱えるよう拡張されました。この拡張により、POINT/LINESTRING/POLYGON および各マルチ型の各型どうしで変換できるパターンが格段に拡がりました。
 詳しくは、本ブログの以下の記事を参照ください。
https://sakaik.hateblo.jp/entry/20210515/mysql_spatial_new_functions_8024_4_CAST_Function

リリースに先立って、リファレンスマニュアルに機能変更の記述が加えられたことを受けての「超先出し(期待記事)」は以下のリンクとなります。
https://sakaik.hateblo.jp/entry/20210123/mysql_spatial_cast_function_in_8_0_24


MySQL 8.0.25 (2021/05 リリース)

 MySQL 8.0.24 に問題があったとのことで、緊急リリースです。GIS関連機能の変化はありません。


MySQL 8.0.26 (2021/07 リリース)

 いままで平面座標系のみを扱うことができた ST_Buffer()、ST_Difference()、ST_Union() の各関数が、多くのSRSに対応しました。平たく言うと「丸い地球」に対応しました(平たく言ったつもりなのに丸くなっちゃった)。
 あと、内部で使っていた関数が開放後のメモリを参照しちゃってた問題が、このバージョンで直されたっぽい。

MySQL 8.0.27 (2021/10 リリース)

 いままで平面座標系のみを扱うことができた ST_SymDifference()、ST_Intersection()の両関数が、他のSRSにも対応しました。平たく言..(略)



まとめ

 以上見てきたように、2021年のMySQL spatial(GIS)は、いくつかの関数追加と、いくつかの関数がSRS対応した、という進化でした。PostGIS並の関数充実に到達するために、もっと派手に関数が追加される1年になると予想していたので、ちょっと拍子抜けしたというのが正直な感想です。
 とは言え、放置されているわけではなく着実に進化はしているので、2022年も引き続きMySQLのspatial機能の変化を楽しみに、注目していきたいと思います。関係ないけど、2022年ってなんか文字集合っぽくて格好良いですね。

f:id:sakaik:20211130225559p:plain:w1