1. 趣味でOSSをやっている者だ
  2. 50: SQLアンチパターン第2版・..
2025-08-21 54:30

50: SQLアンチパターン第2版・削除フラグを添えて (t_wada)

spotify
  • SQLアンチパターン第2版
  • 第1版と第2版の違い
  • MySQLの匂い
  • IDリクワイアドと主キー採番
  • 正規化を学ぼう
  • 幻のアンチパターン「とりあえず削除フラグ」

SQLアンチパターン第2版

第1版と第2版の違い

  • ナイーブツリー
    • 隣接リストとCTE
  • マジックビーンズ
  • ファントムファイル
  • スタンダード・オペレーティング・プロシージャ (さびついた開発標準)

MySQLの匂い

IDリクワイアドと主キー採番

正規化を学ぼう

  • 付録A: 正規化のルール

幻のアンチパターン「とりあえず削除フラグ」

サマリー

SQLアンチパターン第2版では、リレーショナルデータベースの技術的な特徴や課題、特にツリー構造の扱い方の進化について深く掘り下げています。ここでは第1版からの変更点や新たに実装された機能についても解説されており、実践的なデータベース設計への洞察を得られます。 このエピソードでは、SQLアンチパターン第2版の内容について議論され、アクティブレコードパターンの使用に関する考え方の変化や、ファントムファイルとストアドプロシージャーについて説明されています。特に、外部ストレージの利用やデータベース設計の見直しが重要であることが強調されています。 また、SQLアンチパターン第2版を通じて、MySQLの独自性やIDリクワイヤードパターンの複雑さについて考察が行われています。新しいデータベース設計の動向として、多様なリレーショナルデータベースが存在する現状に触れ、それに伴う命名規約や開発生産性のトレードオフについての議論も展開されています。 エピソードでは、UUIDやビッグイントなどのプライマリキーの選択肢についての議論が進められ、特にスノーフレークIDの利点や正規化の重要性が強調されています。また、論理削除と削除フラグに関する問題についても触れられ、アンチパターンとしての認識の必要性が述べられています。論理削除と削除フラグに関する誤解についても議論され、正しい設計とその必要性が強調されています。

