MySQLユーザーがPostgreSQLを触ってみて驚いたことをゆるく書く
ゆるく書く
約6年くらいずっとRDBMSはMySQLを使ってきてたけど、Postgresを触る機会があって「すげー!こんな機能MySQLにも欲しかった!」と思った機能をMySQL onlyなユーザー向けにどういうものかを健忘録も含めて書いてみる
MySQLのシンプルさに慣れてしまっているのでOracleDBとか使ったら高機能さに目ん玉飛び出るんじゃないかと思うのでいつか使ってみたい
RLS (Row Level Security)
今回のPJでポスグレを採用した理由でもあるRLS DBレベルでよりセキュアに設計できるので安心感がある
CREATE TABLE accounts (manager text, company text, contact_email text); ALTER TABLE accounts ENABLE ROW LEVEL SECURITY; CREATE POLICY account_managers ON accounts USING (manager = current_user);
where句でmanagerカラムを指定しなくても、自分のものしか返ってこなくなる。 selectだけではなくinsert/update/deleteでも使えたりユーザーごとにバイパスもできたり、POLICYの張り方も自由度が高くて思ったより使いやすかった。
よく使われるのはSaaSマルチテナントとかDBやスキーマを分けずに実現できるから愛されてそう。 設計の熟練度や仕方にもよると思うのだけど自分のプロダクトの場合どのように接続ユーザーを仕切るかも考えさせられた。 あとはアプリケーション側で基本的にRW権限を持つほぼadminみたいなユーザーでしかDBアクセスしてなかったからその辺のユーザーの切り替え方とか勉強になった。
マテリアライズドビュー
MySQLにもビューはあるけどマテリアライズとかいうFFっぽい名前がついたこれはMySQLでも存在するビューがキャッシュ付きで実現できるというもの
CREATE MATERIALIZED VIEW user_summary AS SELECT user_id, COUNT(*) AS order_count FROM orders GROUP BY user_id;
みたいな感じでビューを作るクエリを実行したらその時点の結果がキャッシュされて、selectするとCREATE MATERIALIZED VIEW実行時の結果が返ってくる。最新化したい場合はREFRESH MATERIALIZED VIEWでリフレッシュ可能
REFRESH MATERIALIZED VIEW user_summary;
重いクエリでリアルタイム性の低いものとかダッシュボードとかランキングとかめちゃくちゃ使えそう。MySQLでやろうとするとクエリを実行した後に結果をredisに入れておくとか別テーブルに保存しておくとかする必要があるので、ポスグレは便利だなぁと思った
Returning句
DMLの出力結果を自由に返せる機能
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com') RETURNING id, name, email, created_at;
INSERT時にオートインクリメントで採番したidも返せるし
UPDATE users SET last_login = NOW() WHERE email = 'alice@example.com' RETURNING id, name, last_login;
whereで絞ったレコード達の情報も返せる(本番とかでやるならもちろん事前にselectしたレコードを確認しないと怖いけど)
postgres 18ではupdate前(old)と後(new)も返せる最高の機能がリリースされた模様
update hoge set value = 'bbb' where id = 1 returning old.*, new.*;
アプリケーション側でoldの情報が必要な場合、変数に入れておくみたいなロジックがいらなくなるのはすごい嬉しい
ARRAY型
配列をサポートしているのでtextカラムに"1, 10, 15"みたいなゴリゴリアンチパターンなジェイウォークが入ってくることが無くなる
とはいえ闇雲に配列にすることが良いかというとそうでもない気がしていてtextカラムで配列を複数レコードにするとか正規化するとかその辺はちゃんと設計する必要がありそう。場合によっては配列型で持っちゃうことがアンチパターンになってしまう場合もありそう、劇薬だ。
まとめ
postgreは高機能でカスタマイズ性も高くて使いがいがあるなぁと思った。 でも初めて触ったRDBMSがMySQLでよかったと思っている(本当はSQLiteだけどローカルでしか使ってないから無視!) MacのOSをアップデートするたびにUIがおかしくなるMySQL Workbenchも含めて愛している。基本的なRDBMSの機能としては一緒だし、スピード感持って開発を進められたり挫折せずに学び続けてこれたのはMySQLのおかげ。要件やプロダクト規模によってはそうはいかなかっただろうから恵まれていたと思う。
今、開発チームが崩壊しようとしている①
今、開発チームが崩壊しようとしている。
退職者が相次ぎ、開発スピードが下がりチームの士気が下がっているの肌で感じている。
まず簡単に今のチーム構成の紹介をする。
EM… 1人
フロントエンド… 3人
バックエンド… 3人
フロントエンドは既に3人退職し、バックエンドは1人退職している。
そして今月末でバックエンドの一人が退職し2人になる。
退職が相次いでいる原因は明確であり、EMのハラスメントによるものである。
理由を決めつけていいのかと思うが、退職する本人から理由を聞いたり、又聞きで聞いたり近くで見ていても退職するのもが納得できるので断言している。
さらに自分も含めて退職検討者が数名出ている状況なので、(既に始まっているけど)崩壊は時間の問題だと思う。
チームの崩壊について、何ができたのだろうか・何が原因なのだろうかというと考えてみようと思う。
この記事では自分の感じたことと反省を書こうと思う。次の記事で会社ができたこと・やるべきだったこと再発防止案を書こうと思う。
何が起きているのか
問題のEMが入社したのは2.5年ほど前だった。
最初の方は今に比べるとハラスメントな感じはなかったが、少し違和感は初めから覚えていた。
- 会社や上長に対する愚痴が多い、それを部下にこぼしている
- コミュニケーションの取り方がおかしい、どこかキレている
この頃はまあそういう特性の人なんだなくらいにしか思っていなかったが、プロジェクトが忙しくなるにつれ徐々に違和感が大きくなる。
ハラスメント面
- 他メンバーの前で特定のメンバーの叱責
- 酷すぎるハラスメント発言・行動(退職者本人から聞いたときは、人としてドン引きするくらい)
仕事面
- 権限移譲ができない、マイクロマネジメント気質
- 他責思考、部下に丸投げしたり他部署のせいにして悪口を言う
- 部下の気に食わない行動にはキレる
- メンバー同士で雑談に近いコミュニケーションをとっているとキレる(開発に集中しろという意味)
- 声が小さいとキレる
個人的にはハラスメントも問題だと思うが、仕事の進め方がおかしいと感じている。
特に、雑談に近いコミュニケーションがEMの前では取れないのでチームの仲も良くなりづらかった。
権限移譲を認めず自己組織化できないため、何をするにも細かくEMの確認が必要であるが、失敗すると叱責されたり本人の正義を押し付けられるため報連相がしづらい環境になっている。
↓
チームとしてうまくいかなくなり、よりハラスメントが強くなる。
そんな悪循環に陥って精神を病んでしまうメンバーが多発している。
人事の介入
退職者の一人が、別のマネージャーに受けたハラスメントを相談してCEOや人事にまで話が回った。
自分も参考人として事情聴取があったので、何人もEMが原因で退職が出ている・退職検討者がいることやハラスメントの事実や見ていて感じたことを話した。
対応処置としては本人への厳重注意と反省文を書かせるとか、人事が定期的に面談するとかだった。
自分も退職するかもしれない旨(選考を受けている)を伝えた。
すぐには良くならないが、ちゃんと人事が見ている点や他部署に移らないかと打診を受けた。
しかし、以下の点からこれは会社の崩壊であり、これ以上この会社にいても仕方ないと思った。
- 50歳近い人間が厳重注意と反省文で変わるとは思えない点
- ハラスメントだけならともかく仕事のやり方でエンジニア・PdM・CSからクレームが入っている点
- 既に退職者が多数出ていて会社へのマイナス影響がでかい点(0に戻すまでに時間がかかる)
何ができたのか
今までハラスメントを受けたことがなく、自分は少し麻痺しているところがあったと後から振り返ると思った。
やばい上司だけどまあそういう人もいるのか、退職してしまう人もいるけどそういうもんか。とあまり危機感を持てずにいた。
ただ人事や退職者や退職検討者と話していてこれは大きな問題だと改めて考えさせられた。
もしかしたら薄々感じていたけど、声を上げられなかったのかもしれない。人事や他の上長に相談するという選択肢がなかった。
そういった意味で社内で普段から信頼できるコネクションを持っておいた方がいいと感じた。
- 気軽に1on1に誘える別チームのEM
- 気軽に相談できる人事
などがいたら崩壊前に何か防げたのかもしれない。
また、退職するくらい病んでしまったメンバーをもっと気にかけてあげればよかったと思った。
今回退職するメンバーとは一度二人でランチに行ったときにハラスメントの話になって色々聞いて転職は検討しないのか?ということを聞いたことがあった。ここで、人事に相談してみないか?という選択肢が無かったことに今振り返って気づいたが、理由は2つあると思う。
- 人事との間で上で書いたような信頼関係がない。
- 相談しても無駄なのではと思ってしまっていた。学習性無気力感に近い。ハラスメントによって抑圧されていたのかもしれない。
今回退職される方は比較的メンタルが強い方なので、僕の前では明るく振る舞っていたので気づけなかったが後から聞いてみたら相当なハラスメントを受けていた。許せない。
本当に大丈夫なのだろうかと考えるクリティカルシンキングが足りてなかったのかもしれない。
- 「信頼できる人事・上長とのコネクションを持っておくべき」
- 「異常を感じたら声を上げることの大切さ」
- 「ハラスメントを個人問題ではなく組織課題として扱う必要性」
を学んだ、もしこの駄文を見ている人がいて、異変を感じていたら自ら動いてみてほしいなと思った。
ただ、僕も一度経験したので今度同じようなことがあった場合はもっとアグレッシブに戦えると思う。
悪と真っ向から立ち向かおう。
削除フラグ、あかん
失敗から学ぶRDBの正しい歩き方という本を読んだり、一時期Xで話題になっていた削除フラグの件を見たりで削除フラグについて考えることがあった。
今自分が担当しているサービスでも、当たり前に削除フラグを使っていて当たり前に負債になっている気がする。もっと問題なのは誰もその負債に気づかず(気づいていても声を上げないのかもしれないが)運用や実装でカバーしていることだと思う。
設計を見直せば今後が楽になるがそこに目がいかない、設計を変えるとなると工数が大きいのが問題であり、そこに対してリソースを割くことに対して上層部の理解がない・説得できるだけの信頼がないのがまた問題だと感じる。
何があかんのか
「失敗から学ぶRDBの正しい歩き方」の受け売りだと以下のような問題がある。
- クエリの複雑化
- UNIQUE制約が使えない
- カーディナリティが低くなる
詳しい説明はぜひ本を買って読んでみてほしい。
すべてウルトラアグリーできるし、実際問題になっている。
クエリの複雑化
複雑化はもちろんで、自分漏れが生まれるのがは怖く感じる。
とあるクエリではしっかり削除されているユーザーのみ絞り込まれているが、とあるクエリではその絞り込みがされておらず削除済みユーザーに対してメールを送ってしまったなど考えただけで胸がキュッとなる。
その問題があることを前提にレビューをするのも観点が増えて負担になる。
UNIQUE制約が使えない
自分の担当しているサービスの場合、UNIQUE制限を使ってしまっている。
そうすると何が起きるかというと退会後に再登録ができないという問題が発生する。
toB向けサービスなので基本的発生しないという要件定義フェーズでの合意のもと実装されているが、そんなことは捕らぬ狸の皮算用であり実際様々な理由で発生している。
カーディナリティが低くなる
削除フラグがインデックス戦略にも影響してしまう。
これのために複合インデックスを貼る必要が出てしまう。
どうすればいいのか
冒頭で紹介したXのポストの通り、削除済みユーザーテーブルを用意しユーザーテーブルのDELETEが走るときにトリガーでINSERTをするやり方が綺麗に感じる。
どうしていけばいいのか
チームに今のテーブル状態の問題を理解してもらい、テーブル設計・アプリケーションの実装を修正していく必要がある。
(気づいてないだけかもしれないが)実際今のサービスの状況において、テーブルを分割することによるデメリットが見当たらない。やりたい。
当初の設計は良くなかったのか
先日、とある会社の統括部長さんとお話しすることがあり、設計ミスったぁという上記の話をすることがあった。
部長さんは「(退会後の再登録の考慮とか)MVPには必要なくない?」とおっしゃっていた。
確かに、その通りではあると思うし自分もその考え方には賛成である。それ今考える必要ある?とかユーザーいないのに何を懸念しているんだろうと思うことが多々ある。
とはいえ現状困っているのは事実なので、どうするのが良かったのか考えるとしっかりビジネスを理解する必要があったと思う。事業として少し見切り発車な部分があったがもう少し業務フローや顧客の課題やシチュエーションを引き出せると多少考慮ができて設計にも活きてきたのかもしれない。
反省や学びがあって良い経験にはなった。