nelmoの日記帳

エンジニア見習いの備忘録とかです。

MySQLテーブルのデータ件数はinformation_schema.tablesから取得できる

前提

やりたいこと

MySQL上のテーブルに COUNT(*) することなく、テーブルの行数を知りたい。

解決法

information_schema.tables テーブルから、テーブルの名前やデータ件数などのメタデータが取得可能。

mysql> desc information_schema.tables;
+-----------------+---------------------+------+-----+---------+-------+
| Field           | Type                | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+-------+
| TABLE_CATALOG   | varchar(512)        | NO   |     |         |       |
| TABLE_SCHEMA    | varchar(64)         | NO   |     |         |       |
| TABLE_NAME      | varchar(64)         | NO   |     |         |       |
| TABLE_TYPE      | varchar(64)         | NO   |     |         |       |
| ENGINE          | varchar(64)         | YES  |     | NULL    |       |
| VERSION         | bigint(21) unsigned | YES  |     | NULL    |       |
| ROW_FORMAT      | varchar(10)         | YES  |     | NULL    |       |
| TABLE_ROWS      | bigint(21) unsigned | YES  |     | NULL    |       |
| AVG_ROW_LENGTH  | bigint(21) unsigned | YES  |     | NULL    |       |
| DATA_LENGTH     | bigint(21) unsigned | YES  |     | NULL    |       |
| MAX_DATA_LENGTH | bigint(21) unsigned | YES  |     | NULL    |       |
| INDEX_LENGTH    | bigint(21) unsigned | YES  |     | NULL    |       |
| DATA_FREE       | bigint(21) unsigned | YES  |     | NULL    |       |
| AUTO_INCREMENT  | bigint(21) unsigned | YES  |     | NULL    |       |
| CREATE_TIME     | datetime            | YES  |     | NULL    |       |
| UPDATE_TIME     | datetime            | YES  |     | NULL    |       |
| CHECK_TIME      | datetime            | YES  |     | NULL    |       |
| TABLE_COLLATION | varchar(32)         | YES  |     | NULL    |       |
| CHECKSUM        | bigint(21) unsigned | YES  |     | NULL    |       |
| CREATE_OPTIONS  | varchar(255)        | YES  |     | NULL    |       |
| TABLE_COMMENT   | varchar(2048)       | NO   |     |         |       |
+-----------------+---------------------+------+-----+---------+-------+
21 rows in set (0.00 sec)

mysql> select * from tables where table_schema = 'information_schema' and table_name = 'tables';
+---------------+--------------------+------------+-------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+
| TABLE_CATALOG | TABLE_SCHEMA       | TABLE_NAME | TABLE_TYPE  | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME         | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT |
+---------------+--------------------+------------+-------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+
| def           | information_schema | TABLES     | SYSTEM VIEW | MEMORY |      10 | Fixed      |       NULL |           9441 |           0 |        16757775 |            0 |         0 |           NULL | 2017-07-09 23:15:45 | NULL        | NULL       | utf8_general_ci |     NULL | max_rows=1777  |               |
+---------------+--------------------+------------+-------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+
1 row in set (0.01 sec)

table_row カラムにデータ件数が格納されている。このテーブルを利用すれば、任意のテーブルの行数を COUNT(*) することなく取得が可能。

mysql> select * from tables where table_schema = 'foo_db' and table_name = 'bar_table';
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME         | UPDATE_TIME         | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------------+
| def           | foo_db        | bar_table   | BASE TABLE | InnoDB |      10 | Dynamic    |      19303 |           1336 |    25804800 |               0 |      4767744 |   4194304 |           NULL | 2017-06-23 00:25:12 | 2017-07-03 11:36:54 | NULL       | utf8mb4_bin     |     NULL |                |               |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------------+
1 row in set (0.00 sec)

このテーブルを利用することで、 データ件数が一定数以上のテーブルを抽出する みたいなこともできる。ただし、このテーブルには mysql スキーマinformation_schema スキーマなどの管理データやメタデータスキーマも含まれるのでそれを必ず除外する必要がある。対象のスキーマを条件に入れて検索すること。

SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema in ('foo_db', 'bar_db')
AND table_rows > 1000;

information_schema 以下には他にも面白そうなテーブルがたくさんあるのでもうちょっと深く掘りたい。

(2017/07/11 13:13 追記)コメント欄で id:n-3104さんから指摘頂きましたが、 table_rows で取得できる行数は概算の値で、その瞬間での正確な値ではありません。概算量が取得できれば問題ないような要件であれば活用できますが、正確な量が知りたい場合は各TABLEに COUNT(*) をかける必要があります。 また、 ANALYZE TABLE を実行することで、テーブル単位での同期をかけることが可能です。

(追記ここまで)

参考

私は何に対してお金をもらっているのか、という話

受託システム開発においては、「人月」という単位でお金の計算をされることが(少なくとも私の観測範囲下では)多いと思う つまり、「人」がどれだけ動くかに対しての報酬を要求するというもの。 このスキームのもとで動く人は、つまり「時間」からお給料をいただいている。

一方、「人」ではなく、「人がつくりだす価値」に対してお金をもらうケースもある。 何かしらのサービスプロバイダはその分類に入るだろう。 そのスキームのもとでは、動いた時間とは無関係に、人ないし組織が提供する「価値」に対して報酬が与えられる。

時間は有限である。だから、時間に対してもらえるお金も有限である。 だが、自分が作り出すことができる価値は有限ではない(と、信じている)。 であれば、その価値を生み出すことにフォーカスしていくのが自然な流れかなと思った。

とはいえ自分が時間ではなく価値を提供できているのか、わからない。

でもこの先の人生において、時間を自分の売り物にしていくには時間が足りなさすぎる、というのがここ数ヶ月の感想。 だからこそ自分は、時間ではなく価値を売り物にする人間になりたい。

自分は何に対してお金をもらっているんだろうか。 ということに一度向き合ったほうがいいな、と思いました、まる

Array#newする時の初期値は同一オブジェクトになる

本日のRubyに関する学び。

[32] pry(main)> arr = Array.new(3, Array.new(4,0))
[
    [0] [
        [0] 0,
        [1] 0,
        [2] 0,
        [3] 0
    ],
    [1] [
        [0] 0,
        [1] 0,
        [2] 0,
        [3] 0
    ],
    [2] [
        [0] 0,
        [1] 0,
        [2] 0,
        [3] 0
    ]
]
[33] pry(main)> arr[0][0] = 1
1
[34] pry(main)> arr
[
    [0] [
        [0] 1, #<= ここが1になるが、
        [1] 0,
        [2] 0,
        [3] 0
    ],
    [1] [
        [0] 1, #<= ここと
        [1] 0,
        [2] 0,
        [3] 0
    ],
    [2] [
        [0] 1, #<= ここも1になる。
        [1] 0,
        [2] 0,
        [3] 0
    ]
]

Array.newする時に第二引数で配列の要素を埋める初期値を指定することができるが、ここで指定したobjectは全て同一のオブジェクトになる。今回の例では、Array.newされた単一のArrayが3つの要素に埋められる。そのため、一つの要素を変更するとその他の要素にも変更が及んでしまう。

[35] pry(main)> arr[0].object_id
70212079356840
[36] pry(main)> arr[1].object_id
70212079356840
[37] pry(main)> arr[0].object_id.eql?(arr[1].object_id)
true

訳あって多次元配列を作っていたらハマったので。

Array#mapで多次元配列を扱う時、複数個のブロック引数で値をとれる

本日のRubyに関する学び。

a = [1,2,3]

a.map do |element|
  element.class #=> Fixnum,Fixnum,Fixnum
end

a.map do |first,second|
  second #=> nil,nil,nil
end
  
b = [[1,2],[3,4],[5,6]]

b.map do |element|
  element.class #=> Array
end

