使用识别 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 KEY
和 INDEX
定义了相同的列。这是否意味着我将在 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帮手指数.
原标题:当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 KEY
和 INDEX
定义了相同的列。这是否意味着我将在 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帮手指数.