Mysql 设计与表A、表B或表A和B相关的SQL表的最佳实践是什么?

Mysql 设计与表A、表B或表A和B相关的SQL表的最佳实践是什么?,mysql,sql,database-design,Mysql,Sql,Database Design,假设我有三张桌子。我将使这些表格尽可能简单,以说明设计问题: 用户: 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_i

假设我有三张桌子。我将使这些表格尽可能简单,以说明设计问题:

用户:

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)
);
如上所示,用户与网络具有多对多关系,如网络用户表中所述。到目前为止,这一切都很传统

现在我的问题是:

假设我想添加一个messages表,并且我想能够存储发送到以下地址的邮件:

  • 特定用户
  • 一个特定的网络
  • 或发送给网络中的用户
  • 消息表的最佳设计方法是什么

    我可以这样构造消息表:

    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)
    );
    
    其中:

  • 发送给特定用户的消息的用户id字段设置为空,网络id字段设置为空
  • 发送到特定网络的消息设置了网络id字段,用户id为NULL
  • 在网络中发送给用户的消息同时设置了“网络id”和“用户id”字段

  • 但这是最好的办法吗?由于network_id和user_id字段可能为空,因此我必须创建一个单独的主键(message_id),而不是像其他方式那样使用复合主键(network_id和user_id)。

    您在问题中描述的被称为多态关联。看看哪一个描述了一些可能的建模方法


    虽然这篇文章描述了如何以最一般的方式对多态关联进行建模,但我认为您的方法也很好,因为您的问题中所描述的消息类型(对于用户、对于网络和对于网络中的用户)可能不会超过3种。看看哪一个描述了一些可能的建模方法


    虽然本文描述了如何以最通用的方式对多态关联进行建模,但我认为您的方法也很好,因为最有可能的消息类型不会超过3种(对于用户、对于网络和对于网络中的用户)

    我见过的一种方法是在
    消息中设置
    实体id
    ,以及
    实体类型
    ,其中类型告诉您记录是指
    用户
    还是
    网络
    (或稍后的其他类型)。有一些处理这样一个案例的有趣例子。

    我见过的一种方法是在
    消息中添加
    实体id
    ,以及
    实体类型
    ,其中类型告诉您记录是指
    用户
    还是
    网络
    (或稍后的其他类型)。有一些处理此类案件的有趣例子。

    如果你在三件事(a、B、C)之间有多:多的关系:

    索引允许您从任何表向其他表移动


    但是。。。在确定这是最好的之前,让我们先看看你的
    选择的一些

    如果你在三件事(a、B、C)之间有多:多的关系:

    索引允许您从任何表向其他表移动


    但是。。。在确定这是最好的之前,让我们先看看您选择的一些

    如果网络N中的用户A不同于网络O中的用户A(向特定网络中的特定用户发送消息),那么用户和网络不是多对多的关系,只是一对多的关系。您能进一步解释一下吗?一个用户可以在多个网络中,并且一个网络可以包含多个用户。这不是网络和用户之间的多对多关系吗?消息关系#3在网络中发送给用户的消息是一对多关系,但这是消息和网络用户之间的一对多关系;我认为消息到网络用户的关系不会影响用户到网络的关系。如果同一用户可以在多个网络中,那么向特定网络中的特定用户发送消息是没有意义的。我只需要将消息发送给用户。上面的示例只是为了说明。我的实际场景要复杂得多,但可以说这三种关系都有有效的用例。例如,我们可以有一条消息,当用户是某个特定网络的一部分时,该消息应该只能被用户访问(案例3),或者一条消息总是可以被用户访问(无论网络如何)(案例1),或者一条消息可以被在某个特定时刻处于给定网络中的所有用户访问(案例2)。如果网络N中的用户A与网络O中的用户A不同(向特定网络中的特定用户发送消息),则用户和网络不是多对多关系,只是一对多关系。Hm您能进一步解释一下吗?一个用户可以在多个网络中,并且一个网络可以包含多个用户。这不是网络和用户之间的多对多关系吗?消息关系#3在网络中发送给用户的消息是一对多关系,但这是消息和网络用户之间的一对多关系;我认为消息到网络用户的关系不会影响用户到网络的关系。如果同一用户可以在多个网络中,那么向特定网络中的特定用户发送消息是没有意义的。我只需要将消息发送给用户。上面的示例只是为了说明。我的实际场景要复杂得多,但可以说这三种关系都有有效的用例。例如,我们可以有一条消息,当用户是某个特定网络的一部分时,该消息应该只能被用户访问(案例3),或者一条消息总是可以被用户访问(无论网络如何)(案例1),或者一条消息可以被在某个特定时刻处于给定网络中的所有用户访问(案例2).在这种方法中,有没有定义外键约束的方法?不是以MySQL为例
    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;