Athenaで元データのカラム数とテーブル定義が一致しない時どのような挙動になるか
概要
ある日のデータからカラムが追加されることになった。
その時、Athenaではどのようなデータが表示されることになるのだろうか
テスト準備
price | name |
---|---|
int | string |
- 上記カラムのファイルの末尾に、country(string)のカラムを追加したcsvファイルを作成
- S3
hr1 | hr2 |
---|---|
price, name | price, name, country |
- Athena
- カラム追加前後、それぞれのテーブルを作成する
Load partitions
を実行して、Athenaにパーティションを認識させる
テスト内容と結果
テーブル毎にSELECTするカラムと読み取るパーティション、その実行結果を出すと下記の通り
- 追加前のカラムが定義されているテーブル(price, name)
SELECTするカラム / 読み取るパーティション | hr1(price,name) | hr2(price,name,country) | hr1 と hr2 両方 |
---|---|---|---|
price, name | price,nameの値が取得可能 | price,nameの値が取得できる | price,nameの値が取得できる |
price, name, country | countryが定義されていないのでエラー | countryが定義されていないのでエラー | countryが定義されていないのでエラー |
- 追加後のカラムが定義されているテーブル(price, name, country)
SELECTするカラム / 読み取るパーティション | hr1(price,name) | hr2(price,name,country) | hr1 と hr2 両方 |
---|---|---|---|
price, name | price,nameの値が取得可能 | price,nameの値が取得できる | price,nameの値が取得できる |
price, name, country | price, nameの値を取得 countryは空白で出力 |
price, nameの値を取得 | price, nameの値を取得 データにcountryがあれば取得、なければ空白 |
まとめ
- ある時点から元データのカラムは増やしてよい
- それに合わせてAthenaのテーブルカラムも増やしてよい
- 元データに存在しないカラムをSELECTしても、空白で出力されるだけでエラーにならない
- 空白があってもそのカラムに対してSUM()等の関数は実行できる
AWS 認定ソリューションアーキテクトに合格するまで
AWS認定ソリューションアーキテクト – アソシエイト (2018 年 2 月リリース)を取った。 どんなことやったかとかを書いておく。
前提レベル
- エンジニア歴1年半
- 普段ちょこちょこAWSサービスに触るものの自分で環境構築することはほぼない
- 使ってたりちょこっとでも設定したことあるのは大体こんな感じだった。
- VPC、 EC2、 S3、 CloudFront、 ELB、 Route 53、 RDS(Aurora)、 SQS、 DynamoDB、 Athena、 Elastic Cache
- いろいろ使ってはいたけど詳細は把握していなかったし、EFS、Glacier、Auto Scaling、 Lambda なんかは名前は知っているかなーくらいの素人に毛が生えたレベル。
やったこと
- 本は下2冊を時には手を動かしながら読み進める。特に上の本は必読と言っていい。
- 合格対策 AWS認定ソリューションアーキテクト - アソシエイト
- ちょっと古い本なので、最新情報が抜けていたりするけど基本的なことは変わっていないので十二分に役立つ
- 2週くらい
- Amazon Web Services 業務システム設計・移行ガイド
- オンプレからクラウドへの移行という趣旨ではあるけど、実際に手を動かしてやってみるような部分も多く、役に立った。
- 関係ない部分も多いので取捨選択が必要。特にアカウント管理、オンプレとの連携部分は流し読みでよい。
- 合格対策 AWS認定ソリューションアーキテクト - アソシエイト
- AWS クラウドサービス活用資料集を読む
- 実際にAWSでいろいろやってみる
- VPC
- プライベートサブネットのルートテーブルのデフォルトゲートウェイにNATゲートウェイを指定してみるとか(これ頻出!!)
- ユーザーデータ入れてEC2立ち上げてみる
- Auto Scaling は特に使ってみた方がいいかな。
- VPC
- 模試
- 2000円かかってしまうが、問題の感じを掴むのに受けておいた方がよい。
試験本番
- 困った時の選択肢はこれ!!
受けて思ったこと
MySQLのEXPAINの見方
EXPLAINとは
- クエリオプティマイザがクエリをどのように実行するのかを解明する手段
- どのインデックス使ってるのかなーとか確認する
- 実際に実行するとこんな感じになる
mysql> EXPLAIN SELECT * FROM covering_test WHERE key1 = 1; +----+-------------+---------------+------------+------+---------------+------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------+------------+------+---------------+------+---------+-------+------+----------+-------+ | 1 | SIMPLE | covering_test | NULL | ref | key1 | key1 | 4 | const | 2 | 100.00 | NULL | +----+-------------+---------------+------------+------+---------------+------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.01 sec)
EXPLAINをどう使うの?
- 下記2点を達成できるようEXPLAINを読み解いていこう
- 書き換える前と後でクエリの実行結果が同じになる
- EXPLAINがよりよい実行計画を表示する
各カラムについて
特に重要なのはtype
カラム
id
- 各SELECT文を識別するための通し番号で実行順序
select_type
クエリの種類を表す
- SIMPLE
- クエリにサブクエリやユニオンが含まれていない
- クエリがSIMPLEってわけではない!
- 上の例の通り
- クエリにサブクエリやユニオンが含まれていない
- SUBQUERY
- SELECTリストのサブクエリに含まれている(FROM句ではない)SELECT文
- DERIVED
- PRIMARY, UNION, UNION_RESULT
- PRIMARY - UNIONの1つ目のSELECT文であることを示す
- UNION - UNIONの2つ目以降のSELECT文であることを示す
- UNION_RESULT - UNIONの無名の一時テーブルから結果を取得するためのSELECT文であることを示す
table
partitions
- 使われているpartitionを示す
- 使われていない場合はNULL
type
MySQLがテーブル内の行を検索する方法
- ALL
- テーブルスキャンと呼ばれるもの
- インデックスが全く使われず、テーブルを最初から最後までスキャンしなければならない
- これが出た場合、改善が必要と思われる
- index
- range
- インデックスを利用した範囲検索
- WHERE句にBETWEENまたは不等号が来ている場合
- ref
- ユニーク(PRIMARYまたはUNIQUE)でないインデックスを使った等価検索(WHERE key = value)
- eq_ref, const
- PRIARY KEYまたはUNIQUE KEY(単一行であることが分かっている)が使われている
- eq_refはJOINのとき、constはそれ以外の時という違いがある
possible_keys
- 利用可能なインデックスの候補
key
- 実際に利用されたキー
key_len
- 選択されたキーの長さ
- intだったら4バイトとか
- 複合インデックスを使った場合には2つのキーの長さの合算値
- 短い方が高速
ref
- キーと比較されている値やカラムの種類
- 定数の場合には
const
- joinの場合には、結合する相手側のテーブルで検索条件として利用されているカラム
- 定数の場合には
rows
- フェッチされる行数の見積もり。あくまで見積もりなので正確な行数ではない
- ただし、サブクエリ(DERIVED)の場合は、実際に実行しないと以降の見積もりができないので正確な値が出される
- フェッチ行が全て結果行として返却されるわけではない。
- フェッチされた行からWHERE句などで絞り込みが行われる場合もある
- JOINする場合は、各クエリのrowsの値の積がフェッチされる行の見積もりになる
filtered
- テーブル条件によってフィルタ処理されるテーブル行の推定の割合
- typeがRANGE, index, rage, index_mergeの時、利用されるようだがよく分かっていない
Extra
上記カラム以外の情報が出力される
その他っぽいけどとても大事
- Using index
- カバリングインデックスが使用されているので、テーブルアクセスが発生していない
- Using where
- テーブルから行をフェッチした後に絞り込みが行われている
- フェッチ時点で行数制限したいので、WHERE句でインデックスを適切に利用する等何らかの改良の余地があると思われる
- Using temporary
- GROUP BY や ORDER BY でソートするために一時テーブルを使用することを意味する
- Using filesort
- インデックスでのソートではなく、ソートアルゴリズムが使われている
- Range checked for each record (index map: N)
- JOINにおいてrangeまたはindex_mergeが利用される
参考
アルゴリズムの計算量について
1年ちょい前に基本的なソートと探索は研修で実装したんだけど(written in Perl)
その頃はなんだか分からないまま実装してた感あったので計算量もちゃんと意識やってみる
それにあたって計算量の基本の確認
計算量の評価
計算量の評価は時間計算量
と領域計算量
の2つから成る
- 時間計算量
- プログラムの実行に必要な時間の評価
- CPUをどれだけ使うか
- プログラムの実行に必要な時間の評価
- 領域計算量
- プログラムの実行に必要な記憶領域の評価
- メモリをどれだけ使うか
- プログラムの実行に必要な記憶領域の評価
時間計算量が問題になることが多いので、計算量といわれるとき大抵は時間計算量
O表記法
- オーダ表記法
O(n)
やO(n²)
のように表記する- nを入力値とし、nを用いた()内の式に計算量が比例することを表す
- 例1) O(n)の場合
- 入力値nが5倍になれば計算量も5倍になる
- 例2) O(n²)の場合
- 入力値nが5倍になれば計算量は(5²=)25倍になる
- 例1) O(n)の場合
参考
- プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
- 特集!知らないと損をする計算量の話 は、アルゴリズムとデータ構造を学ぶモチベーションを高めてくれた
VPCのメインルートテーブルに関してすごい勘違いをしていた
背景
AWSソリューションアーキテクトの勉強も兼ねてVPCの勉強をしていて、どーしても分からないなぁとなっていた。
VPC自体にルートテーブルを設定して何に使うんだ?と。
サブネットに設定されてあるルートテーブルでええやん?と。
結論
- VPCに設定したルートテーブルは
メインルートテーブル
と呼ばれ、ルートテーブルに明示的に関連付けられていない全てのサブネットの全てのルーティングを制御する。- つまり、VPCに設定されているわけではない!!
備考
上記の通り、明示的に設定していない場合、サブネットのルートテーブルはメインルートテーブルになるのです。
この状態でVPCのメインルートテーブルを変更してしまうと、明示的にルートテーブルが設定されていないサブネットのルートテーブルも変わってしまう!
パブリックサブネットがプライベートサブネットに、またはその逆が起こってしまう可能性があるのだ。
参考
DNSとDNSレコードについて
AWSについて勉強していて、Route 53に差し掛かったところでそもそもDNSよく分かってないや、ってなったので簡単なまとめ。
Route 53独自のレコードについても触れる。
そもそもDNSサーバ
DNSレコードとは
主なDNSレコード
タイプ | 略 | 概要 |
---|---|---|
A | Address | IPv4 IPアドレス。 |
AAAA | ? | IPv6 IPアドレス |
CNAME | Canonical NAME | ドメイン名の別名。 |
NS | Name Server | ドメインの管理の委譲先の権威DNSサーバのドメイン名 |
MX | Mail Exchange | ドメインへのメール配送先サーバのドメイン。 |
TXT | TeXT | コメント行。Sender Policy Frameworkにも使える |
PTR | PoinTeR | IPアドレスに対応するドメイン名。 |
SOA | Start Of Authority | プライマリネームサーバ、ドメイン管理者の電子メール、ドメインのシリアル番号(更新されたかどうかの判別に使う)、ゾーンのリフレッシュなど |
- 上記のDNSレコード以外に、Route 53には独自のDNSレコード
ALIAS
がある
参考
バイト列を受け取ったブラウザがDOMツリーをつくるまで
概要
ブラウザがページをレンダリングするまでにはいくつかのステップを経ている。
googleのConstructing the Object Modelを読んで、分からなかった単語などを調べながらまとめる。
CSSDOMのところは除いてとりあえずDOMツリー
が作られるところまで。
バイト文字列からDOMオブジェクトになるまでの流れ
ブラウザーに渡されたバイト列
は、下のような流れでDOMツリー
になってレンダリングされる。
英語が苦手な人もgoogleのページの図を見てもらえると分かりやすいかと。
バイト列 ↓ 文字列 ↓ トークン ↓ オブジェクト ↓ DOMツリー
バイト文字列から文字列へ - Conversion
ブラウザーは、サーバーやディスクから読み込んだバイト列を、決まった文字コードに応じて文字列に変換する。
例えば、htmlファイルのheadに<meta charset="utf-8">
があれば、バイト列をUTF-8として処理する。
文字列からトークンへ - Tokenizing
ブラウザーは文字列を<html>
や<body>
などカギカッコ(angle brackets)に囲まれたトークン1に変換する。
それぞれのトークンはそれぞれの特性を持っている。
トークンからノードへ - Lexing
トークンがオブジェクト(ノード)へと変換される。
Tokenizeで、headやbodyなどの各タグは始まりのタグと終わりのタグで別個になっていたが、
この段階でひとまとまりのオブジェクトへと変換される。
- Lex - レキシカルアナライザ(字句解析プログラム)を生成するプログラム
オブジェクトからDOMツリーへ
HTMLでは各タグ同士の包含関係などの関係性が書かれているので、オブジェクトは木構造へと結びつけられる。 htmlタグがparent、head、bodyがchildといった形。 リンク先の図が分かりやすい。