2016年8月4日

【翻訳】 On Uber’s Choice of Databases (データベースにおけるUberの選択について)

数日前、Uberのブログで「Why Uber Engineering Switched from Postgres to MySQL」というエントリが公開されました。
それに対して、PostgreSQLコミュニティ界隈でもいろいろなブログエントリが公開されました。
今回は、そのエントリの中でも、「Use The Index, Luke!」でおなじみのMarkus Winand氏のエントリ「On Uber’s Choice of Databases」が個人的に興味深かったので、同氏の翻訳許可をいただきまして、ここに対訳形式で公開します。

なお、当然ですが翻訳に際しての文責は翻訳者である永安にありますので、問題を見つけた場合にはコメント欄またはTwitter (@snaga)などで連絡いただけますと幸いです。

では、どうぞ。


■On Uber’s Choice of Databases (データベースにおけるUberの選択について)


On 7-29-2016
By Markus Winand

A few days ago Uber published the article “Why Uber Engineering Switched from Postgres to MySQL”. I didn’t read the article right away because my inner nerd told me to do some home improvements instead. While doing so my mailbox was filling up with questions like “Is PostgreSQL really that lousy?”. Knowing that PostgreSQL is not generally lousy, these messages made me wonder what the heck is written in this article. This post is an attempt to make sense out of Uber’s article.

数日前、Uberが「なぜUberエンジニアリングはPostgresからMySQLに切り替えたのか(Why Uber Engineering Switched from Postgres to MySQL)」という記事を公開しました。私は、この記事をすぐには読んでいませんでした。というのは、私の中のナード魂が、記事を読むのではなく自宅の改修を行うように私に促してきたからです。それをしている間、私のメールボックスは「PostgreSQLはそんなにひどいのか?(Is PostgreSQL really that lousy?)」というような質問でいっぱいになりました。一般的に言って、PostgreSQLはひどくはありません。それらのメッセージは、そもそも元記事でどれだけ大げさなことが書かれているのだろうか、という疑問を私に植えつけました。この記事は、Uberの記事にどのような理屈・道理を見出すか、というひとつ試みになります。

In my opinion Uber’s article basically says that they found MySQL to be a better fit for their environment as PostgreSQL. However, the article does a lousy job to transport this message. Instead of writing “PostgreSQL has some limitations for update-heavy use-cases” the article just says “Inefficient architecture for writes,” for example. In case you don’t have an update-heavy use-case, don’t worry about the problems described in Uber’s article.

私の見解では、Uberの記事は彼らの環境においてPostgreSQLよりMySQLの方がよくフィットしていることに気付いた、ということを基本的には述べています。が、そのメッセージを伝えるに当たって、この記事はひどいものとなっています。例えば、「PostgreSQLは更新処理の多いユースケースではいくつかの制約がある」と書くのではなく、この記事は単に「更新には非効率なアーキテクチャ」と書いています。もし、あなたが更新処理の多いユースケースでないのであれば、Uberの記事で説明されている問題を心配する必要はありません。

In this post I’ll explain why I think Uber’s article must not be taken as general advice about the choice of databases, why MySQL might still be a good fit for Uber, and why success might cause more problems than just scaling the data store.

本ポストでは、なぜUberの記事を一般的なデータベース選択のアドバイスとして受け取ってはならないのか、なぜMySQLがUberによって良い選択肢なのか、そして、成功することがなぜ単なるデータストアのスケーリング以上の問題を引き起こすのかを解説します。

■On UPDATE (UPDATEについて)


The first problem Uber’s article describes in great, yet incomplete detail is that PostgreSQL always needs to update all indexes on a table when updating rows in the table. MySQL with InnoDB, on the other hand, needs to update only those indexes that contain updated columns. The PostgreSQL approach causes more disk IOs for updates that change non-indexed columns (“Write Amplification” in the article). If this is such a big problem to Uber, these updates might be a big part of their overall workload.

