使用识别 Many-To-One 关系是否意味着必须在同一个 table 上具有重复的主键和外键?

Does using Identifying Many-To-One Relationship means having to have duplicate PRIMARY and FOREIGN keys on same table?

原标题:当PRIMARY KEY和外键INDEX设置在相同的列名上,是否意味着相同的索引被复制了?

示例:

我使用 MySQL Workbench 生成了 table,并使用识别与其他 table 的关系。这意味着在我的例子中 PRIMARY KEY 包含 FOREIGN KEY 列。

CREATE TABLE IF NOT EXISTS `price_history` (
`amount` DECIMAL NULL,
  `date_start` DATE NULL,
  `date_end` DATE NULL,
  `product_id` INT NOT NULL,
  `category_id` INT NOT NULL,
  `priceitem_id` INT NOT NULL,
  PRIMARY KEY (`product_id`, `category_id`, `priceitem_id`),
  INDEX `fk_idx` (`product_id` ASC, `category_id` ASC, `priceitem_id` ASC),
ENGINE = InnoDB;

我注意到 PRIMARY KEYINDEX 定义了相同的列。这是否意味着我将在 table 上有两个单独的 "physical" 索引?会不会很浪费?

我想知道这是否是识别关系的必然之恶。

如果我理解你的问题,我不会看到这种情况发生。在下面,price_history 没有重复的数据库引擎自动创建的索引。

create table A
(   `product_id` INT NOT NULL,
    `category_id` INT NOT NULL,
    `priceitem_id` INT NOT NULL,
    PRIMARY KEY (`product_id`, `category_id`, `priceitem_id`)

)ENGINE=INNODB;

CREATE TABLE IF NOT EXISTS `price_history` (
    `amount` DECIMAL NULL,
    `date_start` DATE NULL,
    `date_end` DATE NULL,
    `product_id` INT NOT NULL,
    `category_id` INT NOT NULL,
    `priceitem_id` INT NOT NULL,
    PRIMARY KEY (`product_id`, `category_id`, `priceitem_id`),
    FOREIGN KEY `f` (`product_id`, `category_id`, `priceitem_id`) references A(`product_id`, `category_id`, `priceitem_id`)
)ENGINE = InnoDB;

show create table price_history;
CREATE TABLE `price_history` (
   `amount` decimal(10,0) DEFAULT NULL,
   `date_start` date DEFAULT NULL,
   `date_end` date DEFAULT NULL,
   `product_id` int(11) NOT NULL,
   `category_id` int(11) NOT NULL,
   `priceitem_id` int(11) NOT NULL,
   PRIMARY KEY (`product_id`,`category_id`,`priceitem_id`),
   CONSTRAINT `price_history_ibfk_1` FOREIGN KEY (`product_id`, `category_id`, `priceitem_id`) 
      REFERENCES `a` (`product_id`, `category_id`, `priceitem_id`)
 ) ENGINE=InnoDB;

 CREATE TABLE IF NOT EXISTS `price_history` (
    `amount` DECIMAL NULL,
    `date_start` DATE NULL,
    `date_end` DATE NULL,
    `product_id` INT NOT NULL,
    `category_id` INT NOT NULL,
    `priceitem_id` INT NOT NULL,
    PRIMARY KEY (`product_id`, `category_id`, `priceitem_id`),
    FOREIGN KEY `f` (`product_id`, `category_id`, `priceitem_id`) references A(`product_id`, `category_id`, `priceitem_id`)
)ENGINE = InnoDB;

show create table A;
CREATE TABLE `a` (
   `product_id` int(11) NOT NULL,
   `category_id` int(11) NOT NULL,
   `priceitem_id` int(11) NOT NULL,
   PRIMARY KEY (`product_id`,`category_id`,`priceitem_id`)
 ) ENGINE=InnoDB;

 CREATE TABLE IF NOT EXISTS `price_historyBBB` (
    id int auto_increment primary key,
    `amount` DECIMAL NULL,
    `date_start` DATE NULL,
    `date_end` DATE NULL,
    `product_id` INT NOT NULL,
    `category_id` INT NOT NULL,
    `priceitem_id` INT NOT NULL,
    FOREIGN KEY `g` (`product_id`, `category_id`, `priceitem_id`) references A(`product_id`, `category_id`, `priceitem_id`)
)ENGINE = InnoDB;

show create table price_historyBBB;
CREATE TABLE `price_historybbb` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `amount` decimal(10,0) DEFAULT NULL,
   `date_start` date DEFAULT NULL,
   `date_end` date DEFAULT NULL,
   `product_id` int(11) NOT NULL,
   `category_id` int(11) NOT NULL,
   `priceitem_id` int(11) NOT NULL,
   PRIMARY KEY (`id`),
   KEY `g` (`product_id`,`category_id`,`priceitem_id`),
   CONSTRAINT `price_historybbb_ibfk_1` FOREIGN KEY (`product_id`, `category_id`, `priceitem_id`) 
      REFERENCES `a` (`product_id`, `category_id`, `priceitem_id`)
 ) ENGINE=InnoDB;

show indexes from price_history;
show indexes from price_historyBBB;

因此,如果存在足够的键(例如,组合键)最左边的块足以重复使用,那么数据库引擎将不会自动创建 Helper指数.

例如,如果您有一个键(PK 或其他键)是 (col1,col2,col3,col5) 的组合,并且您的 FK 要求使用 (col1,col2),那么一个新索引不是自动生成的。

如果需要 FK 是为了 (colX,col1,col2) 那么上面的 (col1,col2,col3,col5) 是没有用的(最左边的优先级)并且数据库引擎需要创建一个FK帮手指数.