我们说我有三张桌子。我将使这些表格尽可能简单,以说明设计问题:
用户:
CREATE TABLE users (user_id INT PRIMARY KEY);
网络:
CREATE TABLE networks (network_id INT PRIMARY KEY);
网络用户:
CREATE TABLE network_users (
network_id INT,
user_id INT,
PRIMARY KEY(network_id, user_id),
FOREIGN KEY(network_id) REFERENCES networks(network_id),
FOREIGN KEY(user_id) REFERENCES users(user_id)
);
如上所示,用户与网络有很多关系,如网络用户表中所述。到目前为止,这一切都非常传统。
现在我的问题是:
我想说我想添加一个消息表,我希望能够存储发送到的消息:
消息表的最佳设计方法是什么?
我可以构建一个这样的消息表:
CREATE TABLE messages (
message_id INT PRIMARY KEY,
network_id INT,
user_id INT,
FOREIGN KEY(network_id) REFERENCES networks(network_id),
FOREIGN KEY(user_id) REFERENCES users(user_id)
);
其中:
但这是最好的方法吗?由于network_id和user_id字段可能为null,因此我必须创建一个单独的主键(message_id),而不是使用复合主键(network_id和user_id),否则将会这样做。
答案 0 :(得分:1)
您在问题中描述的内容称为多态关联。请查看this article,其中介绍了一些可能的建模方法。
虽然本文描述了如何以最一般的方式建模多态关联,但我认为您的方法也很好,因为大多数人可能不会拥有超过3种消息类型(对用户而言,对网络而言)以及网络中的用户
答案 1 :(得分:1)
我看到的一种方法是在messages
中加entity_type
以及user
,其中类型告诉您记录是指network
还是{{1}}(或稍后的其他类型)。 This response有一些处理这种情况的有趣例子。
答案 2 :(得分:0)
如果你在3件事(A,B,C)中有很多:很多关系:
CREATE TABLE ABC (
a_id ...,
b_id ...,
c_id ...,
PRIMARY KEY(a_id, b_id, c_id),
INDEX(b_id, c_id, a_id),
INDEX(c_id, a_id, b_id)
) ENGINE=InnoDB;
索引允许您从任何表格到其他表格。
但是......在确定这是最好的之前,让我们看一下你的SELECTs
。