Uberの記事が解説しているけれども厳密には不完全な最初の問題は、PostgreSQLはテーブル内の行を更新する時に常にすべてのインデックスを更新する必要がある、という部分です。一方で、InnoDBを使うMySQLは更新されたカラムを使っているインデックスだけを更新する必要がある。PostgreSQLのアプローチはインデックスのないカラムの更新時により多くのディスクI/Oを引き起こす(元記事では "Write Amplification" とされています)。もし、これがUberにとって大きな問題なのであれば、これらの更新が彼らのワークロードの多くを占めているはずです。

However, there is a little bit more speculation possible based upon something that is not written in Uber’s article: The article doesn’t mention PostgreSQL Heap-Only-Tuples (HOT). From the PostgreSQL source, HOT is useful for the special case “where a tuple is repeatedly updated in ways that do not change its indexed columns.” In that case, PostgreSQL is able to do the update without touching any index if the new row-version can be stored in the same page as the previous version. The latter condition can be tuned using the fillfactor setting. Assuming Uber’s Engineering is aware of this means that HOT is no solution to their problem because the updates they run at high frequency affect at least one indexed column.

しかし、Uberの記事に書かれていない事柄について考慮すると、少し思惑があるのかもしれません: 記事では PostgreSQL の Heap-Only-Tuples (HOT) について言及していないのです。PostgreSQLのソースコードには、HOTは特殊なケース、「インデックスが作成されているカラムを変更しない更新が繰り返される」時に有用である、とあります。この場合に、PostgreSQLは新しいバージョンの行が以前のバージョンの行と同じページに格納できる時には、インデックスに一切触らずに更新できるのです。後者の条件は fillfactor の設定を使うことで調整できます。Uber's Engineering の記事がこれに気付いていると仮定すると、HOTが彼らの問題のソリューションにならない理由は、つまりは彼らが高頻度で実行している更新処理が、インデックスの貼られたカラムを少なくとも一つは対象としているからなのでしょう。

This assumption is also backed by the following sentence in the article: “if we have a table with a dozen indexes defined on it, an update to a field that is only covered by a single index must be propagated into all 12 indexes to reflect the ctid for the new row”. It explicitly says “only covered by a single index” which is the edge case—just one index—otherwise PostgreSQL’s HOT would solve the problem.

この仮定は、記事中の次の文章によって裏付けられています: 「もし、1ダースのインデックスの貼られたテーブルがあったとすると、たった一つのインデックスが作成されているフィールドへの更新は、新しい行の ctid を反映させるために12個すべてのインデックスへと伝播されなければなりません」。ここでは明確に、「たった一つのインデックスが作成されている」と書かれており、ひとつのインデックスというのは境界条件(edge case)になりますが、そうでなければ(※訳注:インデックスが無いカラムの場合には)PostgreSQLのHOTがこの問題を解決します。

[Side note: I’m genuinely curious whether the number of indexes they have could be reduced—index redesign in my challenge. However, it is perfectly possible that those indexes are used sparingly, yet important when they are used.]

[備考: 私は心底、彼らの作成しているインデックスの数をどれだけ減らせるかに興味があります、インデックス再設計の挑戦として。しかし、それらのインデックスがあまり使われていないという可能性は十分にあるものの、それでもそれらが使われた時には重要ではあります。]

It seems that they are running many updates that change at least one indexed column, but still relatively few indexed columns compared to the “dozen” indexes the table has. If this is a predominate use-case, the article’s argument to use MySQL over PostgreSQL makes sense.

彼らは、多くの更新処理を、インデックスの貼られた少なくとも一つ以上のカラムを更新するものを実行しているようですが、それでも「1ダースの」インデックスと比べると、相対的に少ないです。これがユースケースの大部分なのであれば、記事の主張であるPostgreSQLの代わりにMySQLを使うという主張は納得がいくものです。

■On SELECT (SELECTについて)


There is one more statement about their use-case that caught my attention: the article explains that MySQL/InnoDB uses clustered indexes and also admits that “This design means that InnoDB is at a slight disadvantage to Postgres when doing a secondary key lookup, since two indexes must be searched with InnoDB compared to just one for Postgres.” I’ve previously written about this problem (“the clustered index penalty”) in context of SQL Server.

