ねぎ嫌い

始業前に学んだことを小出しに。最近はHacker Newsの人気記事をまとめてみたり。

2017-10-16 Why PostgreSQL is better than MySQL

原文:Why PostgreSQL is better than MySQL |

PostgreSQLMySQLよりも優れているお話。

どんな製品にもバグはつきものである。
PostgreSQLのコミュニティでは、発見されたバグは直ぐに修正されるだろう。
PostgreSQLのコミュニティでは常にバグをトラッキングするかは大きな議論になるからだ。

しかし、MySQL#199にあるような単純なバグが14年間も直されずに放置されてきた。
これが明確に優れている理由である。

2017-10-16 Efficient pagination of a SQL table with 100M records

原文:allyouneedisbackend.com

巨大なデータを持つテーブルを効率的に読み込む方法についてのお話。

1億行のレコードを持つテーブルからデータを読み込む時、どのように読むべきか。

1. 明らかに間違った解決策

SELECT user_id, external_id, name, metadata, date_created FROM users;

シンプルに上のようにやってしまうと、処理は終わらない。

おそらく、取得するデータをすべてRAMに展開するためである。
あるいは、データを送る前のプリロードに時間がかかり、クエリーがタイムアウトをしている。
どちらにしろ、この方法でデータを取得することは出来ない。

2. ページング

SELECT user_id, external_id, name, metadata, date_created FROM users
ORDER BY user_id ASC LIMIT 0, 10 000;

データをページに入れて取得する方法がある。
データの取得順は物理的/論理的に保証されないため、ソートする必要がある。
これの実行時間は10 000 rows in set (0.03 sec)で行われている。

それでは、5,000ページ目を取得するとどうだろうか。

SELECT user_id, external_id, name, metadata, date_created FROM users
ORDER BY user_id ASC 
LIMIT 50 000 000, 10 000; --- 5 000th page * 10 000 page size

この実行時間は、10 000 rows in set (40.81 sec)となる。
確かに、めちゃめちゃ遅い。

さらに最後のページを取ろうとするとどうなるか。

SELECT user_id, external_id, name, metadata, date_created FROM users
ORDER BY user_id ASC
LIMIT 99 990 000, 10 000; --- 9999th page * 10 000 page size

実行時間は、10 000 rows in set (1 min 20.61 sec)となる。
実際に使うには、バックグラウンドで動くようなタスクにしか使えない。

実行時間のほかにもう1つ問題になりうるケースがある。
例えば、既に10ページめくっている状態(100,000 件のデータにアクセス)で、
次のページ(100,001 から 101,000)へアクセスしようとしている時を考える。
そのタイミングで、99,998と99,999レコードが消されてしまったら、
ページの最初の結果は、100,003からになってしまう。

つまり、ミュータブルなデータセットの場合、この方法は使えないということになる。

3. indexを利用したページング

一つ前と非常に似ているが、レコード数でページングをするのではなく、
indexのついたuser_idをオフセットとして利用している。
アルゴリズムとしては、以下のようになる。
1. テーブルからレコードのPAGE_SIZEを取得し、オフセットを0とする 2. 次ページのために取得したuser_idの最大値をオフセットとする 3. 現在のオフセットよりも大きいuser_idを取得する

1ページあたり10,000件のデータを持たせ、5,000ページ目を取得する場合は次のようになる。

SELECT user_id, external_id, name, metadata, date_created FROM users
WHERE user_id > 51 234 123 --- value of user_id for 50 000 000th record
ORDER BY user_id ASC
LIMIT 10 000;

驚くことに実行時間は10 000 rows in set (0.03 sec)とあるように、1000倍も速い。
user_idの値は連続的ではなく、例えば25345の次は25348となっている。
これならば、読み込む次のデータが消されても問題なく動作する。

まとめ

この記事では1億行のレコードを持つテーブルを読み込む時に、
プライマリーキーを指定しているオフセットを使うこととしている。

2017-10-14 Steve Wozniak announces tech education platform Woz U

原文:techcrunch.com

Appleの共同創立者として知られるSteve Wozniak氏が
オンライン教育のプラットフォーム「Woz U」をローンチした。

最初のカリキュラムはコンピューターサポートの専門家と
ソフトウェア開発者がターゲットになっている。
また、データサイエンス、モバイルアプリケーション、
サイバーセキュリティも近い生来追加される予定。