SQLアンチパターン第2版の紹介
はい、趣味でOSSをやっている者だ。引き続き、t-wadaさんを迎えてお話をしていこうと思います。
後半は、もうSQLアンチパターン第2版の話をしていこうと思います。
じゃあ、t-wadaさん、この本についてまずご紹介していただいていいでしょうか。
はい、紹介を預かります。SQLアンチパターン第2版という本の話をさせていただきたいと思います。
第2版というのは、初版があったんですけど、SQLアンチパターンというのは、
良かれと思って、恨みに出てしまうような技術のこと、解決策のことなんですけど、
リリエーショナルデータベースを活用したソフトウェアの開発において、良かれと思って、
それが恨みに出てドツボにはまってしまうみたいな設計のパターンとか、実装のパターンとか、
典型的なやつっていうのがリリエーショナルデータベースを絡んだシステムにはよくあるんですよね。
それを第1版では25のパターンにまとめて、アンチパターン形式という形で読みやすい、
同じような説の構成で読める本にして、よくあるあるある本とかべからず本みたいな感じで、
たくさんの方に読んでいただいてベストセラーになりました。そのベストセラーが12年の時を経て第2版が出るということで、
原初に第2版相当のものが出ましたので、それを再度翻訳して、僕は簡訳したわけですけど、簡訳して、
SQLアンチパターン第2版という形でオラリージャパンから出しました。
第1版と第2版の販売数の考察
7月に、2025年7月に出しましたというような形なので、12年ぶりのロングセラーの改定版という形になります。
いやこれ本当すごいですよね。でもなんかもうSQLアンチパターンとか、もう日本の開発者みんな読んでるでしょぐらいの気持ちだったんですけど、
なんかそれよりかは売れてないんだなみたいなのを、ファインディーさんのイベントでお話しされてたのを伺ってて、ちょっと正直そんなことを思ってしまいました。
数の話ですかね。
そうですね。
SQLアンチパターンの第1版って累計で3万部以上というような形で、これ技術書としてはかなり売れているんですけど、
なので本を書いたことある人は技術書で3万部はすごいなという反応になるんですけど、
逆に文芸書とか小説とかラノベとかに比べると2桁少ないので、それだけなのかみたいな感じとかを印象を受ける方も多分いらっしゃると思います。
そうですね。3万部が技術書の中ではかなりすごいっていうことは感覚としては持ってるんですけど、
とはいえ、もっと売れてていい本だったんじゃないのかなっていう。だってSQLみんな使うじゃんみたいな、そういうふうに結構思ったりしますし。
それこそキャリアの本とかエンジニアの本とか、そういう本だともっと売れてるものもあるのも聞いているので、そうか、結構僕としてはあの数字はショッキングな数字でした。
まあでも、ちゃんとロングセラーで第二版になるのは素晴らしいですね。やっぱりその、翻訳本ってすごく難しいじゃないですか。
ツリー構造の扱いと進化
それこそ版元との契約があって、実はそれが切れちゃうから売れなくなるみたいなパターンとかもあるっていうふうに聞いてますし、
だからちゃんとずっと売れ続けて、この度ちゃんと第二版が出たのって素晴らしいなっていうのを思いました。
なんか結構そういう契約問題で売れなくなっちゃうっていうか、その翻訳契約が切れるからもう日本の出版社から出なくなるみたいなのって結構あったりするって聞きますからね。
そうですよね。結構版元との関係性って割と難しくて、SQLアンチパターンの第二版でも第一版では収録できていたボーナストラックとか新規書き下ろしの章みたいのを
本という形では収録できなくなってしまって、オラリー・ジャパンのサイトから別途ダウンロードできるPDFの形で配布するっていうのがありまして、
具体的には奥野さん、奥野みきやさん、日本男児さんってアカウントの方みんな知ってるSQLのプロですけども、初版のときに書き下ろしで第25章、砂の城っていうのを日本語版ならではのものっていうのを書いてもらったんですね。
なんですけど、SQLアンチパターンも版元との関係でいうと12年経つと、版元プラグマティックブックシェルフという出版社なんですけど、初版訳したときは割と自由にやらせてくれるみたいな感じで
したので、ボーナストラックとしての章を追加したりとか、官訳者としての私も結構、説のレベルだと日本人官訳者による文章みたいな感じで、がっつり説を入れたりとかしていたんですけれども
それがその12年経つと、結構版元の運営母体が変わったわけじゃないですけど、経営の形が変わったんですね。オーナーが変わったみたいなものです。
によって結構、出版契約が厳しくなってしまって、日本語訳以外のオリジナルコンテンツっていうのを書籍の形で差し挟むことはできなくなってしまったんですね。
なので、第1版には追加されていたオリジナルの章であるとか、あるいはオリジナルのコラムであるとか、そういったものは収録できなく、契約上収録できなくなってしまいました。
なので、奥野さんに書いていただいて、しかも第2版向けに改訂もしていただいたんですけど、改訂していただいたにもかかわらず、本に収録、後からできなくなってしまった、契約上できなくなってしまったみたいな形に流れになっちゃったので、
大変申し訳ないので、おらゆりのサイトから皆さんに読んでいただけるようにするというような経緯がありますし、第1版の時に僕が書いていたテクニックとかも収録できなくなっちゃったので、もうそれはお蔵入りみたいな感じになって、
それでも第2版の翻訳を世に出せるっていうことの方が大事だと思っているので、それはやむなしかなと思ってやっています。
そうですね。翻訳本っていうものの性質上、そういうもんだという感じはしますしね。昔、それこそそういうボーナストラックが翻訳版であるみたいなのってすごくたくさんあった気がしますけど、最近そういうの少なくなってきたなって思いますし、ある意味やっぱり大らかな時代だったみたいなのがあるのかもしれないなって思ったりしています。
そうですね。やっぱりその第1版と第2版での違いがあると思うんですけど、そのあたりの話について、ファインディさんの発表でも書かれてますけど、どういったところがあるかみたいなのってお話いただいていいですか。
SKランチパターンの第1版と第2版の間に12年の開きがあるので、リレーションデータベースの世界ってまあまあ枯れてるので、そこまで大幅な技術革新みたいなのはないんですけど、やっぱり12年経っていると、
例えば標準化が進んだりとか、標準化はされていたけど各ベンダーがあんまり実装していなかったとかバラバラだったものが各ベンダーがもう全部それなりに実装するようになったりみたいなところが生まれた結果、第1版のときはアンチパターンだったものがもうほぼ実質的にアンチパターンでなくなったりとか、そういったのも出てきています。
具体的にはツリー構造を扱う章があるんですね。第2版だと第3章の内部ツリーというアンチパターンなんですけど、これ第1版のときはツリー構造、リレーションデータベースで例えば組織の構造とかツリー構造をリレーションデータベースに格納しようとすると、
普通何をするかというと、親IDを持つペアレントIDを持つポインタでつながってるみたいな感じのデータ構造を作ることが多いんですよね。親のIDを持って、孫が親のIDを持って、親がさらにその親のIDを持ってみたいな感じで最終的には根っこ、ルートにつながるみたいな感じのツリー構造というのを形成することが多くて、
それを隣接リストと言うんですけど、この隣接リストってSQLで扱うときは鬼門中の鬼門というか階層が深くなってしまうと隣接リストの階層の深さの分ジョインしなきゃいけなくなって、SQLは縦に長くなって、Columnは横に長くなってみたいな感じでだいぶつらいプログラミングになってしまうので、
隣接リスト設計っていうのをツリー構造の格納に使うのはやめましょう。だから入れ子集合であるとか、あるいはクロージャーテーブルというA4テーブルというやり方ですとか、いくつかやり方があるよというようなパターンが出てきていて、
第1版でもだいぶ好評の章だったんですけど、第2版になって何が変わったかというと、第1版のときにも標準はあったんですけど、いわゆる最期的なSQLが書けるようになったんですよね。
共通テーブル式、Common Table Expression、CTEとよく訳すんですけど、CTEの実装が第1版のときはあまり各ベンダー実装していたりしていなかったりみたいなものが、12年経つと様々なデータベースがCTE共通テーブル式と最経スケールっていうのをもう実装しているので、
そしたらペアレントID持つのでいいじゃんって、多くの場合は隣接リスト設計、初版のときはアンチパターンだった設計でも最経スケールを書けば良いよという話になったんですよね。
これは実質的にはほぼアンチパターンではなくなりました。ツリー構造を格納して検索するとかメインテナンスするっていうのを最経スケールによって多くの場合は問題なくできるようになって、
ツリー構造の検索に対して非常に高パフォーマンスを求める場合とか、ものすごく特殊な場合のみ隣接リスト以外の設計を使いましょうというような温度感になってきました。
そうですよね。これはやっぱりかなり、あの話を聞いて理解したんですけど革命的な出来事だなっていうのは思っていて、やっぱりRDBMSが機構造を扱うのが苦手っていうところがもともとあって、第1版だといくつか解決方法は示されてるものの決定版がない割と歯切れの悪いような内容になってたと思うんですけど、
そこがだいぶ、このサイキクエリーみたいなものによって、かなり恐れる必要がなくなったっていうのはかなり大きな変化なのかなっていうのは思いました。
なんかこのパスを格納しておく方式とか、すごい苦しいやり方がされているから。
そうなんですよね。
まあ今でもそういったのが、それこそ検索性のためには必要になることはあるかもしれないけど、でも概ねかなり解決できたっていうのはかなり大きいですね。
一般的にはツリー構造を格納するときは、隣接リストを第一候補にしていいよとなりましたね。
なので、書き込みより読み込みの方が圧倒的に多いツリー構造で、しかも階層をまたいだ読み込みが非常に多いみたいなときのみ、
入れ子集合とか特殊なデータ構造を使うみたいな感じになってくるかなぐらいのものですね。
そうですね。いや、これはすごいやっぱり進化を感じるいい話だなと思いました。
12年で進化しました。
あと他には何かありますか。
他はですね、大きいところで言うと、第1版にあった章、初版に存在していて第2版には存在していない章があるんですよ。
具体的には第4部に24章、マジックビーンズという章が第1版にはあったんですね。
アクティブレコードパターンの見直し
このマジックビーンズって何かっていうと、アクティブレコードパターンをドメインモデルにアクティブレコードパターンを使うのはアンチパターンだよというような内容だったんですね。
モデルとデータベースと共結合させてしまって、さまざまなところに弊害をもたらすので、アクティブレコードでモデルを実装するのはやめましょうねと。
つまり、ルビオンレールズとかララベルとかに対して真っ向からNOを言ってるみたいな感じの章になっていたんですけど、これがなくなりました。
なくなったっていうのもまたこれ実に味わい深いことで、つまりアクティブレコードパターン自体はデメリットもある。
簡単に言うと結合度、インフラストラクチャーとの結合度が高まってしまうとか、テストビリティの面ではデメリットがあるとかあるんですけど、
それでもこの12年の間でもやっぱりルビオンレールズもそうだし、ララベルもそうだし、さらにそこから派生していったさまざまなフレームワークとかオールマッパーとかが、
さまざまな事業を前に進めてさまざまな事業を支えてきたっていう側面があるので、アクティブレコードパターンあるいはアクティブレコードパターンで
ドメインモデルを実装することそのものがNGなのかアンチパターンなのかっていうと、そうではないよねということになったと思うんですよね。
これも結構大きい変更かなというふうに個人的には思っています。
そうですね、これはある意味アクティブレコードパターンみたいなものを現実界として受け入れたっていうことだと思うので、これはかなりすごい話だなと思いますし、
ただこの本やっぱり主張が強い本ではあるので、ファントムファイルってやつがまだ残ってるっていうのがこれがすごい、それもまた逆に味わい深いなっていうのを思いました。
そうですね、これはおっしゃる通りで、第2版を完約するときに、ファントムファイルまだ残ってるかって気持ちになったんですね。
ファントムファイルというパターンは何かというと、画像ファイルとか動画ファイルとか、要するに巨大なバイナリファイルの類いというのを格納するときにリレーショナルデータベースの中に入れるか、
つまりテーブルの中にVLOG型のような形で入れるか、それとも外部のストレージとかに格納してそこのファイルパスとか、あるいはS3とかだったらURLですよね。
外部のポインターみたいなものだけリレーショナルデータベースの中に格納するか。
この本、ISQLアンチパターン著者は、外部のつまりURLとかだけをデータベースのテーブルの中に格納するのはアンチパターンだって言ってるんですよね。
本当かみたいな気持ちになるんですけど、この章は正直99%の人はノーを唱えるみたいな感じの章だったりするし、
このパターンが編み出された当初はバイナリファイルとかが格納されるのはウェブサーバーそのものだったり、あるいはどこかのファイルサーバーだったり、
どちらにしろ何かオンプレミスの自分たちが管理しているサーバーのどこかで、そこのファイルパスとか、あるいはネットワークファイルパスとかそういったものがデータベースに格納されていて、
それはNGパターンだよっていうのは正直わからなくもない点はあって、
なんですけど、12年経つとっていうより、その前からすでにあったんですけど、12年経つと普通アップロードしたファイルってローカルには置かないよねっていう話になるわけですよね。
アップロードしたファイルっていうのはS3とかGCSみたいなオブジェクトストレージに置きますと。
S3とかGCSのほうが可用性とか信頼性が高いんですよね。
ファイルサーバー、自前のオンプレのファイルサーバーだったら全滅するみたいな可能性もなくはないけれども、
でも外部のオブジェクトストレージ、S3の信頼性ってどのくらいだか知ってるみたいな話になるわけですよね。
これだから外部ファイルの扱いにリスクがあるっていうのはちょっともう時代遅れだと思うんですね。
ただ、このショーが言ってるのは、どちらかというと外部にファイルを置いてそこのURLだけ格納するのがアンチパターンと言いたいわけではなくて、
外部に置いてURLだけデータベースに入れるのが当たり前だと思っていると結構盲点があるよ。
盲目的に普通こうするものだと思い込むのはやめようというアンチパターンになっている。
必須と思い込む。だから物理ファイルの使用を必須と思い込む。
必須と思い込むのほうがアンチパターンだよと言ってて、
必須じゃなくてデータベースに格納できるとするとこういうことができるよっていうので、
簡単に言うとやっぱり強い整合性。ファイルの扱いをトランザクションに含められるっていうのがでかいんですよね。
なので、データベースにコミットされればファイルは存在してるし、
ファイルアップロードしたけどその後処理に失敗してデータベースの扱い、データベースのエリアをロールバックしたら
ファイルだけ残っちゃってる。不整合みたいなことが起こらない。ファイルもなくなるみたいな感じのところ。
データの整合性であるとかバックアップに関する問題とかそういったところを考えなきゃいけませんよ。
Amazon S3が例えばいかに高信頼性のあるストレージだとしても、
強い一貫性がないのであればゴミファイルが残ってしまう。
あるいは不整合な状態に一時的になるっていうことは当然発生しているんだから、
それに対して設計で備えましょうというような考える訓練になってるヒントになってるっていうのが、
ちょっと弁護するとそうでしょうになってるなというふうには思います。
ストアドプロシージャーのアンチパターン
そうですね。やっぱりでもS3的なもののオブジェクトストレージの信頼性みたいなのがもう12年前とは段違いなので、
そこに多少ゴミデータが多少あっても許容できるみたいな話もあるから、
かなりなかなかこういう形にはしないよなっていうのは思いますね。
わかります。
じゃあ他のアンチパターンの話で、ストアドの話ですかね。
そうですね。なのでアンチパターンでなくなったものもあれば、
新たにアンチパターンとして加わったものもあって、
第2版では新しく新規書き下ろしの章っていうのがいくつかあるんですけど、
その中でさっきのアクティブレコードの代わりに入ってきた章がありまして、
それが第25章のスタンダードプレーティングプロセージャーと錆びついた開発標準っていうアンチパターンなんですけど、
これですね、ストアドプロセージャーを使ってビジネスロジックを実装するっていうのは、
アンチパターンなのでやめましょうねというような視点になっていますね。
これももうちょっとメッタ的に見ると、これまでそうしてきたからという理由で技術を採用し続けるのはやめましょうと。
伝統的な企業だとやっぱりストアドプロセージャーでビジネスロジックを実装しているところって結構あったんです。
あったっていうか、たぶんまだいっぱいあると思うんですよね。
これまでそうしてきたからという考えで技術を採用してしまうと、
ストアドプロセージャー自体はやっぱりパフォーマンスとか拡張性とか開発効率とかデプロイメントに関することとかテストに関することとか、
さまざまなやっぱりデメリットがあるので、現代的な構成でアプリケーションを開発しましょう。
なので、これまでずっとストアドプロセージャーで実装してきたから、これからもストアドプロセージャーで実装するみたいな、
そういうまさに錆びついた考え方みたいなところに固執するのはやめましょうねというようなアンチパターンになってます。
そうなんですよね。結構他のところでもありましたけど、
DBAとかデータベース管理者みたいな人が権威的になって、特権的に開発プロセスを無視できるみたいな、
ストアドみたいなのもそういうことになりがちみたいなのは、僕もSI時代とかに感じてたことがあったので、そこも含めていい話だなって思います。
あとやっぱり、これも時代の変化ですよね。
昔はそれこそクラサバモデルみたいな、VBで書かれたクライアントアプリの真後ろにデータベースがいるみたいな場合って、
データベースサーバー自体がロジックを持つっていうことが自然だったわけですよね。
ただ、今はもう僕らはそんな発想はなくなって、データベースの前にアプリケーションサーバーがいて、
そこがロジックを持って、ちゃんとフロントに返していくっていうモデルになっていくので、
データベースはより純粋にデータの入れ物として使いましょうっていう形になってきてるっていうところがあるのかなっていうのは思いました。
おっしゃる通りですね。
ちなみにトリガーとかについて書かれてたところってあった?
トリガーはですね、この本ではそんなに言及はなくて、
トリガーのドキュメントを書きましょうねとか、
トリガーもちゃんとテストしましょうねみたいなところで少し言及されていて、
トリガーそのものはアンチパターン扱いまではされていないんですけど、
ストアドプロセージャーとかストアドファンクションがアンチパターン扱いに近くなっているので、
トリガーもある程度それに準じるというところはあるかなとは思います。
そうですよね。ただ結構節度を使って使うみたいなのが大事なのかなと僕は思っていて、
僕としてはクリエイティッドアッドとかアップデートアッドみたいなのはトリガーに入れさせてしまうのがいいんじゃないかなと思っていて、
ただそれをアプリケーションから参照しないみたいにするのが設計としてはいいんじゃないかなっていうのを個人的に思ってるんですよね。
トリガーが生成した情報をアプリケーションが依存し出しちゃうと結構危ないかなっていうのを思ったりします。
クローコーとか裏型に留めておきたいっていう感じですよね。
あとこの本って今時っていうとあれですけど結構MySQLに寄った本ですよね。
それこそ12年前とかだと日本のウェブ開発界隈ってかなりMySQLが活発だったと思いますけど、
近年は僕もMySQLじゃなくてPostgreSQLを触ることの方が結構増えてきていて、
結構MySQLのことが載ってて、なんかすごく懐かしい気持ちになったりとか、
あと途中に書かれてるミニアンチパターンのとこにポータブルSQLっていうのがあって、
もうSQLの過半生みたいなのを求めるのはもう諦めろみたいなことが書いてあって、結構重み深いなって思ったりしました。
そうですね。この本の原著者のビル・カーウィンさんってMySQLのエキスパートなんですよね。
もともとペルコナっていうMySQLのツール、PTなんとかシリーズっていろいろMySQL使いなら知っている便利ツールたちがあるんですけど、
MySQLの独自性とアンチパターン
そのペルコナのコンサルタントとかをやっていた人でもMySQLゴリゴリのエキスパートなので、
本の中も、初版もそうですし、第2版もMySQLに特化した内容っていうのもいくつか出てきたりしていて、
なので官躍者として結構そこに対して官躍注を入れてるっていうところもあります。
アップデート文の評価の順番みたいなものとかって、MySQLと例えばPostgreSQLとかDB2とかとは異なるみたいなところがあって、
MySQLだけ非標準的な動きをするみたいな箇所っていうのも結構あったり、いまだにあったりするんですよね。
そういったところをMySQL側の記述になったりするので、ちょっと客注でいくつか入れたいみたいなのもありますし、
標準SQLを軸足にして書かれてる本なんですけど、やっぱりMySQLの匂いみたいなのがそこかしこに香るみたいな感じの本にはなってると思います。
そうですよね。ちょっと面白いなと思って。
外部キーに関して結構丁寧に解説されてる章とかもあって、あれいいなって思ったんですけど、結構MySQLはこうしないといけないみたいな、
リファレンスをカラムにリファレンス設定するとうまく動かないバグがあるのでこう書きましょうみたいなのが書いてあって、ちゃんとバグのURLも書かれていて面白いなって思いました。
あとそうですね、あとちょっと話をしたいのが、やっぱりそのIDリクワイヤードパターン、これも結構物議を醸すパターンだと思うし、
割と現実的に柔らかく書かれてるところではあると思うんですけど、やっぱり手記設定がすごく難しいよねっていうのは思うところではあるんですよね。
やっぱその手記って実はイミュータブルであるっていうことも結構運用の面では大事だと思っているので、そういう意味では無機質で変わらないものをIDとしたいので、
そうするとナチュラルキーだとどうしても限界があるよなっていうのは思ったりはしてます。
そうですよね。これなのでリレーショナルデータベースの設計者の流派の、なんていうかリレーショナルデータベースの設計って割と強い意見があったり意見の対策があったりとか流儀があったりするんですけど、
プライマリーキーの設計ってものすごく設計者の流派性とか流派性みたいなやつが出るところで、
サロゲートキーによる、つまり自動裁判される機械裁判される自然界には存在しないID列みたいなもののみを使う人もいれば、
そうじゃなくて全てのエンティティには何らかのナチュラルキー、自然キーがあるはずであると、それをプライマリーキーに使うべきであるっていう人もいたり、
複合主キーっていうのをアリとする人もいれば、複合主キーの場合はサロゲートキーをプライマリーキーにしようみたいな派閥の人もいたりして、
なんかいろいろよく揉めるんですよね。
で、著者のビル・カーウィンさんはどちらかというとナチュラルキー派って言えばいいんですかね。
ナチュラルキーがある場合にはナチュラルキーにしましょう。
ただこの本の現実的なところというかいいところは、徹底して割と思考停止みたいなものを誘めているところで、
このID Requiredっていう章もサロゲートキーを批判しているかというと別にそうではないんですね。
じゃなくて全てのテーブルに盲目的にIDという名前のサロゲートキー列を設けて、それをプライマリーキーとして運用するっていうのはやめましょうと言ってて、
例えば機械的な交差テーブルにはそういったサロゲートキー必要ないし、よりふさわしいナチュラルキーがあるんだったらそちらを使った方がいいし、
そもそもカラムの名前としてIDっていう名前を固定にするのではなくて、
例えばバグステーブルだったらバグIDにしましょうとか、イシューステーブルだったらイシューIDにしましょうみたいな命名規約の観点というのも述べていて、
これも正直開発生産性とディレイショナルデータベースとしての意図の明快さとのトレードオフになるので、まあ揉めるところなんですよね。
例えばRuby on Railsは全てのテーブルのプライマリーキーをIDという名前に決め打ちすれば設定を書かなくてよいよというコンベンションオーバーコンフィグレーションですよね。
設定より規約という考え方によって開発生産性を飛躍的に上げたわけですけど、それ自身をビルカーインは批判しているわけですね。
IDというカラム名に決め打ちしたことでプログラムの開発生産性は高くなったんだけど、
そこから離れてリレーショナルデータベースのテーブル設計、エンティティの設計として見たときに、
このIDという列は果たしてわかりやすいですかとか、そういった形になってくるんですよね。
あとは12年経ってリレーショナルデータベースの中のデータって、12年前ももうだいぶ起き始めてるんですけど、
データエンジニアリングっていうのが大幅に進んだので、リレーショナルデータベースって全システムの中のデータを1点に引き受ける存在ではもう全然なくなったんですよね。
昔はリレーショナルデータベースっていうのが全てのシステムの真ん中にデンと備えていて、
全てのデータをリレーショナルデータベースの中で扱っていたみたいな時代もあったんですけど、
今やリレーショナルデータベースってでもなくなるわけではなくて、明らかにデータストレージとしては第一候補なんですけど、
巨大なリレーショナルデータベースにいろんなシステムがつなぎにいくっていうのはむしろ最近だとアンチパターンになっていて、
どちらかというとある程度ドメインで区切られたシステムがあって、それらのシステムが自分のリレーショナルデータベースにアクセスすると。
リレーショナルデータベースは中央に1つ存在するんじゃなくて、数はそんなに多くないけど意味のある区切りごとにリレーショナルデータベースが存在するというような時代になってきています。
人によってはそれをマイクロサービスと呼ぶでしょう。そうするとマイクロサービスごとにリレーショナルデータベースが1個ずつ存在するみたいな感じになります。
そうすると何が起こるかというと、分析系のデータを集約するときにさまざまなリレーショナルデータベースからデータを持ってきて分析系データベースに入れるとかデータエンジニアリングするみたいな形になるんですけど、
そうすると元のリレーショナルデータベースの文脈を離れてカラム名とデータがやってくるみたいな形になるので、
全てのテーブルのプライマリーキーの名前がIDだと本当に分からなくなりますよね。
どのIDだ、どこからやってきたIDというカラムなのかなっていうのが、これ分析系データエンジニアリングの文脈になると
プライマリーキーの名前が全部一緒だと結構なレベルの混乱になるということが言われていて、
これアプリケーションの開発生産性とデータエンジニアリングの観点での明快さというものが一種トレードオフの関係になっているのかなというのがあるんですよね。
リレーショナルデータベースの現状と命名規約
その辺もやっぱり12年経つと結構変わってきているなというふうに思います。
そうですね。そういう複数のアプリケーションから参照される中央集権的なデータベースみたいなのは少なくとも、
それについてはもうアプリケーション開発上のアンチパターンとされるようにはなったのは間違いないですしね。
マイクロサービスで分けるかどうかともかくとしてっていうのはありますよね。
ただ、IDの名前がIDになってる。
でもまあ大丈夫なのか。でもそうですよね。
僕もちゃんとユーザーテーブルはユーザーIDを主キーにしましょうみたいになってるので、すごくメイクセンスだなと思っていて。
ただそれをフォローするフレームワークがないから結局そのIDが使われてしまっているっていうのがあって、
結構実はこのルールを踏襲するフレームワークがあるのがいいんじゃないかっていうふうに思ったことはありますね。
そうですよね。
もともと僕もユーザーズドットユーザーIDとか書くのまどろっこしいじゃんとか思ってたけど、
例えばデータを他のテーブルに移し替えるときとか、そういったことが発生するときとかだったりとか、
あとユージンググが使えるっていう、この本で押されてるユージンググ、僕もこの本で知ったんですけど、ユージンググが使えるみたいなメリットがあるから。
確かに実はそういうテーブル名の単数系-IDを主キーにするっていうのが実は理にかなってるんじゃないかなっていうのを僕もすごくそれは思ってますね。
ただやっぱりそれを踏襲するフレームワークがないからみんなそれができないっていう部分がすごくあるなっていうのを思ってるし、
多分それをオレオレフレームワークとかでやりだしても誰も見向きもしないだろうし、
むしろ他のところとのコンベンションとコンフリックとして塞いになるだろうなっていうのがあるからここは難しいところだなって思いますね。
そうですね。
ちなみにこの本だとサロゲートキーって使われてなくて疑似キーって訳出されてるように思ったんですが、そこはどういう理由があるんですか。
サロゲートキー、カタカナでなくてって話ですよね。
疑似キー自体はある程度、そもそもシュードキーの役を疑似キーにしていて、サロゲートキーの役を代理キーにしてるんですけど、
原文がそもそもわりとシュードキーって書かれているというところもあって、
わりと語彙として、著者の好む名前ってことですよね。
僕たちが使っている語彙とは違う方を選んでいる箇所がいくつかあって、そのあたりは客中で補ったりしています。
例えば、私たちよくUUIDというものを使うんですけど、この本の中ではGUIDって書かれています。グローバルユニークアイデンティファイアって書かれていて、
ここでいうGUIDっていうのは、我々よく言うところのUUIDのことだよと。
UUIDっていうのはRFCだと9562で定義されてるよみたいな感じの客中を当てたりしているので、
その辺は多分、原著者の語彙の選択みたいなところはあると思います。
なるほど、そういうのがあるっていうことなんですね。
そう、UUIDの話ちょっとしたくて、これもミニアンチパターンっていう項目があって、
ビッグイントは十分に大きいっていうミニアンチパターンが載ってて、
これは結論としてはもう十分に大きいから心配すんなっていうことが書いてあるんですけど、
結構そうかって思うことがあって、それこそ最近だとUUIDを主キーに使ってる設計ってすごく増えてきてるなっていうのを思っていて、
イント128的なものは欲しくなることが増えてきてるし、
そのUUIDを主キーにするとフレームワークが対応してないから困るなみたいなのが結構増えてきてるような感じがするんですけど、
この辺りって何か思ってることはありますか?
プライマリキーの選択とその考察
そうですよね。UUIDをプライマリキーにする話とかって、この本の中ではあんまり出てこない。時々チラッと出てくるんですけど、
連番の決番が気になってしまって、連番を詰めてしまうっていうアンチパターンが出てくるんですけど、
シュードキーニットフリークっていう章が出てくるんですけど、連番だから空きが気になってしまうので、
それだったらUUID使えよみたいなソリューションも一つに出てくるんですけど、そういった側面で出てくるだけであって、
現在のシステムアーキテクチャの設計のところで、そもそもプライマリキーをUUIDにするといいんじゃないので、
そのUIDにちょうどいいデータ型っていうのは何だろうかみたいな議論までは、この本の中ではあんまり出てこないんですね。
さっき話題に挙がったビッグイントは十分に大きいっていうコラムも、大きいっていうのは何のことかっていうと、値が枯渇する心配はありませんよっていう意味なんですよね。
データ型として大きい小さいの話ではなくて、大体インテージャー型だと枯渇するんじゃないのみたいな心配があって、
実際にTwitterは枯渇しますよね。Twitterはインテージャーでプライマリキーが設計されていて、インテージャーが枯渇したみたいな感じの旧Twitterですけど、
ありましたみたいなところがあって、じゃあビッグイント型にしましょうって。ビッグイント型もどうせ枯渇するんじゃないのみたいな感じの心配症に対して、
いやビッグイントは正直枯渇しないですよと。同じスピードで消費されるとしたら17億年かかりますよ、枯渇するまでにみたいなそんな感じのことが書かれてるんですけど、
いやいや、現代の我々ビッグイントで連番にするか否かじゃなくて、ビッグイントで連番にするかあるいはUUIDにするか。
UUIDにする場合のトレードオフ、データのアクセスに関するストレージの観点での最適化っていうのが有利か不利かみたいなそういったところでいろいろ話をしたりしてるし、
そもそも最近のデータベースのプライマリキーのオプションとしてもうUIとか出てきているしなみたいなそういう議論になるんですよね。
なのでこの本ではそこまでは踏み込んでいないっていうのが正直なところですね。
そうですよね。エポックとかそういう連番みたいなものを前提とすればビッグイントで十分大きいし、みんなうっかりインテジャーを32ビットイント主機にして21億とか42億でギャーってなったっていうのは、
まあ結構大きくしてきた人はいるのかなって思うんですけど、まあ確かにそれに比べたら全然大丈夫ではあるんですけど、僕は結構IDの流儀はちょっと特殊な流儀なんですけど、僕はそのスノーフレークIDっていうのを使うのが好きなんですよ。
で、これはさっきティーワダさんがおっしゃってたTwitterが32ビットイントで枯渇したときにじゃあどうするかみたいなときに考え出されたようなアイデアなんですけど、まあこれは分散裁判機みたいなそういう裁判機に裁判させてそれをIDとして使いましょうみたいなモデルで、
で、結構やっぱり裁判機みたいなものをデータベースの外に置いてIDを裁判するのって、実はアプリケーションとデータベースを切り離す上ですごく実は大事だったりするわけじゃないですか。なので、リトライとかも考えると、なんかインサートしてからじゃないとIDが確定しないみたいなのじゃなくて、もうそのエンティティを作るときにすでにもう事前にIDが決まっているっていうことの大事さみたいなのがあって、
そういう意味でやっぱ裁判機を使うっていうのが結構一つのパターンとしてあるなっていうふうに思っている。で、ただその裁判機を結構ちゃんと分散させてうまくやっていこうってすると、その裁判機の番号だったりとか、まあそういういろいろな制約が出てくるので、64ビットをフルでそのデータ領域に使うことができないという話があり、
で、このスノーフレークIDっていう、もうちょっとスノーフレークって言うともう、最近だとデータストアのストアスノーフレークのことばっかりみんな思っちゃうんですけど、このツイッタースノーフレークIDっていうのがあって、これさっきちょっと調べたら、それこそやっぱインスタグラムとかディスコードとかでもやっぱ使われてる、類似のやり方が使われてるらしいし、
まあ僕がこれ使ってたのは、特にマカレルっていうサービスなんですけど、マカレルっていうサービスの中でもまだ使われてて、てかその、なんていうか、もともとツイッターってスノーフレークのライブラリを公開してたんですけど、それをもうアーカイブしちゃったんで、そのライブラリを一番、今世界で一番アクティブにメンテナンスしてるのはマカレルチームの人たちだったりするみたいなのがあるんですが、
まあちょっとだいぶ話が長くなっちゃったんですけど、で、でもこのツイッタースノーフレークIDって、そのタイムスタンプ部分が41ビットしかないんですよね。64ビットの中の41ビットをタイムスタンプに当てるっていう形になってて、で、これディスコードとかもそうなってるらしいんですけど、ただ41ビットでミリ秒を入れるっていう作りになってるので、そうすると全然持たないんですよね。
70年しか持たないっていうのがあるので、そうすると、実は結構そういうタイムスタンプベースの64ビットのなんかその1位である程度順番が保たれたIDを発売するっていう時に、実は結構64ビット足りない決定版が実はあんまりないっていうのがあるよなって思っていて、やっぱりそうすると素直にUUIDを使うのがいいんじゃないのかなっていうのを最近こう、
正規化の重要性
結構思ってるみたいなのがあります。
そうですよね。最近プライマリキュー政権なので、それこそUUIDとか、いわゆるULIDというやつとか、そのあたりがいろいろ候補に入るようになってきてまして、さっきおっしゃってたようにIDの確定自体がデータベースから分離できる、そのIDの裁判自体はデータベースから独立して、かつ分散して行うことができるというところですとか、
あとIDの裁判がスイケンスだと、どう考えてもそこが本当のハイトラフィック環境だとボトルネックになってしまうんですよね。裁判のために一列に並ぶって形になってしまうので、
原理上重ならない番号というものを分散環境で裁判できるほうが分散システムとしては有利っていうところがあるので、やっぱり大規模システムとかのプライマリキューを裁判するという観点だと分散裁判機っていうのがやっぱり一般的になってきてるなというふうに思います。
おだしょー ありがとうございます。そうですよね。なのでちょっとここはまだみんな悩んでるところなんだろうなっていうのを思いますね。あとそうですね、正規化のルールの話がこの本に載ってるっていうのが熱いっていうことを岡田さんが主張されてて、これは実際すごい熱いなって思いました。
やっぱりその最後に載ってるし結構簡潔にまとめられてるのに加えて、なんかそう、このパターンは、EAVパターンはこの正規化に違反してるんだみたいなことが結構そういう具体例含めて載ってるからめちゃくちゃ理解しやすい内容になってるなって思いました。
そうですよね。なのでこのフロクA、正規化のルールっていうところは、第一正規系、第二正規系、第三正規化系とか正規化のルールってなんとなく我々実務でなんとなく学んでいくみたいなところが多くって、かつちゃんと学ぼうとすると今度は割と数学っぽい本を読むことになってしまったりとか、
そんな感じになってしまって、ちょうどいいレベル感の正規化のルールの文章ってあんまりないんですけど、この本のフロクAの正規化のルールってちょうどいいぐらいのアカデミックさとちょうどいいぐらいの実例みたいな形になっていて、
この本の翻訳レビューの社内読書会みたいなカルタホールディングスでやっていたんですけど、実は一番評判がいい部分の一つがこのフロクAの正規化のルールだったと思います。
ちゃんと学んだことないとか、ちゃんと学びたい時にちょうどいいみたいなレベル感みたいなところの意見があったりして、ぜひこの本手に取った人はフロクAまで読んでみてくださいという感じです。
そうですよね。正規化、実は結構あやふやだったりとか、実験の叩き上げのエンジニアとかでも実はあんまりよく知らなかったりみたいなことが結構あるんだなっていうのは、僕もハテナ社とかに入ったときに、やっぱり結構すごい優秀なシニアなエンジニアの方でもそこがあやふやだったりして、
僕はSIのときとかにデータベーススペシャリストとか勉強したりしたから、多少は分かってる部分があったので、ちゃんとやっておくことで大事だなって思いますし、ちゃんとやることで実はそれがパフォーマンスとトレードオフにならないっていうか、むしろ拡張性とかそういったところ含めて実はやりやすくなるんだよっていうことが書かれてるのがすごい良いなって思いました。
論理削除の議論
そうですね。こんなとこかな。じゃあちょっと最後に一個だけ軽く話すと、最近全然別の文脈で論理削除が盛り上がっていて、僕もちょっと盛り上げに一役かかってしまってるんですが、良くも悪くも。
以前、この話って結構T和田さんが終止符を打ったと僕は思っていて、それこそ昔の発表とかだと、SQLアンチパターンに絡めて幻の第26章をとりあえず削除不落っていうのを書かれているので、
なんていうか、結構T和田さんがこの間のイベントでおっしゃってたこととして、パターンとして認識されることが大事だから、あえてパターン名はカタカナにしたみたいなことをおっしゃってたと思うんですよね。
だから、それこそ削除不落とか論理削除みたいなものがアンチパターンとして認識されてればいいんだけど、どうもある意味テクニックのように受け取られてるから、それを使ってしまう人が後を絶たないと思っていて、これは結構悲しいことだなって個人的に思っています。
そうですよね。なので、なんか再び削除不落の議論っていうのは、また取り立たされる時代なのかみたいな、結構時代が1週2週ぐらいしたなみたいな考えがあったりするんですけど、確かにちょっと一昔前に総まとめして資料にしたり、
ポッドキャストで喋ったりみたいな感じで、論理削除っていうことはまた結構定義に揺れがあったりするんですけど、いわゆる削除フラグ、is deletedみたいなブーリアンのフラグを設けることによって、論理削除と言われる機能を実現しようとするっていうのは、これはもうアンチパターンだよっていうのは、
もうさすがにそういう常識になってほしいなっていうところはあって、なのでいくつか資料まとめたりみたいな感じはあるんですけど、いまだにやっぱり全部のテーブルに削除フラグを設けるみたいな規約すらあったりとかするので、まだまだたくさん出回ってるので、削除フラグを使わない設計イコール物理削除するって意味ではないので、
そもそも論理削除に関する議論が誤った二文法で語られてること多いですよね。だから論理削除ダメって言ったら物理削除しろってことですかみたいな感じになってしまって、そうじゃないんだよっていうその設計で解決するんだよっていうところをもっと伝えていかないとならないので、
論理削除っていう言葉がドメインにあなたの業務の言葉にありますかっていうと、ないっすよねって話になるんですよね。それがだから論理削除って言われてるものが大会であったりとか、公読の会場であったりとか、何らかの例えば関係性の消失を意味するのだったら関係性の消失としてイベントとしてモデリングすればいいしみたいな感じの、つまりちゃんと設計をやると論理削除とか削除フラグってやつは
次第になくなっていくし、それは物理削除を使うということは意味しないよというのをもっとやっぱりちゃんと伝えていかなきゃいけないし、だからやっぱり言い続けなきゃいけないんですよね。総代さんもそうだし私もそうだし、昔終わった議論だみたいな感じにするんじゃなくて、やっぱり丁寧に説明をしていくっていうのはやっぱり2週3週して必要だなーってのをちょっとここ数日思いましたね。
アンチパターンとしてやっぱり意識されるべきっていうことですよね。
そうですね。だから名前をつけるっていうのが大事ですよね。アンチパターンだよっていう形で、つまりとりあえず削除フラグってとりあえずビールみたいな感覚でつけたんですけど、とにかく削除フラグっていうのは全部のテーブルにつけるもんだよみたいなのは、やっぱりとりあえずIDがアンチパターンであるのと同じくとりあえず削除フラグっていうのもアンチパターンだよっていう形で伝えていければというふうに思います。
もう一つあって、削除フラグよりもっとひどいというか困るのが、Deleted Atをぬらぶるで追加するっていうパターンも結構やられがちっていうのがあって、そうするともうぬらぶるなカラムでインデックスが聞きづらいものに対してさらに意味を持たせるみたいになるから、もうやめてくれみたいになるんですよね。
だから削除フラグっていうのとDeleted Atみたいな、そういう削除のためのマークのための絡みを持たせるっていうことが結構危ないなって思ったりしてます。
そんなところですかね。よかった。だいぶお話できてよかったです。
そうですね。よかった。
じゃあまたぜひ飲みに行ったりしましょうということで。
ぜひよろしくお願いします。
今日はありがとうございました。
ありがとうございました。
54:30

コメント

スクロール