彼らのユースケースについて、私が注目した文章がもう一つあります: 記事では、MySQL/InnoDBはクラスター化インデックスを使っており、「この設計は、InnoDBがセカンダリインデックスを参照する時に、PostgreSQLに対してわずかな不利益があることを意味している。なぜならば、Postgresがただ一つのインデックスを使うのに対して、InnoDBでは2つのインデックスを検索しなければならないからだ」ということを認めています。私は、SQL Serverにおけるこの問題(クラスタ化インデックスのペナルティ)について以前書いたことがあります。

What caught my attention is that they describe the clustered index penalty as a “slight disadvantage”. In my opinion, it is a pretty big disadvantage if you run many queries that use secondary indexes. If it is only a slight disadvantage to them, it might suggest that those indexes are used rather seldom. That would mean, they are mostly searching by primary key (then there is no clustered index penalty to pay). Note that I wrote “searching” rather than “selecting”. The reason is that the clustered index penalty affects any statement that has a where clause—not just select. That also implies that the high frequency updates are mostly based on the primary key.

私の注意を引いたのは、彼らがクラスター化インデックスのペナルティを「わずかな不利益」としていたことです。私の見解では、もしあなたがセカンダリインデックスを使う多くのクエリを実行しているのであれば、これは非常に大きな不利益なのです。もし、これが彼らにとってわずかな不利益なのであれば、それらのインデックスがめったに使われていないことを示唆しています。つまり、ほとんどの場合には主キーによる検索(searching)である(よってクラスター化インデックスのペナルティは発生しない)ことを意味しています。私が選択(selecting)ではなく検索(searching)と書いたことに注意してください。その理由は、クラスター化インデックスのペナルティは、SELECTのみならず、すべてのWHERE句を持つクエリに影響するからです。またこのことにより、高頻度の更新処理の大部分は主キーを使っていると想定できます。

Finally there is another omission that tells me something about their queries: they don’t mention PostgreSQL’s limited ability to do index-only scans. Especially in an update-heavy database, the PostgreSQL implementation of index-only scans is pretty much useless. I’d even say this is the single issue that affects most of my clients. I’ve already blogged about this in 2011. In 2012, PostgreSQL 9.2 got limited support of index-only scans (works only for mostly static data). In 2014 I even raised one aspect of my concern at PgCon. However, Uber doesn’t complain about that. Select speed is not their problem. I guess query speed is generally solved by running the selects on the replicas (see below) and possibly limited by mostly doing primary key side.

最後に、もう一つの書かれていない点、彼らのクエリについて私に何かを教えてくれている部分があります: 彼らはPostgreSQLのIndex-Onlyスキャンの実行における制約については触れていません。特に更新の多いデータベースにおいては、PostgreSQLのIndex-Onlyスキャンはまったくと言っていいほど役に立ちません。これは、私の顧客の多くに影響を与える唯一の問題です。このことについて、2011年にはブログを書きました2012年には、PostgreSQL 9.2がIndex-Onlyスキャンの限定されたサポート(大部分が静的なデータに対してのみ機能する)を実現しました。2014年には、私の懸念のひとつの側面について PgCon で問題提起をしました。しかし、Uberはそれについて問題視していません。SELECTの速さは彼らにとって問題ではないのです。想像するに、クエリの速さは一般的に、レプリカでSELECTすることによって解決され、かつ、主キーを使って操作するということによって(※訳注:実行時間は)限定されるのです。

By now, their use-case seems to be a better fit for a key/value store. And guess what: InnoDB is a pretty solid and popular key/value store. There are even packages that bundle InnoDB with some (very limited) SQL front-ends: MySQL and MariaDB are the most popular ones, I think. Excuse the sarcasm. But seriously: if you basically need a key/value store and occasionally want to run a simple SQL query, MySQL (or MariaDB) is a reasonable choice. I guess it is at least a better choice than any random NoSQL key/value store that just started offering an even more limited SQL-ish query language. Uber, on the other hand just builds their own thing (“Schemaless”) on top of InnoDB and MySQL.

