规范化三个表

时间:2015-03-25 00:56:05

标签: mysql database

我在ERD正常化的过程中遇到了问题 - 这是我第一次这样做,所以请耐心等待。

我有三张桌子:Users; Clients;和Messages。它们之间关系的基数如下 -

  1. Users:Clients m n

    • 每个用户可能有一个或多个客户端。

    • 每个客户可能有一个或多个用户。

  2. Users:Messages为1: n

    • 每个用户都可以发送一条或多条消息。

    • 每条消息只能由一个客户发送。

  3. Clients:Messages为1: n

    • 每个客户端都可以发送一条或多条消息。

    • 每条消息只能由一个客户发送。

  4. 据我了解,我必须创建一个关联表来解析UsersClients之间的 m n 关系:let& #39; s我说我称之为user_client_list。我了解UsersClients中的两个PK现在将成为user_client_list中的FK,但是它的PK是新分配的ID计数器吗?

    此外,在解析Clients:MessagesUsers:Messages 1: n 关系时,我最终会得到外键client_iduser_idMessages表中。这对我来说有点奇怪 - 这是正确的做法吗?我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:1)

(将我的评论升级为答案)。

  1.   

    据我了解,我必须创建一个关联表来解析UsersClients之间的 m n 关系:let's我称之为表user_client_list。我了解UsersClients中的两个PK现在将成为user_client_list中的FK,但是它的PK是新分配的ID计数器吗?

    可以user_client_list中创建一个ID计数器并将其作为你的PK,但这通常不是必需的:除非可能存在多次完全相同的关系,否则PK可能只是是两个FK的化合物,例如(user_id, client_id)

  2.   

    此外,在解析Clients:MessagesUsers:Messages 1: n 关系时,我最终会得到外键client_iduser_idMessages表中。这对我来说有点奇怪 - 这是正确的做法吗?我在这里错过了什么吗?

    UsersClients合并到一个表(例如People)中更为典型,其中一列标记记录是代表用户还是客户端;那么Messages表只有一个 FK到你的新People表中。

    采用这种方法可能遇到的一个问题是,user_client_list关联表可能会允许不受欢迎的用户 - 用户和客户 - 客户关系。保护这些错误的关系将成为您的业务逻辑的一部分,通常在您的应用程序代码中实现 - 但如果需要,可以使用triggers在MySQL中强制执行:

    CREATE TRIGGER checkInsertedRelationship
      BEFORE INSERT ON user_client_list  -- also do the same for updates
      FOR EACH ROW BEGIN
        IF (SELECT type FROM People WHERE id = NEW.user_id) <> 'user' THEN
          SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 
            'The provided user_id does not represent a user type person';
        END IF;
    
        IF (SELECT type FROM People WHERE id = NEW.client_id) <> 'client' THEN
          SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT =
            'The provided client_id does not represent a client type person';
        END IF;
      END
    ;;