【问题标题】:MySQL table design: Primary Foreign Multi-Column Key possible?MySQL 表设计:Primary Foreign Multi-Column Key 可能吗?
【发布时间】:2010-01-10 01:46:32
【问题描述】:

我目前正在考虑“朋友”表的数据库设计(多对多,存储用户之间的友谊)。

列:user_id friend_id

首选多列主键而不是额外的“friendship_id”列是否有意义?

如果是这样,我可以为两列添加外键吗?

【问题讨论】:

    标签: mysql database-design foreign-keys


    【解决方案1】:

    数据库处理此问题的最快方式可能是

    PRIMARY KEY ('user_id', 'friend_id')
    

    这确保它们是唯一的组合,同时两者都可以是外键。 也许你也想要一个关于 user_id 的索引,这样你就可以快速查找一个用户的所有朋友。

    INDEX ('user_id')
    

    不需要代理键,因为它会产生与维护表相关的额外工作。无论如何,这些组合都是独一无二的,而且您已经知道这两个 ID。

    【讨论】:

    • 没有自动生成的外键索引吗?
    • 可能。但具体一点也无妨。
    • 也许“friend_id”上的索引会更重要。 PK 声明将按该顺序在“user_id”和“friend_id”上生成索引,并且在查找特定 user_id 时将使用该复合索引。但是在friend_id上查找需要一个单独的索引。
    • 这取决于相关的数据库引擎。
    【解决方案2】:

    是的,您确实可以创建两个外键列,这通常是这种关联的设计方式。您还可以指定两列一起是唯一的,因此 (user_id,friend_id) 是唯一的。

    编辑:这方面的一个例子可能是:

    CREAT TABLE friendship (
        user_id INT,
        friend_id INT,
        FOREIGN KEY (user_id) REFERENCES user(id),
        FOREIGN KEY (friend_id) REFERENCES user(id),
        UNIQUE(user_id,friend_id)
    );
    

    【讨论】:

      【解决方案3】:

      我会选择单列代理键 (friendship_id) 加上唯一约束和 user_idfriend_id 组合上的索引。我会使用代理键来保持一致性,因为您似乎在其他表上使用代理(user_id 可能是指 user 上的列 id 等)。

      【讨论】:

        【解决方案4】:

        如果你需要跟踪友谊事件,你可以有一个friendship_id(比如你想要一个框,列出系统中最近的友谊并带有详细信息的链接),但如果你的数据模型不需要这种关系,一个多列主键就可以了。你可以像这样创建它:

        create table friend (
          user_id int,
          friend_id int,
          foreign key (user_id) references user(id),
          foreign key (friend_id) references user(id),
          primary key (user_id, friend_id)
        );
        

        在由外键约束单独创建的两列上都有一个索引,在 user_id、friend_id 上会有一个多列唯一索引。

        【讨论】:

          猜你喜欢
          • 2016-11-12
          • 2021-06-29
          • 1970-01-01
          • 2012-11-20
          • 2012-02-08
          • 1970-01-01
          • 2021-05-14
          • 2021-11-11
          • 2022-12-21
          相关资源
          最近更新 更多