この時点で、彼らのユースケースは Key/Valueストアの方がよりフィットするように見えます。そして、想像してください: InnoDBは非常に堅牢で人気のあるKey/Valueストアなのです。InnoDBに(非常に限定された)SQLフロントエンドをバンドルしたパッケージがあります: 私が思うに、MySQLとMariaDBは非常に人気のあるものです。皮肉を許してください。でもマジメに: もしあなたが求めているものがKey/Valueストアであり、シンプルなクエリを時々実行するものであれば、MySQL(またはMariaDB)は合理的な選択肢です。少なくとも、最近になって限定されたSQLっぽいクエリ言語を提供し始めたばかりのどこかのNoSQL Key/Valueストアよりは良い選択肢だと思います。Uberは、逆に彼ら自身のもの(Schemaless)をInnoDBとMySQLの上に構築しました。

■On Index Rebalancing (インデックスの再バランスについて)


One last note about how the article describes indexing: it uses the word “rebalancing” in context of B-tree indexes. It even links to a Wikipedia article on “Rebalancing after deletion.” Unfortunately, the Wikipedia article doesn’t generally apply to database indexes because the algorithm described on Wikipedia maintains the requirement that each node has to be at least half-full. To improve concurrency, PostgreSQL uses the Lehman, Yao variation of B-trees, which lifts this requirement and thus allows sparse indexes. As a side note, PostgreSQL still removes empty pages from the index (see slide 15 of “Indexing Internals”). However, this is really just a side issue.

その記事が、インデックスについてどのように説明しているかについての最後の一点です: 記事中でB-Treeインデックスの文脈で「再バランス(rebalancing)」という言葉を使っています。また、Wikipediaの「削除後の再バランス」の記事へのリンクも貼っています。残念なことに、Wikipediaの記事の内容はデータベースのインデックスに対して適用させることはできません。なぜなら、Wikipediaで説明されているアルゴリズムでは、各ノードが少なくとも半分埋まっている状態であることを要求しているからです。PostgreSQLでは、並行性を向上させるためにこの前提を除去して疎(sparse)なインデックスを可能にするLhemanとYaoのB-treeの派生版を使っています。追記しておくと、PostgreSQLはインデックス内で空になったページを削除しますが("Indexing Internals"のスライド15枚目を見てください)、これは枝葉の問題です。

What really worries me is this sentence: “An essential aspect of B-trees are that they must be periodically rebalanced, …” Here I’d like to clarify that this is not a periodic process one that runs every day. The index balance is maintained with every single index change (even worse, hmm?). But the article continues “…and these rebalancing operations can completely change the structure of the tree as sub-trees are moved to new on-disk locations.” If you now think that the “rebalancing” involves a lot of data moving, you misunderstood it.

私が本当に心配しているのは次の文章です: 「B-treeの本質的な側面は、それらが定期的に再バランスを必要とすることです」。ここで明確にしておきたいのは、これは毎日実行されるような定期的なプロセスではない、ということです。インデックスのバランスは、いかなる小さな変更であれ、インデックスが変更される際に常にメンテナンスされるのです(もっと悪いですか? ふーむ)。しかし、この記事は続けます。「これらの再バランスの処理は、ツリーの一部(sub-trees)を新しいディスク上の位置に移動させることによって、ツリーの構造を完全に変えてしまうことになります」。ここで、もしあなたが「再バランス」が大量のデータ移動を引き起こしてしまうと考えているならば、それは間違いです。

The important operation in a B-tree is the node split. As you might guess, a node split takes place when a node cannot host a new entry that belongs into this node. To give you a ballpark figure, this might happen once for about 100 inserts. The node split allocates a new node, moves half of the entries to the new node and connects the new node to the previous, next and parent nodes. This is where Lehman, Yao save a lot of locking. In some cases, the new node cannot be added to the parent node straight away because the parent node doesn’t have enough space for the new child entry. In this case, the parent node is split and everything repeats.

B-treeにおいて重要な操作はノードの分割です。あなたが想像した通り、ノードの分割は、そのノードに保持すべき新しいエントリが入り切らなくなった時に発生します。ざっくり理解するために、100回INSERTする度に発生すると仮定しましょう。ノード分割は、新しいノードを割り当て、インデックスエントリの半分を新しいノードに移動させ、新しいノードを以前のノード、隣のノード、および親ノードと連結します。これこそが、LehmanとYaoが多くのロックを削減した部分です。場合によっては、親ノードがいっぱいで新しいノードをすぐに親ノードに追加できない場合があります。その場合、親ノードが分割され、同じようにすべてが繰り返されることになります。