b.map do |first,second|
  second #=> 2,4,6
end

ドキュメントにも可変長引数に関する言及が無かったので最初よく分からなかったが、How does Array.map work for 2D arrays? - Ruby Forumを読んでいたら仕組みについては少し腹落ちした感じがある。

とはいえまだ人に説明できるほど理解できたわけではないので後日もう一回読む。

AWS re:Invent 2014感想文

11/10〜11/16の期間、ラスベガスで開催されたAWSの大規模カンファレンス「AWS re:Invent 2014」に参加してきた。1万人以上が参加する超大規模なカンファレンスに、会社を代表する形で4名で参加させてもらった。 セッションやKeynoteの内容については会社のブログで腐るほど書いたので*1、もっと個人的な感想とかをメモっておく。

セッション全体

昨年のre:InventではKinesisとかWorkspacesとか、それまでのAWSの領域とは少し毛色の違うサービスが追加されたけれど、今年の新サービスはどれも、「ああ、それ欲しかったよね」とか「なるほど。。」と唸る機能が多かった印象。Keynoteと新機能紹介のセッションを聞いた感じ、KMSは既にPublicになっているし、機能としてもかなりイケてるんじゃないかと思った。ただセキュリティ系はあまり詳しくないので実際に使ってみないとなんとも言えない。これから試してみる。

通常セッションではNetflixとかDropboxみたいにコアに使い倒している企業の使い方を聞けたのが素晴らしかった。自分で参加したり、資料を読んだりした中で特に素晴らしいと感じたのは以下のセッション。これからも見つけ次第追加していく。

その他

英語に関して

セッションの内容とか展示ブースでの会話は7〜8割聞き取れて、ブースで説明されたプロダクトに関しての質問とかもそれなりにできるんだけど、店の店員とか他人に声をかけられた時に反応できなくて困った。英語は大丈夫だろうとかなり高を括って参加していたので結構ショックではある。レアジョブやろうかな、と本気で思案中。

アメリカに関して

ラスベガスのホテルという、なんというか非日常な領域に滞在していたので、あまりアメリカでの生活に触れられた感じはしていないけど、アメリカの文化の一端には触れることが出来たかな、という感じ。イギリスに滞在していたときの間隔と比較すると、やはりアメリカはイギリスよりは文化的に日本に近い印象を受けた。当然本気で現地で生活するor仕事する、となると全く別次元の話になることは認識しているけど。次はもう少し一般の生活に触れられるところに行きたい。できれば仕事で。

re:Inventというイベントに関して

とにかく何から何まで規模が違いすぎて焦った。Keynote会場の集客と熱気、各セッションの内容の濃さ、re:Playの桁外れのパーティー感、などなど。本当に参加できてよかったと思う。自分自身の価値観に影響を与えられた気がする。

まとめ

  • 英語はがんばる
  • 新機能は使い倒す
  • 来年も行きたい
  • 今年行っていない人は来年行くといいと思います
  • 眠い

*1:まだ書いてるよ!

「アンダースタンディングコンピュテーション」読書録 - 第1部

アンダースタンディングコンピュテーションを読み始めた。 2週間かけてようやく第1部を読了、手を動かせたので記録。

なぜ読んでるのか

もともと文系卒で計算機科学というものを学んだことがなく、エンジニアとして仕事をする上でそれに対して負い目というか劣等感を抱いているのは事実。 何か手近に始められる教材はないかと思っていたところ、この本の存在を知った。購入に至った理由は2つあり、1つは普段から触れているRubyでサンプルコードが記載されていること。もう一つは普段から聞いているrebuild.fm で触れられていたこと。

感想

「プログラムと機械」という第1部の題名通り、プログラムがどのように記述を解釈し、計算しているのかということをRubyソースコードをベースに進めていった。オートマトンチューリングマシンというものは名前は聞いたことある、程度の理解だったけれど実際にどういった概念のものなのか、というのをirbで自分で動かしながら勉強できた点が非常によかった。