Wozniak氏によると、Woz Uの目的は、
働くことの出来る人にデジタルスキルの教育と訓練を
何年もかけずに行うこととしている。

Google API をJava経由で叩く時にログを出す

com.google.api.client.http.HttpRequest内でログレベルがLEVEL.CONFIGだったらログを出すとしている。

  public HttpResponse execute() throws IOException {
      //省略
      Logger logger = HttpTransport.LOGGER;
      boolean loggable = loggingEnabled && logger.isLoggable(Level.CONFIG);
      //省略
      if (loggable) {
            logger.config(logbuf.toString());
      }     
      //省略
  }

結論としては、動かしているJREのlib以下にあるlogging.propertiesを編集すれば良い。

handlers= java.util.logging.ConsoleHandler

java.util.logging.ConsoleHandler.level = CONFIG
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

こうなっていれば出るはず。

最終的に以下のような出力が得られる。
ここではGSuiteのAdmin SDKを利用した際のログを示す。

2017/10/12 17:42:04 com.google.api.client.http.HttpRequest execute
設定: -------------- REQUEST  --------------
GET https://www.googleapis.com/admin/directory/v1/groups/${group_mail}/members?maxResults=200
Accept-Encoding: gzip
Authorization: Bearer ${token}
User-Agent: GoogleApps-Test Google-API-Java-Client Google-HTTP-Java-Client/1.20.0 (gzip)

2017/10/12 17:42:04 com.google.api.client.http.HttpRequest execute
設定: curl -v --compressed -H 'Accept-Encoding: gzip' -H 'Authorization: Bearer ${token}' -H 'User-Agent: GoogleApps-Test Google-API-Java-Client Google-HTTP-Java-Client/1.20.0 (gzip)' -- 'https://www.googleapis.com/admin/directory/v1/groups/${group_mail}/members?maxResults=200'
2017/10/12 17:42:05 com.google.api.client.http.HttpResponse <init>
設定: -------------- RESPONSE --------------
HTTP/1.1 200 OK
ETag: "${etag}"
X-XSS-Protection: 1; mode=block
Expires: Thu, 12 Oct 2017 08:42:07 GMT
Server: GSE
X-Content-Type-Options: nosniff
Cache-Control: private, max-age=0, must-revalidate, no-transform
X-Frame-Options: SAMEORIGIN
Alt-Svc: quic=":443"; ma=2592000; v="39,38,37,35"
Transfer-Encoding: chunked
Vary: X-Origin
Vary: Origin
Date: Thu, 12 Oct 2017 08:42:07 GMT
Content-Encoding: gzip
Content-Type: application/json; charset=UTF-8

2017/10/12 17:42:05 com.google.api.client.util.LoggingByteArrayOutputStream close
設定: Total: 111 bytes
2017/10/12 17:42:05 com.google.api.client.util.LoggingByteArrayOutputStream close
設定: {
 "kind": "admin#directory#members",
 "etag": "\"${etag}\""
}

2017-10-10 A Data-Driven Guide to Becoming a Consistent Billionaire

原文:A Data Driven Guide to Becoming a Consistent&nbsp;Billionairetheartandscienceofdata.wordpress.com

億万長者の特性についてのお話。

Bill Gatesのように、常にForbesの億万長者ランキング上位にいる人もいれば、
里見治のように、3回もランキングから外れる人もいる。
この2人は同じように億万長者として一般化して言えるのか、をデータから分析している。

始めに、億万長者を以下の4つで分類している:

  • The Consistent : 年々資産が増加し続けている
  • The Ghosts : 過去4年の間にリストから消えて戻ってこない人
  • The Hustlers : リストから消えたり戻ってきたりする人
  • The Newbies : 過去2年の間にランクインした人。

The Consistentの55%近くは1つ以上の学位を有している。
事実として、The Consistentは学士、修士、博士のいずれか1つ以上を有している。

自らビジネスを興したThe Consistentの億万長者は、
平均して30台でビジネスをスタートさせている。

The Consistentの事業は、電気通信、ファッションあるいは多様化したポートフォリオを行っている。

アフリカの億万長者のほとんどがThe Consistentである。
逆にアジアはThe Consistentが占める割合が40%未満しかない。

億万長者のうち、修士を持っている人のほうが、中退している人よりも多い。

The Consistentのうち11%が女性である。
The Newbiesでは16%が女性である。

The Consistentのうち64%は自分で起業している。
The Ghostsが最も割合が低く、60%程度ある。