In the worst case, the splitting bubbles up to the root node, which will then be split as well and a new root node will be put above it. Only in this case, a B-tree ever becomes deeper. Note that a root node split effectively shifts the whole tree down and therefore keeps the balance. However, this doesn’t involve a lot of data moving. In the worst case, it might touch three nodes on each level and the new root node. To be explicit: most real world indexes have no more than 5 levels. To be even more explicit: the worst case—root node split—might happen about five times for a billion inserts. On the other cases it will not need to go the whole tree up. After all, index maintenance is not “periodic”, not even very frequent, and is never completely changing the structure of the tree. At least not physically on disk.

最悪なケースでは、ノード分割はルートノードまで伝播していき、同じようにルートノードが分割され、新しいルートノードがその上に配置されます。この場合のみ、B-treeはその階層が深くなるのです。ルートノードの分割は実際、ツリーを下方にシフトさせることでそのバランスを保ちます。しかし、この処理は多くのデータ移動を伴うものではありません。最悪の場合には、各階層で3ノード、および新しいルートノードにアクセスします。明確にしておきたい点: 実際の世の中のほとんどのインデックスは、5階層以上にはならないということです。さらに明確にしておきたい点: 最悪なケース ―ルートノードの分割― は、10億回のINSERTに対して5回くらい起こる、ということです。その他の場合には、ツリー全体を上がっていく必要はありません。このように、インデックスのメンテナンスというのは「定期的」なのではなく、非常に頻繁に発生しているものであり、ツリー全体の構造を完全に変えてしまうようなものでもありません。少なくとも、ディスク上の物理配置については。

■On Physical Replication (物理ログを使ったレプリケーションについて)


That brings me to the next major concern the article raises about PostgreSQL: physical replication. The reason the article even touches the index “rebalancing” topic is that Uber once hit a PostgreSQL replication bug that caused data corruption on the downstream servers (the bug “only affected certain releases of Postgres 9.2 and has been fixed for a long time now”).

この記事が提起したPostgreSQLへの次の大きな懸念: 物理ログを使ったレプリケーションです。元の記事がインデックスの「再バランス」の件に触れたのは、UberがPostgreSQLのレプリケーションで、下流のレプリカにおけるデータ破壊を引き起こすバグを踏んだからです。(このバグは「Postgres 9.2の特定のバージョンだけに発生し、かなり以前に修正されているものです」)

Because PostgreSQL 9.2 only offers physical replication in core, a replication bug “can cause large parts of the tree to become completely invalid.” To elaborate: if a node split is replicated incorrectly so that it doesn’t point to the right child nodes anymore, this sub-tree is invalid. This is absolutely true—like any other “if there is a bug, bad things happen” statement. You don’t need to change a lot of data to break a tree structure: a single bad pointer is enough.

PostgreSQL 9.2では、コア(本体)では物理ログを使ったレプリケーションだけを提供していますので、レプリケーションのバグは「インデックスツリーの大部分が完全に壊れているという状況を引き起こしうる」ものです。詳細に言うと、ノード分割が間違ってレプリケーションされると、二度と正しい子ノードを指し示さなくなってしまい、ツリーの一部が壊れた状態になります。これは、その他の「もしバグがあったなら、悪いことが起こるでしょう」という話と同じで真実のように聞こえるものです。ツリー構造を壊すには、多くのデータを書き換える必要はあなく、ただひとつの間違ったポインタだけで十分なのです。

The Uber article mentions other issues with physical replication: huge replication traffic—partly due to the write amplification caused by updates—and the downtime required to update to new PostgreSQL versions. While the first one makes sense to me, I really cannot comment on the second one (but there were some statements on the PostgreSQL-hackers mailing list).

