この記事について
- システム開発するうえで絶対に避けては通れないユーザ情報周りの設計を自分なりに考察してみた
- 結局何が最適かわからないけど色々と考え出すと奥が深かった
きっかけ的な
Railsでアプリ作ったんだけど、bootstrapとかdeviseとか使って横着したので、正直やった感ないなーって思いました。HTML/CSS多少勉強しなおして、あとこの本読んで、もう一回横着しないでなんちゃってQiitaみたいななんちゃってメディアシステムみたいなの作ろうかなと。そうなると、当然ユーザ情報の設計とか考えなきゃなんですが、いろいろ考えたら奥が深かったのでQiitaに載せて整理しようかなーって思いました。あと、ここに公開すればありがたいお言葉を頂戴いただけるのではないかとか思ったり。
本記事のユーザ情報の定義
利用用途
- ログイン認証に用いる。
- サインアップ画面より、新規登録をユーザ自身で可能とする。
- ユーザによるプロフィール編集を可能とする。
- プロフィールは他ユーザにより、CMS上のある画面から一覧表示できる。また、個別のユーザはユーザ名で検索可能とする。
- プロフィール詳細はほかユーザにより、CMS上のある画面から確認可能とする。
- ユーザ削除時は、ログイン情報も含めてすべて物理削除する
項目定義
- 一意のログインID、パスワードをもつ。また、最終ログイン日時を保持する。
- CMS内で利用される一意のユーザ名を保持する。
- 上記ユーザ名とは別でユーザの氏名、氏名カナを保持する。ユーザの氏名、氏名カナは他ユーザは見れないものとする。
- ユーザ登録時や運営お知らせに利用するためのメールアドレスを保持する。
- プロフィール情報として年齢、誕生日、自由記述欄を保持する。
私の設計
こうなりました。詳細は追ってですが、この後簡単に思考プロセスを書いていきます。なお、簡単にするため、インデックスどうするとかは一旦考えません。
テーブルにどう持たせるか
まあ単純に考えるとusersテーブルにえいやって全項目突っ込みたくなりますよね。こんな感じです。
別に個人で勉強用途に使う程度ならこれでいいんですが、ある程度ユーザ増えるという前提で考えると、ユーザに関する全操作のたびにテーブルがロックされて、パフォーマンス落ちるんじゃない?とかデータ量多くなって適切にインデックス設計とかしても限界ありそうだよねとか思ったわけです。あと、このテーブルにカラム追加するとか、検索のためのタグ付けするとか、そういうの考えるとなんだか背筋が凍ります。特に住所情報持たせるとかなったらとんでもないことになりそう。
テーブルを分けてみる
要件に立ち返ると、認証、プロフィールとあるので、この観点で分けてみます。
ログインIDとパスワード、最終ログイン日時をauthenticatesとして定義しました。なお両テーブルは1:1で関連付けられています。
とりあえずusersテーブルのごった煮感はなくなりましたが、profileもう少しなんとかできないかなーとか思うので、もう少し分けてみます。
よく見るとほかユーザに見られてほしくない氏名の情報が混じってるのでこれは分けたほうがよさげ。と思ったのですが、、、
いい感じに分けられたんですけど、なんかセンスないというか、どう関連付けていいのかぱっと見わからないですね。。。
というわけで、fullnamesを親にして、profilesとauthenticatesと関連付けてみます。
なんかいい感じに見えました。でも親にfullnameってのがなんかあれですね。もう分けてしまいましょう。
いい感じになったけど、なんかこれでいいのか感があります。ちょっと大げさに分けすぎてしまったかな。。。
なんかもやっとしてますけど、これで終わりにします。名前のセンスないなとかそういうのはありますが。。。
最後に
もやっとした感じで終わってしまったので、なんか不完全燃焼ですが、これはこれで結論ということで。
authenticatesとusersの関連付けっているのかな。正直model側でdestroyの依存をかけてしまうだけでいい気もする。でも、直接SQLで触られたりすると一気にデータがおかしくなる。。。
あと、Railsの規約って観点でもどうなのかなとも少し思ったりもした。