複数のユーザーのメッセージを保存するデータベースを構築しようとしています。各ユーザーは、5 つの異なるメッセージ「タイプ」を送受信できます (厳密にはラベルであり、実際のデータ タイプは同じです)。私が最初に考えたのは、ユーザーごとに 5 つの異なるメッセージ タイプを表す複数のテーブルを作成することでした。これはあまり良い考えではないことがすぐにわかりました。次に考えたのは、users 列を持つメッセージ タイプごとに 1 つのテーブルを作成することでしたが、パフォーマンスの観点からも、それが最善の方法かどうかはわかりません。ユーザー 1 がタイプ 1 のメッセージを 100 回送信し、ユーザー 3 が 10 回しか送信しなかった場合はどうなるでしょうか。残りのフィールドは null 値になり、それが違いを生むかどうかはわかりません。考え?提案および/または提案された読書? 前もって感謝します!
3 に答える
いいえ、それ(この質問の主題で与えられたアイデア)は非常に非効率的です。新しいユーザーが作成されるたびに新しいテーブルを導入する必要があり、それらすべてを一度にクエリするのは悪夢です。
メッセージに関する情報を格納するための単一のテーブルを使用する方がはるかに簡単です。この表の各行は、1 つだけのメッセージに対応します。
さらに、このテーブルにはおそらく 3 つの「参照」列が必要です。2 つは特定のメッセージをその送信者と受信者にリンクするためのもので、もう 1 つはそのタイプを格納するためのもので、値の限られたセットのみを割り当てることができます。
例えば:
MSG_ID | SENDER_ID | RECEIVER_ID | MSG_TYPE | MSG_TEXT
------------------------------------------------------
1 | 1 | 2 | 1 | .......
2 | 2 | 1 | 1 | #######
3 | 1 | 3 | 2 | $$$$$$$
4 | 3 | 1 | 2 | %%%%%%%
...
誰かが送信したすべてのメッセージ(WHERE sender_id = %someone_id%
句を使用)、誰かに送信されたメッセージ( WHERE receiver_id = %someone_id%
)、特定のタイプのメッセージ ( )の両方を取得するのは非常に簡単WHERE msg_type = %some_type%
です。しかし、最も優れているのは、これらの句を簡単に組み合わせて、より洗練されたフィルターを設定できることです。
あなたが最初に考えたことは、次のように見えます。
IS_MSG_TYPE1 | IS_MSG_TYPE2 | IS_MSG_TYPE3 | IS_MSG_TYPE4
---------------------------------------------------------
1 | 0 | 0 | 0
0 | 1 | 0 | 0
0 | 0 | 1 | 0
NULL
の代わりに s を使用できますが0
、コアは同じです。そして、それは壊れています。WHERE is_msg_type_1 = 1
はい、句を使用して単一タイプのすべてのメッセージを引き続き取得できます。しかし、特定のタイプのメッセージを取得するような簡単なタスクでさえ、それほど簡単ではありません。価値のあるものを見つけるまで、これらの 5 つの列をそれぞれtruthy
確認する必要があります。
同様の困難は、各タイプのメッセージの数を数えようとする人に予想されます (これは、上記の構造ではほとんど自明です: COUNT(msg_id)... GROUP BY msg_type
.
ですから、これをしないでください。) そうしないという非常に強い理由がない限り、時間の経過とともに幅ではなく高さが大きくなるようにテーブルを構成するようにしてください。
残りのフィールドは null 値になります
データベースを垂直に設計している場合を除いて、残りのフィールドはありません。
user int
msgid int
msg text
create table `tv_ge_main`.`Users`(
`USER_ID` bigint NOT NULL AUTO_INCREMENT ,
`USER_NAME` varchar(128),
PRIMARY KEY (`ID`)
)
create table `tv_ge_main`.`Message_Types`(
`MESSAGE_TYPE_ID` bigint NOT NULL AUTO_INCREMENT ,
`MESSAGE_TYPE` varchar(128),
PRIMARY KEY (`ID`)
)
create table `tv_ge_main`.`Messages`(
`MESSAGE_ID` bigint NOT NULL AUTO_INCREMENT ,
`USER_ID` bigint ,
`MESSAGE_TYPE_ID` bigint ,
`MESSAGE_TEXT` varchar(255) ,
PRIMARY KEY (`ID`)
)