Uberの元記事は、物理ログベースのレプリケーションのその他の問題を指摘しています: 大量のレプリケーション通信―UPDATEによる書き込みの増幅(write amplification)によるものを含む―、および新しいPostgreSQLバージョンへのアップデートの際にダウンタイムを必要としていること、などです。前者については納得がいくものですが、後者については私にはコメントできません。(が、PostgreSQL-hackersメーリングリストでいくつか言及がありました)

Finally, the article also claims that “Postgres does not have true replica MVCC support.” Luckily the article links to the PostgreSQL documentation where this problem (and remediations) are explained. The problem is basically that the master doesn’t know what the replicas are doing and might thus delete data that is still required on a replica to complete a query.

最後に、元記事は「PostgreSQLはレプリカで真のMVCCをサポートしていない」と苦情を述べています。ラッキーなことに、元記事はその問題を解説した(そして改善した)PostgreSQLのドキュメントにリンクを張っています。この問題は、基本的にはマスターというのはレプリカが何をやっているか知る由もない、つまり、レプリカがクエリを完了するために必要としているデータを、(マスタが)削除するようなことがあり得る、ということです。

According to the PostgreSQL documentation, there are two ways to cope with this issue: (1) delaying the application of the replication stream for a configurable timeout so the read transaction gets a chance to complete. If a query doesn’t finish in time, kill the query and continue applying the replication stream. (2) configure the replicas to send feedback to the master about the queries they are running so that the master does not vacuum row versions still needed by any slave. Uber’s article rules the first option out and doesn’t mention the second one at all. Instead the article blames the Uber developers.

PostgreSQLのドキュメントによると、この問題に対処するためには2つの方法があります: (1) 設定したタイムアウトに達するまで、レプリケーションストリーム(ログ転送)を生成しているアプリケーションを遅延させることで、(※訳注:レプリカで)実行されている読み取りトランザクションが完了できるようにする。(※訳注:レプリカ上の読み取り)クエリが指定した時間内に完了しなければ、そのクエリをキャンセルしてレプリケーションストリームの適用を継続する。 (2) レプリカが実行しているクエリについて、マスター側にフィードバックを送るように設定する。それによって、どこかのスレーブで必要としている行のバージョンに対してマスター側でVACUUMしないようにする。Uberの元記事は1つ目の選択肢については規定していますが、2つ目の選択肢についてはまったく言及していません。Uberの開発者のせいにする代わりに。

■On Developers (開発者について)


To quote it in all its glory: “For instance, say a developer has some code that has to email a receipt to a user. Depending on how it’s written, the code may implicitly have a database transaction that’s held open until after the email finishes sending. While it’s always bad form to let your code hold open database transactions while performing unrelated blocking I/O, the reality is that most engineers are not database experts and may not always understand this problem, especially when using an ORM that obscures low-level details like open transactions.”

これを引用できることを嬉しく思います: 「例えば、開発者が領収書をユーザにメールするコードを書いたとします。どのように書かれたのか、その実装にもよりますが、そのコードでは暗黙的に、メールの送信を完了するまでデータベーストランザクションがオープンされたままになるかもしれません。データベースに関連性のないブロッキングI/Oが実行される間、データベーストランザクションをオープンしたままにするというのは、どんな場合でも悪い状況となるわけけですが、現実的にはほとんどのエンジニアはデータベースのエキスパートではなく、特にオープントランザクションのような低いレベルの問題を引き起こすORMを使うような場合には、これらの問題を常には認識していないでしょう。」

Unfortunately, I understand and even agree with this argument. Instead of “most engineers are not database experts” I’d even say that most developers have very little understanding of databases because every developer that touches SQL needs know about transactions—not just database experts.

残念なことに、私は認識しており、この主張に賛同しています。「ほとんどのエンジニアはデータベースのエキスパートではない」と言う代わりに、データベースエキスパートだけではなくSQLに触るすべての開発者がトランザクションについて知っていなければならないにも関わらず、ほとんどの開発者はデータベースについてわずかしか理解していない、と言うことができます。

