GitHub Pages にホスティングしたTypeDocが404になる

GitHub Pagesは、 _で始まるファイルが表示されない。これはGitHubの仕様である模様。

TypoeDocは module ディレクトリ以下に _ で挟まれたHTMLファイルを生成する。そのまま、GitHub Pagesにホスティングしてしまうと404になってしまう。

これらのファイルを表示するためには、ドキュメントのルートに( docs 下をGitHubPagesで公開していたら docs ディレクトリ直下).nojekyll ファイルを設置すればよい。

touch .nojekyll

References

typedocで 「no such file or directory, stat」 というエラーが出る

typedoc でドキュメントを生成しようとすると以下のようなエラーが出るようになってしまった。

❯ yarn docs
yarn docs v0.27.5
$ typedoc --theme default --out docs src

Using TypeScript 2.4.1 from /Users/yoshiki_aoki/work/src/.../node_modules/typescript/libfs.js:954
  binding.stat(pathModule._makeLong(path));
          ^
Error: ENOENT: no such file or directory, stat '/Users/yoshiki_aoki/work/src/.../node_modules/typedoc-default-themes/bin/default/assets'

試しに全部node_module消してキャッシュもクリーンしてインストールし直してみた。

yarn cache clean
yarn

yarnでインストールし直してもダメ。lsで該当ファイルを確認してもない。。。

ふと、npmを使ってインストールしてみた。 npm install したら治った。

🤔

.yarnclean が原因

2017/09/14 追記。

色々と調べてみるとどうやら、yarn clean を実行して作成された.yarncleanが原因っぽいということがわかった。 確かに中を覗いてみると、assetsという項目がある。これによって、node_modules内のassetsが削除されている模様。

qiita.com

そして、最新バージョン(1.0.0以降)ではyarn clean からyarn autocleanになっている。

github.com

ローカルで使っていたバージョンが v0.27.5 なのでアップグレードした。

Alfred 3のForce Keyboardがうまく動かない(Sierra)

Alfredの設定で、 Preference > Advanced > Force Keyboard を設定しておくと、IMEが日本語入力になっていても自動的に英字入力に切り替えてくれる。

f:id:ringo6119:20170902014141j:plain

しかし、TouchBarのMacBookProになってからこの機能がうまく動かない。調べるとSierraになってから発生してるらしい。

事象としては一文字めだけ日本語入力になってしまう。例えば、「chrome」と入力しようとすると「chrome」のようになったり、「alfred」と入力しようとすると「あlfred」となる。

f:id:ringo6119:20170902014136g:plain

調べてみたらAlfred公式のフォーラムにポストがあった。

Force keyboard is a little buggy on Sierra - Noted - Alfred App Community Forum

こんな書き込みが。

I’ll look into this, but for now, try switching Alfred to focus compatibility mode in the Appearance > Options preferences

ほー。なるほど🤔。

f:id:ringo6119:20170902014131j:plain

目立たないところにあるなぁ。。

Focusingを Compatibility Mode に変更。

f:id:ringo6119:20170902014139j:plain

今の所、いい感じで動いてる。

MySQLで外部キー制約を課すべきか

外部キー制約を設けておくと、存在しないエンティティ(例えばユーザIDなど)にリレーションをシステム的に持てないようにすることができる。これは、データの不整合を防ぐためには非常に有効な手段であると思う。

SQLアンチパターンには「キーレスエントリ(外部キー嫌い)」というタイトルで章が割かれている。基本的に制約を設けた方が色々とよいという結論である模様。

私が所属しているチームでも同様な議論がされたため、論点になった箇所と考察を書いておく(普段はこういうところにあんまり書かないんだけど、なんか勿体無いなと思って)。最終的な結論としては、外部キー制約は設けない方向で行くという決断をした。

外部キー制約に関する論点

データの整合性

外部キー制約を設けると、最初にも書いたが存在しない要素のIDにはリレーションを持つことができないため、データの生合成を保証することができる。これは、制約を設けることの大きなメリット。人間が考えることを少なくし、システムを強固にしてくれる。

テストについて

テストデータを作成する場合、リレーション元のテーブルから順番に作成しないといけないため、テストデータに工夫が必要でコストが高いという意見が出た。この件に関しては、どちらのケースでも対応する方法はある模様。

少し乱暴だがテストデータをインサートする前に SET FOREIGN_KEY_CHECKS=0; を発行して外部キー制約のチェックを無効にする方法がある。そして、テストが終わった時に SET FOREIGN_KEY_CHECKS=1; チェックを有効にする。本番のDBではあり得ないが、テストDBなら問題はないだろう(そもそもモックしろとかそういう話も色々あるが)。

しかし、これはこれで「外部キー制約を踏まえたテストができないので全てが丸く収まるというわけにはいかなそう」という問題もでてきた。

