Означает ли использование идентификации многозначных отношений наличие одинаковых ключей 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.