Giving SQL training to developers is my main business. I do it at companies of all sizes. If there is one thing I can say for sure is that the knowledge about SQL is ridiculously low. In context of the “open transaction” problem just mentioned I can conform that hardly any developer even knows that read only transactions are a real thing. Most developers just know that transactions can be used to back out writes. I’ve encountered this misunderstanding often enough that I’ve prepared slides to explain it and I just uploaded these slides for the curious reader.

SQLのトレーニングを開発者に提供することは私のメインのビジネスです。あらゆる規模の企業においてこれを行っています。私が言えるひとつ確実なことは、SQLについての知識が尋常でなく低いということです。たった今言った「オープントランザクション」の文脈においては、開発者たちは、参照のみのトランザクションが実際重要なものである、と多少は知っていると思います。ほとんどの開発者はトランザクションは書いたものを戻すために使うことができる、ということを知っているくらいでしょう。私は、これを説明するスライドを準備している際、度々この誤解に遭遇しますし、その度にこの問題に興味のある読者に向けてスライドをアップロードしているのです。

■On Success (成功について)


This leads me to the last problem I’d like to write about: the more people a company hires, the closer their qualification will be to the average. To exaggerate, if you hire the whole planet, you’ll have the exact average. Hiring more people really just increases the sample size.

このことは、私が書きたい最後の問題に私を導きます: 企業がより多くの人を雇うようになると、彼ら彼女らの能力は平均値に近づきます。大げさに言うと、もし地球上のすべての人を雇えば、完全に平均値になります。より多くの人を雇うということは、実際にサンプルサイズを大きくする、ということなのです。

The two ways to beat the odds are: (1) Only hire the best. The difficult part with this approach is to wait if no above-average candidates are available; (2) Hire the average and train them on the job. This needs a pretty long warm-up period for the new staff and might also bind existing staff for the training. The problem with both approaches is that they take time. If you don’t have time—because your business is rapidly growing—you have to take the average, which doesn’t know a lot about databases (empirical data from 2014). In other words: for a rapidly growing company, technology is easier to change than people.

この可能性を避ける2つの方法は: (1) ベストな人材のみを雇うこと。このアプローチの難しいところは、平均値以上の候補者が見つからない時に待つ必要があることです。 (2) 平均値の人を雇って仕事をしながらトレーニングすること。この方法は新しいスタッフに対して本当に長いウォームアップ期間を必要としますし、既存のスタッフについてもトレーニングに拘束することになるでしょう。両者に共通する問題は、時間がかかる、ということです。もし、あなたに時間がない ―ビジネスが急成長しているなどの理由で― のであれば、データベースについてさほど分かっていない平均値の人を雇うしかありません(2014年に実証されています)。言い換えれば: 急激に成長している企業にとっては、人材よりもテクノロジーの方が取り換えは容易なのです。

The success factor also affects the technology stack as requirements change over time. At an early stage, start-ups need out-of-the-box technology that is immediately available and flexible enough to be used for their business. SQL is a good choice here because it is actually flexible (you can query your data in any way) and it is easy to find people knowing SQL at least a little bit. Great, let’s get started! And for many—probably most—companies, the story ends here. Even if they become moderately successful and their business grows, they might still stay well within the limits of SQL databases forever. Not so for Uber.

また成功要因は、時間の経過に伴って要求が変化するため、テクノロジースタックに影響を与えます。アーリーステージにおいては、スタートアップはすぐに利用可能なテクノロジーであり、彼らのビジネスにおいて十分に柔軟であるものを必要とします。SQLは、本当に柔軟であるからこそ(どんなやり方であれ、データに対して問い合わせすることはできます)、この局面で良い選択肢であり、SQLを多少なりとも知っている人を見つけることはたやすいことです。素晴らしい、さぁ始めましょう! そして、ほとんどの会社にとって、話はここで終わるのです。仮に緩やかな成功と、ビジネスの成長が実現できたとしても、SQLデータベースの制約の中に健やかに留まっていることになるでしょう。Uberはそうではありませんでしたが。

A few lucky start-ups eventually outgrow SQL. By the time that happens, they have access to way more (virtually unlimited?) resources and then…something wonderful happens: They realize that they can solve many problems if they replace their general purpose database by a system they develop just for their very own use-case. This is the moment a new NoSQL database is born. At Uber, they call it Schemaless.

