我在ERD正常化的过程中遇到了问题 - 这是我第一次这样做,所以请耐心等待。
我有三张桌子:Users
; Clients
;和Messages
。它们之间关系的基数如下 -
Users:Clients
m : n
每个用户可能有一个或多个客户端。
每个客户可能有一个或多个用户。
Users:Messages
为1: n
每个用户都可以发送一条或多条消息。
每条消息只能由一个客户发送。
Clients:Messages
为1: n
每个客户端都可以发送一条或多条消息。
每条消息只能由一个客户发送。
据我了解,我必须创建一个关联表来解析Users
和Clients
之间的 m : n 关系:let& #39; s我说我称之为user_client_list
。我了解Users
和Clients
中的两个PK现在将成为user_client_list
中的FK,但是它的PK是新分配的ID计数器吗?
此外,在解析Clients:Messages
和Users:Messages
1: n 关系时,我最终会得到外键client_id
和user_id
在Messages
表中。这对我来说有点奇怪 - 这是正确的做法吗?我在这里错过了什么吗?
答案 0 :(得分:1)
(将我的评论升级为答案)。
据我了解,我必须创建一个关联表来解析
Users
和Clients
之间的 m : n 关系:let's我称之为表user_client_list
。我了解Users
和Clients
中的两个PK现在将成为user_client_list
中的FK,但是它的PK是新分配的ID计数器吗?
你可以在user_client_list
中创建一个ID计数器并将其作为你的PK,但这通常不是必需的:除非可能存在多次完全相同的关系,否则PK可能只是是两个FK的化合物,例如(user_id, client_id)
。
此外,在解析
Clients:Messages
和Users:Messages
1: n 关系时,我最终会得到外键client_id
和user_id
在Messages
表中。这对我来说有点奇怪 - 这是正确的做法吗?我在这里错过了什么吗?
将Users
和Clients
合并到一个表(例如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
;;