質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

MariaDB

MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。

Q&A

解決済

2回答

400閲覧

DB設計について、「いつ、何に、誰が」を持つテーブルよりも、「誰が、その他の情報」という方がいいのではないか?

theearth

総合スコア11

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

MariaDB

MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。

0グッド

0クリップ

投稿2020/01/21 06:56

編集2020/01/25 03:24

よくある「いいね機能」などのDB設計で質問があります。

「いつ、何に、誰が」を持つテーブルよりも、「誰が、その他の情報」という方がいいのではないか?という考えなのですが、

なぜ前者が用いられるのでしょうか?

###「いつ、何に、誰が」を持つテーブル
こちらでは、「user_idが2さんがいいねしている記事」を取得するとき、「user_idが2の行」を複数探し、そこから「updated_at」や「article_id」など複数の列を取得してこなければなりません。

+----+---------------------+------------+---------+ | id | updated_at | article_id | user_id | +----+---------------------+------------+---------+ | 1 | 2020-01-25 12:35:43 | 1 | 1 | | 2 | 2020-01-25 12:35:44 | 1 | 2 | | 3 | 2020-01-25 12:35:44 | 1 | 3 | | 5 | 2020-01-25 12:36:16 | 2 | 2 | +----+---------------------+------------+---------+

###「誰が、その他の情報」を持つテーブル
こちらならば、「user_idが2さんがいいねしている記事」を取得する速度が速いですよね。

「user_idが2の行」は1つしかなく(下記は見やすく2行にはしていますけど)、その1つのdataを取得すれば済むからです。

同様に削除も更新も何もかもこちらの方が早いような気がするのですが、どうなのでしょうか。なぜこちらより上の設計が用いられるのか妥当な理由を知りたいです。

+----+-------------------------------------------------------+---------+ | id | data | user_id | +----+-------------------------------------------------------+---------+ | 1 | [{"updated_at":"2020-01-25 12:35:43","article_id":1}] | 1 | | 2 | [{"updated_at":"2020-01-25 12:35:44","article_id":1}, | 2 | | | {"updated_at":"2020-01-25 12:36:16","article_id":2}] | | | 3 | [{"updated_at":"2020-01-25 12:35:44","article_id":1}] | 3 | +----+-------------------------------------------------------+---------+

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

同様に削除も更新も何もかもこちらの方が早いような気がするのですが

たしかに、ただ単に入れるだけであれば、この方法でも構いません。個人設定など、「他の項目と全く絡まない」「中身で検索することもありえない」項目については、こういう入れ方で済ませてしまうことも考えられます。

ただし、このようにデータを突っ込んでしまうと、検索・並べ替えなどにまとめて突っ込んだデータを使うのが難しい、あるいは不可能となります。

あと、外部キーもかけられないので、article_idに存在しないIDが来ても、データベースレベルではそれを通してしまいます。

というように、このようなデータのもたせ方をすることは、RDBMS(リレーショナルデータベース)を、単なるデータ置き場としてしか使わない、ことにほかなりません。

投稿2020/01/25 04:00

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/01/25 04:02

なお、「NoSQL」といって、リレーショナル性にこだわらないデータストアの仕組みもあります。データの内容と使い方によっては、NoSQLのほうが便利ということも考えられます。
theearth

2020/01/29 03:43

ご回答の確認が遅くなり申し訳ございません。 ご慧眼、感服いたしました。 考え直したところ次の質問がございます。(長文すみません。) まず「いいね機能」は当人しか見ず、「他の項目と全く絡まない」情報です。 ただし「中身で検索することもありえない」ではなく、検索・並べ替え・削除(以下「抽出」)も必要です。ここで質問ですが、 抽出は次の流れになりまして、 ➀dataからjsonすべて取得 ➁そこから抽出するIDを持つ配列を取得 この➀➁の流れは、「いつ、何に、誰が」を持つテーブルからの取得よりも早くないでしょうか? ユーザーが10万人いたとしたら、「いつ、何に、誰が」を持つテーブルにその10万人のアクションが数百万行入ることになります。すると「Aさんのいいね一覧」を抽出する際、わざわざ数百万行から探し出すことになります。 他方で「誰が、その他の情報」を持つテーブルならば、「Aさんのいいね一覧」は10万行からAさんのdataを探し、先の➀➁を処理するだけになります。 このように比べると、「他の項目と全く絡まない」情報ならば、例え抽出が必要であっても、「誰が、その他の情報」を持つテーブルの方が早いということになりませんでしょうか?
maisumakun

2020/01/29 04:05 編集

> ユーザーが10万人いたとしたら、「いつ、何に、誰が」を持つテーブルにその10万人のアクションが数百万行入ることになります。 インデックスを張れば、「特定のuser_idを持つもの」のような条件による検索は一瞬で行なえます。 (逆に、JSONを使ったデータ構造だと、「ある案件についたいいね数」を集計する場合に全JSONを展開する必要が出てきますが、正規化して列に分けて入れていた場合には同様にすぐ集計可能です)
theearth

2020/01/29 04:05

なるほどインデックスというものを知りませんでした。早速試してみたいと思います。ご返信誠にありがとうございます。 すでにベストアンサーは選んでしまっておりますが、また別のところで機会がございましたらどうぞ宜しくお願い致します。
guest

0

ベストアンサー

理由は正規化です。
要件次第で、正規化を崩すこともありますが、一般論として正規化されたデータのほうが扱いやすいです。

投稿2020/01/25 03:32

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

theearth

2020/01/25 03:49

正規化、知りませんでした。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問