まれにラッキーなスタートアップは最終的にSQLの限界を超えます。それが起こる時、彼らはさらなる(仮想的には無限の?)リソースを利用することができ、そして。。。何か素敵なことが起こります: 彼らは、その一般的な用途のデータベースを彼ら独自のユースケースだけのために開発したシステムでリプレースすることで、多くの問題を解決できることを認識するのです。これこそが、新しいNoSQLデータベースが生まれる瞬間です。Uberでは、それはSchemalessと呼ばれています。

■On Uber’s Choice of Databases (データベースにおけるUberの選択について)


By now, I believe Uber did not replace PostgreSQL by MySQL as their article suggests. It seems that they actually replaced PostgreSQL by their tailor-made solution, which happens to be backed by MySQL/InnoDB (at the moment).

現時点では、私はUberは彼らの記事が言っているようにPostgreSQLをMySQLでリプレースしたとは思っていません。彼らは実際には、(現時点では)MySQL/InnoDBで支えられた彼ら独自のソリューションでPostgreSQLを置き換えたように見えます。

It seems that the article just explains why MySQL/InnoDB is a better backend for Schemaless than PostgreSQL. For those of you using Schemaless, take their advice! Unfortunately, the article doesn’t make this very clear because it doesn’t mention how their requirements changed with the introduction of Schemaless compared to 2013, when they migrated from MySQL to PostgreSQL.

元記事は、MySQL/InnoDBがなぜ彼らのSchemalessのバックエンドとして、PostgreSQLよりも良かったのか、ということを説明しているように見えます。Schemalessを使っている人たちは、そのアドバイスを聞くべきでしょう! 残念ながら、元記事はそのことについて明確にしていません。というのは、Schemalessを紹介するに当たって、彼らの要件が2013年、彼らがMySQLからPostgreSQLに移行した時と比べてどのように変化してきたのかについて言及していないからです。

Sadly, the only thing that sticks in the reader’s mind is that PostgreSQL is lousy.

悲しいことに、読者の頭の中に残るのは、PostgreSQLがひどい、ということだけです。

If you like my way of explaining things, you’ll love my book.

もし、私が説明する諸々を気に入っていただけるのであれば、おそらく私の本(※訳注:日本語版)も気に入ってもらえるのではないかと思います。

2 件のコメント:

  1. 翻訳おつかれさまでした & ありがとうございます。

    『most developers have very little understanding of databases because every developer that touches SQL needs know about transactions―not just database experts.』の部分についてですが、「because」をmacosx付属の英和辞典で調べると、以下のような意味があります。


    3 ⦅くだけた話⦆〖否定語を伴った主節と共に〗…だからといって(…ない) (!主節の否定語は文全体にかかる; 主節の後でもbecauseの前には通例コンマ[休止]をおかない)
    ▸ I didn't come hére because I wanted apologies or thank-yous(). All I wanted was for us to be friends.
    謝罪や感謝の言葉が欲しくてここに来たんじゃない. ただ友達になりたかったんだ(≒It was not because I wanted apologies or thank-yous that I came here…) (!1と違って文末は下降上昇調となる) .


    なので、先の英文を翻訳すると、
    「データベースのエキスパートに限らずSQLに携わる開発者はすべて、トランザクションについての知識を持ってる必要があるのに、たいていの開発者はデータベースの知識をほとんど持っていない」
    という意味かな、と思いました。
    (英語に自信があるわけではないので、間違っていたらごめんなさい。)

    返信削除
    返信
    1. ありがとうございます。
      ここの文章、確かに訳すのが難しかった個所のひとつだったんですが、文脈と勢いで訳してました。

      なるほど、
      「every developer that touches SQL needs know about transactions―not just database experts」だからと言って、「most developers have very little understanding of databases」(否定文)という構造なんですね。

      ということは、
      「データベースエキスパートだけではなく、SQLに触るすべての開発者がトランザクションについて知っていなければならないにも関わらず、ほとんどの開発者はデータベースについてわずかしか理解していない」
      ということになるわけですね。

      勉強になりました。ありがとうございます。修正しておきます。

      削除