実装の想定を基礎とした、いいねに関する考察
まず、想定としてなろうではSQLデータベースを使用していると考えます。
SQLデータベースは、スキーマの規定されたテーブルにデータを格納します。
考え方としては、列見出しのついたエクセルシートにデータを入れるようなもので、そのシートがたくさんある、というところですね。
そして、テーブル(シート)の各情報は、別のシートの情報と関連付けられたりしています。そのために、「キー」を使用します。
例えば、ユーザー情報のテーブルが有って、それには個々のユーザーの登録情報が記録されています。ユーザー情報のキーは、ユーザー番号ですね。マイページとか誤字報告で使用されるIDです。
それとは別に、作品のテーブルがあり、そこには各作品の小説情報が格納されています。その際のキーはn番号になるかな。そして、作品テーブルの中には作者カラムが存在し、そこにユーザーidを記録することで、誰の作品かが判るようにしているわけです。
さらにその下に部分テーブルがあります。ここには、各部分の属性が書かれているわけです。もちろん、小説の本体も。
部分の情報は、小説キー+部分番号としてアクセスすることもできますが、実際には内部的には固有のidがふられているでしょう。それは、感想などの情報を、この固有idに関連付けないと、部分の削除・挿入によって部分番号がずれた場合に、感想が変なところについてしまったりするからです。
では、「いいね」をどう実装するかです。
実装の際の基本としては、なるべく他に影響を与えず、かつ拡張性を考えながら必要最低限で行う、という事です。これにより、開発工数を削減し、かつバグの発生の可能性を低くします。
普通に考えると、部分テーブルに「いいね」カウンタをつけるのがよさそうに思いますが、これは適当ではありません。
理由の一つは、このようにすると複数の人が同時に同じ部分に「いいね」したりすると、書き込みの競合が起こってしまうからです。例えば、AとBが、現在10いいねの部分にいいねをつけると、双方が11を書き込みに行って、結果的に12になるべきカウントが11のままになってしまったりします。
これを避けるためには、更新するまでデータにロックをかけて、他の更新を拒否したり、あるいはタイムスタンプを用いて更新が正しく行えたかどうかを確認し、ダメならリトライする、というような措置をする必要があり、多少複雑になるか、パフォーマンスが劣化します。
さらに、既存のテーブルのスキーマを変更すると、そのテーブルにアクセスしている部分に問題がないか、という点を逐一チェックする必要があります(このため、SQLデータベースは頻繁なスキーマの変更を嫌います)。
で、実際にどのようにいいねを実装するかというと、おそらくは新規のいいねテーブルを作成し、キーは小説キー・部分キー・ユーザーキーの複合キーとして、データに作成日時・更新日時と現状の設定(On/Off)を記録するようにします。
これは、評価でも同じですが、もし作成日時が無かったり、評価取り消しでデータを削除し、次の評価でデータを作り直しにしたりすると、評価を消してはつけることで何度も評価カウントを上げる事が出来てしまいます。これを避けるために、初回作成日時が一定範囲(1日・1週間・1か月・四半期・年刊)の評価カウントだけを集計したりするわけです。
小説管理ページを開くたびに、当該小説に関連付けられたいいねデータのうち、Onのものの数を数えて、それを表示させます。また、連載の場合は、部分単位でも集計し、その結果を部分ごとのいいねの欄に表示させます。当初、いいね件数がうまく表示されなかったのは、この集計作業がうまく行っていなかったためでしょう。
また、ユーザーが部分を表示した場合は、このいいねテーブルのエントリを検索し、データが存在してOnになっている場合にのみいいねの現在値をOn、そうでなければOffとして表示しているわけです。
という(想定)実装を前提として、なぜ「いいね」の現状がそうなっているのか、将来的にどうなるか、について少し考察します。
※なぜいいねが一般ユーザーに公開されていないか
前記の様に、いいねの数は集計作業により計算されるので、それは比較的重たい作業となります。小説情報ならまだアクセスは少ないでしょうが、目次を表示するたびに部分ごとのいいねを集計するのはシステム負担になると考えられます。このために、一般ユーザーには公開されていないと考えられます。
※将来的にも一般ユーザーに公開されないか
リアルタイムのいいね数の公開は難しいでしょうが、評価ポイントと同様に一定間隔でバッチ処理をして、集計結果を作成しておく事は考えられます。こうすれば、ユーザーへの公開も可能でしょう。バッチの更新は競合の問題が起きないので、割とよく使用されます。
ただ、そのためには検証に時間が必要だと思われますので、ある程度先の話になるかと思います。
※いいねをした作品(部分)一覧は表示できないか
いいねデータの構造から、評価をつけた作品と同様に内容を表示することに技術的問題は少ないと思います。要望が有って、開発側にリソースが有れば、実現される可能性は少なくないと思います。
※非ログインユーザーはなぜいいねを押せないのか
いいねテーブルの構成上、ユーザーIDがキーになっています。このため、いいねの水増しとかを心配する以前に、そのままではデータを登録することができません。これが非ログインユーザーにいいねが解放されていない大きな原因と思われます。
そも、本当に非ログインユーザーが無名であれば、いいねボタンを押しても、それをOn表示にすることができない(少なくともページを行って戻ってしたらクリアされてしまう)状態になるのは自明です。これでは、その気が無くても複数押ししてしまいそうです。
実際には、非ログインユーザーのユニーク性を判定する方法はないではないでしょうが、たとえばKasasagiのユニークユーザー数の集計が2日遅れになる事を考えても、それはそう簡単な作業ではないでしょう。
非ログインユーザーに、ブラウザごとにユニークIDを発行して、それをクッキーに保存し、ユーザーID代わりに使用する、という事は考えられます。クッキー管理などを見直す必要があるでしょうから、実装されるにしても多少の時間は見ないといけないでしょう。
個人的には、名前の入力を必須にする(名前はクッキーで管理する)のが実は良いんじゃないかと思っています。非ログインユーザーが感想を書く場合も名前は必須項目でしょうから、同様にいいねにも名前を要求し、その名前を仮のユーザーIDと対応付けるわけです。「あああ」とかそういう名前だとかぶりが多くなりすましになってしまう事もあるでしょうが、ある程度かぶらないような複雑な名前であれば、案外うまく管理できるのではないかと思うのです。
※いいねランキングが実装される可能性はあるか
前提として、バッチによる集計が実装されている必要があるでしょうが、それ自体は実現可能だと思います。
ただ、単純に考えても部分数が多い作品はいいね数が当然増える事になります。総計評価を考えると、いいね数を部分数で割る、とか考えられはしますが、やはりそれでは短編が過剰に有利になるでしょう。
逆に、日間など期間を区切ったいいね数の場合、部分数で割る事は逆に変なことになりますし、いずれにしろ1日の更新回数が多いほど、いいね数も増える事になります(短編が不利になります)。これでは、指標として役に立つかどうかというと、とても疑問です。
現実的には、いいね数ランキングは使い物にはならないんじゃないかと思います。
というところで、まあ今回はまず最小限の実装が行われた、という所だと理解するのがよさそうです。将来どのように発展していくかは、開発リソースによるのではないかと。
実装の想定は、あくまで常識的にはこう作るだろう、というものを現状と併せて考えたものですので、もちろん本当にそのようになっていることを保証するものでは全くありません。