【问题标题】:Multiple Primary/Foreign Keys多个主键/外键
【发布时间】:2011-11-28 14:42:00
【问题描述】:

老实说,我对主键和外键的工作方式有点模糊。有人告诉我在这里设置我的数据库,以便我有 7 个表,一个用于组织,一个用于类别、服务和文化,以及一个组织之间的三个交叉引用表,以及类别、服务和文化其他。

以 org_culture_xref 表为例。我有两列,一列是org_id,与组织表的org_id列(主键)相同。另一个是cult_id,与culture表的cult_id列(主键)相同。

我相信 org_culture_xref 表的两列都是主键和外键。 但是,这似乎不允许我为这两个列设置多个值。我希望能够在组织和文化之间建立多种关系 - 因为在每个组织中都可以与多个相关联文化,每种文化都可以与多个组织相关联。

如何确保两列都可以有多个值?

【问题讨论】:

    标签: mysql


    【解决方案1】:

    您所说的是多对多关系。使用交叉引用表,您走在正确的道路上。

    回顾一下外键和主键是如何工作的很好;每个表只能有一个主键,但可以有多个外键。但是,请注意,主键不必限于一列;您可以拥有一个跨越两列、三列或更多列的主键。

    您的解决方案是有两个外键,一个用于每个列/表关系,一个主键跨越两个表。

    这是一个我曾经使用过的表格的示例,它以多对多的关系将城市和县连接起来。

    mysql> show create table xref_cities_counties\G
    *************************** 1. row ***************************
           Table: xref_cities_counties
    Create Table: CREATE TABLE `xref_cities_counties` (
      `city_id` int(10) unsigned NOT NULL,
      `county_id` tinyint(3) unsigned NOT NULL,
      PRIMARY KEY  (`city_id`,`county_id`),
      KEY `city_id` (`city_id`),
      KEY `county_id` (`county_id`),
      CONSTRAINT `fk_xrefcitiescounties_cityid` FOREIGN KEY (`city_id`) REFERENCES `florida_cities` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
      CONSTRAINT `fk_xrefcitiescounties_countyid` FOREIGN KEY (`county_id`) REFERENCES `florida_counties` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    1 row in set (0.00 sec)
    
    mysql>
    mysql>
    mysql> describe xref_cities_counties;
    +-----------+---------------------+------+-----+---------+-------+
    | Field     | Type                | Null | Key | Default | Extra |
    +-----------+---------------------+------+-----+---------+-------+
    | city_id   | int(10) unsigned    | NO   | PRI |         |       |
    | county_id | tinyint(3) unsigned | NO   | PRI |         |       |
    +-----------+---------------------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    
    mysql>
    

    我建议对该主题进行一些额外的阅读。看来您的开端不错。

    【讨论】:

      【解决方案2】:

      您的交叉引用表的主键将是两列,这意味着两个 id 的组合必须是唯一的,但您可以在任一列中重复单个 id。

      下面是创建这样一个表的语句:

      CREATE TABLE `x` (
        `a_id` varchar(6) NOT NULL default '',
        `b_id` varchar(6) NOT NULL default '',
        PRIMARY KEY  (`a_id`,`b_id`)
      )
      

      问题本身和多对多关系的交叉引用表方法适用于大多数(如果不是全部)关系数据库,但由于我大约 10 年没有使用 mysql,我从 here 获得了该代码,里面好像有mysql具体代码的详细讨论。

      【讨论】:

      • 每当我尝试这样做时,它似乎都会替换以前的 ID。为什么会这样?
      • @JakeSmith 抱歉 - 正如我所说,我的 mysql 已经用完了,所以除了我给出的 create table 语句之外,我无法指导您正确创建主键的详细信息。
      • @JakeSmith 如果您已经构建了一个表,您不想使用该 CREATE TABLE 语句,因为该语句不包含任何外键定义。如果我没记错的话,你会想要使用ALTER TABLE 语句。
      【解决方案3】:

      org_culture_xref 的每一列都是一个外键:org_idorganization 的外键,cult_idculture 的外键。他们两个一起org_culture_xref的主键。

      所以,大致是这样的:

      CREATE TABLE org_culture_xref
      (
        org_id NUMERIC(10) NOT NULL,
        cult_id NUMERIC(10) NOT NULL,
        PRIMARY KEY (org_id, cult_id),
        FOREIGN KEY (org_id) REFERENCES organization (org_id),
        FOREIGN KEY (cult_id) REFERENCES culture (cult_id)
      );
      

      【讨论】:

      • 当我尝试删除我以前的表并使用此 SQL 代码时,它给了我一条关于无法创建表的错误消息。
      • @JakeSmith: org_idcult_id 具有 与它们的引用具有相同的类型,如表 org 中的 ord_id 和表中的 cult_idcult
      • @JakeSmith:我无权访问您的数据库,所以我需要对您没有明确说明的事情进行一些猜测。如果其中一个或多个猜测错误,您将收到一条错误消息。除非您给我更多信息,否则我无法提供任何帮助。 (例如,与其写“无法创建表的错误信息”,不如告诉我错误信息是什么?)
      猜你喜欢
      • 2011-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      • 1970-01-01
      • 2013-05-12
      • 2018-03-25
      相关资源
      最近更新 更多