ページ

2012-06-11

[web]”ろぐほー”のデータベースを正規化した

”ろぐほー”のデータベースはMySQLを使用しています。

テーブルの構成を最初いい加減に作って、後になってちょっとやばくなって修正したので、その過程を紹介します。



はじめにお詫び:説明不足な点が多いため、分かりにくいところが多いです…


では、気を取り直して。

まず、始めの頃は以下のようなテーブル構成でした。


entrysテーブルがエントリーを保持するテーブルで、エントリー毎に1つデータが出来ます。
timestampsテーブルはエントリーを保存した時刻を保持するテーブルで、一回保存するごとに1つのデータ出来ます。

一つのtimestampsテーブルデータに複数個のentrysテーブルのデータがtimestamp_idによって紐付きます。

これの何がやばいのかというと、同一のエントリー(同一のURLを持つエントリー)を何回もentrysテーブルに保存してしまう為に、データベースの容量がめちゃくちゃ大きくなってしまうことです。

ある時刻T1の時に、あるエントリーAがあった場合、entrysテーブルには当然、URLやtitleの情報が記録されます。

別の時刻T2の時にも、エントリーAがあった場合、entryテーブルに再びURLやtitleの情報が記録されてしまいます(すでにさっき記録したにも関わらず…)。

解りやすいかわかりませんが、式で書くと


T1のentryに記録されるデータ:id + timestamp_id + [title] + [url] + cnt + rank + etc...
T2のentryに記録されるデータ:id + timestamp_id + [title] + [url] + cnt + rank + etc...


T1とT2で、titleとurlは同じ物をダブって保存しています。他のもの(cnt、rank)は変化します。

しかも、titleとurlは文字列データなので、数値データと比較してデータベース容量を大量に食います。

なので、titleとurlをダブって記録しないようにすれば、データベース容量の節約ができそうです。

そこで、titleとurlだけを別のテーブルに括り出して、entrysテーブルからは別のテーブルのidで参照させることにしました。

このように、ダブっているデータを別のテーブルに括り出すことを”正規化する”とか言ったりします。

別のテーブルにcontentsという名前を付けて、

T1:id + timestamp_id + content_id + cnt + rank + etc...
T2:id + timestamp_id + content_id + cnt + rank + etc...

別のテーブル(contents)

id + [title] + [url] 

これによって、何回も同じエントリーが登場してもurlとtitleの情報は一つのみになります。
ちなみにcontentsテーブルを参照するためにデータが1個(content_id)増えましたが、そのデータは数値データなので、文字列データに比べたら非常に小さいデータになるため、結果的にデータベース容量の節約になります。


変更後は以下のようになりました。



これによって、データベース容量の節約が出来ました。めでたしめでたし。

0 件のコメント:

コメントを投稿