
例えば、Twitterのようなシステムを作るとします。ユーザの情報に「名前」「ID」「フォロワー」があります(3つだけユーザー情報とします)。
id , name, follower_idsのようなフィールドが必要だと思います。ですが、この時follower_idsはいくらでも要素が増える可能性があります。このようなユーザー情報をSQL(特にMySQL)で管理することはできますか?
今回の例のような構造をデータベースに保管したいのですが、どんな形式をとったらいいか迷っているので、質問しました。ちなみにSQLはやったことがありません。おすすめの方法があったらお願いします。XMLやJSON形式というキーワードにもたどり着きましたが、なるべく早いデータ操作をしたいです。
No.3ベストアンサー
- 回答日時:
0 TARO (ID 2, 3をフォロー)
1 HANAKO (ID 3をフォロー)
2 JACK (ID 0をフォロー)
3 TOM (誰もフォローしていない)
でしたら
id(主キー),name
0 TARO
1 HANAKO
2 JACK
3 TOM
と
id , follower_ids(idとfollower_idsの複合で主キー)
0 2
2 0
3 0
3 1
ですね。前者のテーブルはidの数だけレコード。
後者のテーブルはフォロワーの延べ数だけあればよいかと。
主キーは数字でなくて文字でもユニーク(一意)であればOKです。
なるほど、理解しました。
id, nameで管理するテーブルはどのようなデータ構造を取ればいいかはわかっていましたが、id, follower_idsのデータ構造は分かりませんでした。
2人フォロワーがいるときは、
3 0
3 1
のように重複させて1対1で保管するんですね。どうしてもそういう風にデータを捉えることができませんでした。
<users>
<user id='0'>
<name>Taro</name>
<followers>
<id>2</id>
<id>3</id>
</followers>
</user>
<user>
....
</user>
....
</users>
XML風に書くと上記のような感じのデータ構造を感じしか頭にでてきませんでした。
MySQLの概要を把握するために、ドットインストール(http://dotinstall.com/lessons/basic_mysql_v2) でSQLの文の書き方は見たので、SELECT文がかなり強力なのは見ました。複合で主キーにすることもできるんですね。
フォロワーのリストの2つの対のデータは、重複しない組み合わせになって、主キーにしておけば検索が早く済むというわけですね。
最後までありがとうございました。
No.4
- 回答日時:
標準のSQLには配列に対する配慮がほとんどなく、テーブル構造には配列のような繰り返しは持たない方法が一般的です。
繰り返しの代わりに必要な分の行を登録します。なので「ID」と「名前」のテーブルを1人に1行と「ID」「フォロアー」のテーブルで繰り返しの分だけ行を登録します。ご回答ありがとうございます。
本当に申し訳ありません。こちらが、他の回答者さんのお礼を書いている間にご回答されたようです。
これから、またお世話になる機会があるかもしれないので、その時はよろしくお願いします
No.2
- 回答日時:
先に、質問の答えだけ挙げておきますね。
USER_LIST
user_id (pk)
name
FOLLOWER_LIST
user_id (pk)
follower_id (pk)
の二つのテーブルで、データベースを構築します。ここで、pkが振ってあるのは、プライマリーキーです。
これだけの情報で、ユーザーとフォロワーに関する質問には、大抵答えられます。
sqlを横に置いておいて、手で、探してみましょう。
followerの名前も、userの名前も、ちゃんとuser_listにあります。followerだって、ユーザーの一員ですから、あるfollower_idがあった時、名前を調べるには、USER_LISTのuser_idで引けば良いですよね。
あるユーザーがだれをフォローしているかは、FOOLLOWER_LISTのuser_idを見て、該当するユーザーの全ての行のfollower_idを拾ってくればOKです。follower_idの名前が知りたければ、USER_LISTに戻って、名前を調べれば良いです。
逆も出来ます。ある人にフォローされている人は誰ですか?今度は、FOLLOWER_LISTの該当するfollower_idの行を全部とってきて、user_idをリストにすればよいです。名前が知りたければ、USER_LISTに戻れば調べられます。
SQLで、データを検索するために使用する、SELECT文は、このような複数から行う表引きを簡単にできるように設計されています。
もっと複雑な質問でも、ちゃんと書けば大概の質問には答えられます。
実は、リレーショナルデータベース(MySQLもこの一員です。)を操作するのに、必須の命令は、たったの7つしかありません。
SELECT
INSERT
UPDATE
DELETE
CREATE TABLE
ALTER TABLE
DROP TABLE
最初の4つは、データを操作するための命令。後の3つは、テーブルを作ったり修正するための命令です。リファレンスを見ると他にも山のように命令語がありますが、全部、データベースそのものの管理・保守用の命令です。
このたった7つの命令を解説すると、本が一冊出来上がります。
上級向けの本では、SELECT命令だけを解説するのに、一冊の本があるくらいです。(極端な事例では、ツリー構造をselect文でどう扱うか?だけをテーマにした書籍も知っています。)
当然、その背景には、数多くの概念があるわけですが、残念なことに、これを説明するには、この解答枠はあまりにも狭すぎます。
ぜひ、MySQLの入門書(書店に行けば、そのものずばりの入門書が多数あります。)を一冊購入されて学習されることを強くお勧めします。
一番それが早道でしょう。
普通、ソフトの使い方は、「ヘルプを読め」とか「ググレ」の一言で全てを片付けることも出来るんですが、このリレーショナルデータベースシステムは、それが出来ない数少ないソフトの一つです。
基礎の概念を最初から順を追ってやっておかないと、理解できないんですね。こういう時には、マニュアルとか、web検索という代物はすっごく不便ですから。
ご回答ありがとうございます
どのように検索すればいいか頭で考えさせるくれる文もあって親切にありがとうございます。
プログラミングをやってきてもクライアントサイドとサーバーサイドはかなり違う感じがします。サーバーサイドのほうがどうしても敷居が高いです。mitonekoのアドバイスを聞いてSQLに関する書籍を読んでみたいと思いました。
No.1
- 回答日時:
DBにデータを格納するうえで正規化は外せません。
正規化するということは繰り返し項目をなくすことです。
ですから、
id , name
というテーブルのレコードはユーザーの数だけあり、
id , follower_ids
というテーブルのレコードはユーザーあたりフォロワーの数だけレコードが存在します。
これらを結合して読み出せばよいかと。
シンプルなご回答ありがとうございます。
申し訳ないですが、SQLを使ったことがないので、どのようにすればよいか想像がつきません。
例えば、以下のユーザーがいた時はどういうデータ構造を取ればよいのでしょうか?
ID NAME
0 TARO (ID 2, 3をフォロー)
1 HANAKO (ID 3をフォロー)
2 JACK (ID 0をフォロー)
3 TOM (誰もフォローしていない)
できれば、IDは数値ではなく文字列でも大丈夫な方法をお願いします
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルの関数について教えて...
-
エクセルで最後の文字だけ置き...
-
クエリ表示と、ADOで抽出したレ...
-
エラー 1068 (42000): 複数の主...
-
マイクラPC版のコマンドで効率...
-
別テーブルからSELECTした値を...
-
select文のwhere句に配列を入れ...
-
一つ前のレコードの値と減算し...
-
VMware Player でCD-ROMドライ...
-
ID毎に最新の値を取得する
-
SQLサーバから、項目の属性(型...
-
文字列を結合したカラムでJoin...
-
小人の読み方は?
-
access2007でdcountを使って連...
-
フィールドのデータ型を取得し...
-
ある列の値を自動的にずらしたい
-
sqlite結果の非表示
-
Webで、図形描画を行いたい。
-
レコードセットに新規追加する
-
`picture` varchar(255) のコマ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
VIEWの元のテーブルのindexって...
-
エラー 1068 (42000): 複数の主...
-
SQLサーバから、項目の属性(型...
-
select文のwhere句に配列を入れ...
-
SQL Left Join で重複を排除す...
-
Access パラメータクエリをcsv...
-
マイクラPC版のコマンドで効率...
-
【Transact-sql】 execの結果を...
-
sqlで、600行あるテーブルを100...
-
SQLにて特定の文字を除いた検索...
-
1テーブル&複数レコードの更新...
-
PL/SQLの変数について
-
WordpressのContact form 7でzi...
-
複数テーブルのGROUP BY の使い...
-
バインド変数について
-
inner joinをすると数がおかし...
-
MySQLのint型で001と表示する方...
-
updateを1行ずつ実行したい。
おすすめ情報