Означает ли использование идентификации многозначных отношений наличие одинаковых ключей PRIMARY и FOREIGN в одной таблице?

Оригинальное название: если PRIMARY KEY и внешний ключ INDEX установлены для одинаковых имен столбцов, означает ли это, что один и тот же индекс дублируется?

Пример:

Я сгенерировал таблицу, используя MySQL Workbench и используя Идентификацию отношений с другими таблицами. Это означает, что 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 KEY а также INDEX определить те же столбцы. Означает ли это, что у меня будет два отдельных "физических" показателя на столе? Разве это не расточительно?

Мне интересно, является ли это необходимым злом выявления отношений.

1 ответ

Решение

Я не вижу этого, если я понимаю ваш вопрос. Ниже 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;

Таким образом, если существует адекватный ключевой (скажем, составной) крайний левый блок, достаточный для повторного использования, то механизм БД не будет автоматически создавать индекс Хелпера.

Например, если у вас был ключ (PK или другой), который был составным из (col1,col2,col3,col5), и ваш FK требовал использования (col1,col2), то новый индекс не является auto-gen "d.

Если необходимость в FK была для (colX,col1,col2), то вышеприведенное (col1,col2,col3,col5) бесполезно (крайний левый приоритет), и механизму БД потребуется создать индекс помощника FK.

Другие вопросы по тегам