テストデータを作成するのが面倒くさいというが、何も制約がない状況下で制約を担保するようなテストを書く方が手間がかかり、考え事が増えるという話もある(テストfixtureを準備するのがめんどくさい(?))。

とはいえ、安全側に倒すことを考えるとこの件に関しても外部キー制約を設けた方が良さそうな気がする。

パーティショニングされたテーブル

InnoDBはパーティショニングされたテーブルについて、外部キー制約をサポートしないという悲しい事実がある。これはどうにもできない。親だろうが、子だろうがどちらか一方がパーティショニングされたテーブルだった場合、制約を課すことができない。 また、シャーディングされたテーブルにおいても同様に、外部キー制約を課すことができない。

InnoDB ストレージエンジンを使用するパーティション化されたテーブルでは、外部キーはサポートされません。これは具体的には、次の 2 つの記述が true であることを意味します。 1. ユーザー定義パーティショニングを使用する InnoDB テーブルの定義には、外部キー参照を含めることはできません。定義に外部キー参照が含まれる InnoDB テーブルはパーティション化できません。 2. InnoDB テーブル定義に、ユーザーパーティション化されたテーブルへの外部キー参照を含めることはできません。ユーザー定義パーティショニングを持つ InnoDB テーブルに、外部キーによって参照されるカラムを含めることはできません。 https://dev.mysql.com/doc/refman/5.6/ja/partitioning-limitations.html

今回のプロジェクトはパーティショニングされたテーブルがそれなりの個数存在し、当初はSpiderでのシャーディングも検討していた。そのため、外部キー制約は全てのテーブルに設けない方向で今まで進んでいた。

導入コスト

パーティションの件があるので、すでに外部キー制約を設けない方向でプロジェクトを進めている。とはいえ、制約を課せるところだけ課そうとする意見もあったが、どちらかに統一したいという意見もあった。それに加え、今から導入するとそれなりの作業が発生し導入コストがかかる(これは外部キー制約のデメリットではないが…)。

暗黙のインデックス

このスライドにも書いてあるが、暗黙のインデックスというのが貼られ、インデックスサイズの肥大化につながる。デメリットだけどあまり気にしない。

意図しない箇所でのテーブルロック

リレーション先の行にshared lockがかかる」で指摘されていることで、こっちは逆に外部キー制約を課すデメリットなのかもしれない。

リレーションの親テーブルをうっかりshared lockしていることがある http://songmu.github.io/slides/fk-night/#15

削除対象のレコードがある場合

レコードの削除が想定されるテーブルに外部キー制約を課すと、レコード削除が難しくなるケースがありうるという意見。整合性を保つゆえ仕方ないが、何も考えずにカスケード削除を行うと事故を起こす可能性は否定できないとも。これは、整合性を保ってはくれるがDBの構造を理解しない・気にしなくていいというわけではないのではない。これに関しては、構造は理解していることに越したことはないのだが、「親テーブルの行を消したときに子テーブルの行は残したい」という状況が発生した時点で、設計を見直すべきである

考察

外部キー制約を課すことによって得られるメリットである、「データの整合性」は非常に魅力的ではあるが、パーティショニングをしているテーブルが多いこと、また現在の状況と対応工数を踏まえて検討すると、外部キー制約を課さない方向で行こうと思う。ただ、注意すべきは整合性が取れないということを前提にシステムを設計・構築しなければならない。例えば、どういうことを意味するかというと、APIなどで投稿されるあるキー(例えば商品IDなど)をそのまま信じてDBにインサートしてはいけない(当たり前だけど)。必ずそのIDがデータとして有効なものであるかを確認する必要がある(整合性は取れなかったとしても)。このことを考えると一部だけ外部キー制約を課すという案もある。これは必要に応じで外部キー制約を課したほうが少しはマシになるのではないか。

今回は採用しない方針で進めるが、外部キー制約を課さない方がよいというわけではない。当然だが、全ての事柄はケースバイケースである。外部キー制約を課さないとしても、エンティティ同士のリレーションを表現する図(つまりER図)は人間が見るときに欲しい。

Foreign Key Nightの「我々(主語が大きい)は何故MySQLで外部キーを使わないのか」がだいぶ参考になった。🤔

References

aws-cliの導入とAWS Credentialの設定

AWSが公開してるドキュメントを見ればわかるんだけど、再セットアップ時に行ったので備忘録。

まず、IAMでアクセスキーを発行する。

f:id:ringo6119:20170822020821p:plain

そして、awsコマンドのインストール。

brew install awscli

終わったらターミナルで aws configure を実行して設定を行う。

❯ aws configure
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxxxxxxxxx
Default region name [None]: ap-northeast-1
Default output format [None]: json

References