3章から5章では単純なオートマトンから状態を持ったプッシュダウン・オートマトン、永続的なストレージを持ったチューリングマシンに至る説明は非常に分かりやすく、ほとんど詰まることなく読み進められた。入出力を実行するだけの本当に単純な機械から、普段利用しているような「高度な」機械に至るまでにどういった機能を持つことが必要かをざっくりと眺めることがたのではないかと思う。

正規表現オートマトンの概念を利用していることなど、普段から使っている技術が計算機上ではどのように扱われているのか、という点に触れていたところも、身近な話題に落としこんで考えることができた。

まとめ

こういう計算理論の本とかはLispとかが多い印象で、Rubyで書かれている本は結構珍しいらしい。

普段自分がRubyをそれなりに使っていることもあり素直に読み進めることができたけど、そうじゃなかったら少し読むのに苦戦していたとは思う。*1 この分野における事前知識がない状態で読むにはあらかじめRubyに触っていたほうがよいのは確かだと思う。文系卒でも3〜4年目くらいの人なら読み進められそうな難易度の本だと思った。

オートマトンとかチューリングマシンWikipediaを見ると感じるのは、この本で触れられているトピックはどれも本来は複雑な数式とともに説明されるべき理論なのだろうという点。そんな中で数式を一切排除して身近なコードで表現されているのは本当にとっつきやすいので、興味をもった方は是非読んでみるといいと思います。

まだ第2部「計算と計算可能性」が残っているので、その感想はまた後日。

*1:Pythonとかだったらそもそも興味持てなかっただろうし

「エンジニアのためのデータ可視化[実践]入門」を読んだ

業務ではまだ触れていないけれど、少しづつ増えてきそうなので勉強を始めている。

エンジニアのための データ可視化[実践]入門 ~D3.jsによるWebの可視化 (Software Design plus)

エンジニアのための データ可視化[実践]入門 ~D3.jsによるWebの可視化 (Software Design plus)

以下、読書メモ。

感想

副題に「D3.jsによるWebの可視化」とあるけれどD3.jsはあまり本題ではなく、データ分析の目的とその目的を達成するためのアプローチ、そこから得られた結果をいかに理解しやすく伝えるかに主眼の置かれた本だと感じた。

特に勉強になったのは4章「何を可視化すべきか」と6章「探索的データ解析入門」。

4章ではKGI(Key Goal Indicator)とKPI(Key Performance Indicator)の設計について、Webサービスに典型的な例を基にした解説。 KPIの乱立はやりがちだと思うけれど、そういう時はKGIとの関連性を考えて必要な物に絞り込んで利用しないと効果が減ってしまう。「なぜそれをKPIに設定するのか」というのをKGIと照らしあわせて考えることが重要。 KPIの設計・データの利用方針についても勉強になった。実際に利用する時に読み返す章になると思う。 また、「仮説検証的なアプローチ」と「探索的なアプローチ」という2つを区別してデータ分析にとりかかるのは非常に重要。

  • 仮説検証的なアプローチ : 設定した仮説が正しいかどうかをデータを基に裏付けをとるための可視化
  • 探索的なアプローチ : データを様々な切り口から可視化することで問題を発見したり仮説設定の切り口とする

自分でも混同しないように気をつけないといけない。

6章では、上に述べた「探索的なアプローチ」を実施する際の概念と手法の解説が記載されていた。データを可視化した時に、中央値・分散・平均等のどこを中止するべきなのか、可視化する時にどういった図が有効なのかを学べた。

D3.jsは、、、はい、JS勉強します。でもブラウザ上でSVGを操作して可視化できるというのはかなりイノベーティブなことだと思うし、利用できる状況はかなり多そう。

JSはすぐにカオスなコードになってしまうので一度AltJSをしっかり勉強しなきゃと思いつつ手が付けられていない状況。CoffeeScriptとかTypeScriptとかあるけど、今から勉強するならどれがいいんですかね。

まとめ

いい本だと思いました(小学生並みの感想)。