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

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

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

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

Q&A

解決済

1回答

2819閲覧

ある要求を満たす、MySQLを用いたデータベース設計の確認

Kei227

総合スコア44

MySQL

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

0グッド

0クリップ

投稿2015/11/06 12:45

編集2015/11/06 14:45

以下の要求を満たすテーブルを作成し、

  • User登録に必要な情報は名前、メアド、パスワード
  • 友だち追加は一方的にできるが、相手は追加又はブロックできる
  • ブロックしたユーザー一覧が見れる(ブロックを外せる)
  • 友達一覧が見れる
  • 個人チャットでメッセージが遅れる
  • グループ作成できる
  • グループでもメッセージを送れる
  • グループにはユーザーを追加、削除できる
  • グループ名を変えられる

=============

lang

1create table users ( 2 id int primary key auto_increment, 3 name varchar(50), 4 mail varchar(50), 5 password varchar(50) 6); 7 8insert into users (id, name) values (1, 'keita'); 9insert into users (id, name) values (2, 'takeru'); 10insert into users (id, name) values (3, 'taro'); 11insert into users (id, name) values (4, 'ken'); 12 13create table blockusers( 14 blockuser_id int, 15 blockuser_name varchar(50), 16 id int, 17 foreign key (id) references users (id) 18); 19 20insert into blockusers (blockuser_id, blockuser_name) values (1, 'yui'); 21insert into blockusers (blockuser_id, blockuser_name) values (2, 'ayu'); 22 23create table friends( 24 friend_id int primary key, 25 friend_name varchar(50), 26 id int, 27 foreign key (id) references users(id) 28); 29 30insert into friends (friend_id, friend_name) values (1, 'mim'); 31insert into friends (friend_id, friend_name) values (2, 'erika'); 32 33create table groups( 34 group_id int primary key, 35 group_name varchar(50), 36 id int, 37 foreign key (id) references users(id) 38); 39 40insert into groups (group_id, group_name,id) values (1,'school',1,); 41insert into groups (group_id, group_name,id) values (2,'school',3,); 42insert into groups (group_id, group_name,id) values (3,'bestfried',2,); 43insert into groups (group_id, group_name,id) values (4,'teamA',2,); 44 45create table schools ( 46 school_id int primary key, 47 school_message_content text, 48 id int, 49 foreign key (id) references users(id) 50); 51 52insert into schools (school_id, school_message_content) values (1, 'aaa'); 53insert into schools (school_id, school_message_content) values (2, 'bbb'); 54insert into schools (school_id, school_message_content) values (3, 'ccc'); 55 56create table messages( 57 message_id int, 58 message_content text, 59 id int, 60 foreign key (id) references users(id), 61 friend_id int, 62 foreign key (friend_id) references friends(friend_id), 63 group_id int, 64 foreign key (group_id) references groups(group_id) 65); 66 67insert into messages (message_id, message_content) values (1, 'hoge?'); 68insert into messages (message_id, message_content) values (2, 'hoge!!!'); 69insert into messages (message_id, message_content) values (3, 'hoge'); 70insert into messages (message_id, message_content) values (4, 'honcon');

以下の命令を実行するMysql文を出力しました。

(1)ユーザ(id=1)とユーザ(id=2)の会話の履歴
(2)グループ(id=1)に所属しているメンバー一覧
(3)グループ(id=1)の会話履歴
(4)hogeという文字を含むメッセージ一覧

lang

1(1)select messages.message_content from messages 2inner join users on messages.message_id = users.id 3inner join friends on messages.message_id = friends.friend_id 4where users.id = 1 and users.id = 2; 5 6(2)select users.name from users 7inner join groups on users.id = groups.id 8where group_name = 'school'; 9 10(3)select schools.school_message_content from schools; 11 12(4)where messages.message_content like '%hoge%';

自分で把握している疑問点は一つあります。
上記のsql文で、グループラインのテーブル(shools)のメッセージ履歴を書いたのですが、

lang

1(3)select schools.school_message_content from schools;

下記のように、グループラインごとにテーブルをひとつずつ作成していたら膨大なテーブル数に成ってしまいますよね。

sql

1create table schools ( 2 school_id int primary key, 3 school_message_content text, 4 id int, 5 foreign key (id) references users(id) 6); 7 8insert into schools (school_id, school_message_content) values (1, 'aaa'); 9insert into schools (school_id, school_message_content) values (2, 'bbb'); 10insert into schools (school_id, school_message_content) values (3, 'ccc');

グループテーブルの中に、グループラインそれぞれの履歴を格納したいのですが、どのように記入してあげればいいのかが分かりません。

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

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

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

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

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

KiyoshiMotoki

2015/11/06 13:49

分からない点・問題点をもっと細かい粒度に落とし込んでから質問された方が、回答がつきやすくなると思います。 答えるべき内容が多すぎると回答者は負担に感じますし、なによりこのご質問からは、ちょっと「丸投げ感」を感じますよw
Kei227

2015/11/06 14:47

確かに丸投げのようなもので、回答者様にご負担かける書き方でした、、。 訂正いたしました。ご教授ありがとうございます!
guest

回答1

0

ベストアンサー

情報の追記、ありがとうございます。

"グループライン"とは、グループ内のメッセージのことでしょうか?
とりあえず、↑であると仮定して回答させていただきます。

グループテーブルの中に、グループラインそれぞれの履歴を格納したいのですが、

これはまずい設計です。

groupsテーブルはあくまで1つのレコードが1つのグループを表現するテーブルであるべきで、
そこに、グループラインのような1グループに対して複数生成されるデータを混ぜ込むべきではありません。

以下のように、グループラインを格納するためのテーブルを別途、定義してやる方が良いです。

sql

1CREATE TABLE group_lines ( 2 group_line_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, 3 id INTEGER NOT NULL, 4 group_id INTEGER NOT NULL, 5 message_content TEXT NOT NULL, 6 FOREIGN KEY (id) REFERENCES users (id), 7 FOREIGN KEY (group_id) REFERENCES groups (group_id) 8);

group_idカラムをgroups.group_idの外部キーとして定義してやれば、
グループごとにテーブルを用意する必要はなくなります。

"スクール"のグループラインを取得する

sql

1SELECT group_lines.* 2FROM group_lines 3WHERE group_id = 1;

groupsテーブルはあくまで1つのレコードが1つのグループを表現するテーブルであるべき

に関連して付記させていただくと、idカラムもgroupsテーブルに定義するべきではありません。

1人のユーザーは1つのグループのみに所属するのであれば、usersテーブルにgroup_idカラムを持たせる。
1人のユーザーが複数のグループに所属できるのであれば、user_group_relationsテーブルを別途、定義してやる。
この方がよいです。

user_group_relationsテーブルをどのように設計すればよいかは、
「リレーションシップ 多対多」
とか
「relationship many to many」
とかで検索して、ご自分で調べてみて下さい。

投稿2015/11/06 15:49

KiyoshiMotoki

総合スコア4791

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

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

Orlofsky

2015/11/06 18:09

KiyoshiMotokiさんに賛成。 >グループテーブルの中に、グループラインそれぞれの履歴を格納したいのですが、 >>これはまずい設計です。 ひとつのテーブルには同じ性質のデータを置きます。昔、マスターと履歴を一つのテーブルにまとめる主義の人が設計していた人がいたけど、マスター情報と履歴情報は必ず別テーブルに分けます。マスターテーブルはprimary keyでunique scanでアクセスできるように設計するべきです。頻繁にselectするデータがrange scanしているとデータが増えるとどんどんパフォーマンスが落ちますし、SQLが複雑になります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問