【发布时间】:2017-05-22 19:56:06
【问题描述】:
假设我有三张桌子。我将尽可能简化这些表格来说明设计问题:
用户:
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)
);
地点:
- 发送给特定用户的消息设置了 user_id 字段,并且 network_id 字段为 NULL
- 发送到特定网络的消息设置了 network_id 字段,并且 user_id 为 NULL
- 发送给网络内用户的消息同时设置了 network_id 和 user_id 字段
但这是最好的方法吗?由于 network_id 和 user_id 字段可能为空,我必须创建一个单独的主键 (message_id),而不是使用复合主键(network_id 和 user_id),否则会这样做。
【问题讨论】:
-
如果网络 N 中的用户 A 与网络 O 中的用户 A 不同(向特定网络中的特定用户发送消息),则用户和网络不是多对多关系,仅在一对多中。
-
嗯,你能进一步解释一下吗?一个用户可以在多个网络中,一个网络可以包含多个用户。这不是网络和用户之间的多对多关系吗?消息与网络中用户的消息关系#3 将是一对多关系,但这是消息和 network_users 之间的一对多关系;我认为 messages-to-network_users 关系不会影响 users-to-networks 关系。
-
如果同一用户可以在多个网络中,那么向特定网络中的特定用户发送消息是没有意义的。我只需要将消息发送给用户。
-
上面的例子只是为了说明。我的实际情况要复杂得多,但可以说所有三个关系都有有效的用例。例如,我们可能有一条消息,只有当用户是特定网络的一部分时才能访问(案例 3),或者无论网络如何,用户始终可以访问的消息(案例 1),或者一条消息在特定时刻处于给定网络中的所有用户都可以访问(案例 2)。
标签: mysql sql database-design