gpt4 book ai didi

mysql - 应该使用替代 PK 加唯一列还是使用唯一列的自然 PK?

转载 作者:行者123 更新时间:2023-11-29 20:59:43 27 4
gpt4 key购买 nike

已知:tX_1.name 永远不能为 NULL,长度可变,最多 45 个字符,并且必须始终是唯一的。

哪些因素会影响是否应使用代理 PK 加唯一列(架构 1)或 PK 自然键是否使用第一个表的唯一列作为其 PK(架构 2)?

enter image description here架构1

CREATE TABLE IF NOT EXISTS t1_1 (
idt1_1 INT NOT NULL AUTO_INCREMENT,
name VARCHAR(45) NOT NULL,
data VARCHAR(45) NULL,
PRIMARY KEY (idt1_1),
UNIQUE INDEX name_UNIQUE (name ASC))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS t1_2 (
idt1_2 INT NOT NULL AUTO_INCREMENT,
t1_1_idt1_1 INT NOT NULL,
data VARCHAR(45) NULL,
PRIMARY KEY (idt1_2),
INDEX fk_t1_2_t1_1_idx (t1_1_idt1_1 ASC),
CONSTRAINT fk_t1_2_t1_1
FOREIGN KEY (t1_1_idt1_1)
REFERENCES t1_1 (idt1_1)
ON DELETE CASCADE
ON UPDATE NO ACTION)
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS t1_3 (
idt1_3 INT NOT NULL AUTO_INCREMENT,
data VARCHAR(45) NULL,
PRIMARY KEY (idt1_3))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS t1_1_has_t1_3 (
t1_1_idt1_1 INT NOT NULL,
t1_3_idt1_3 INT NOT NULL,
PRIMARY KEY (t1_1_idt1_1, t1_3_idt1_3),
INDEX fk_t1_1_has_t1_3_t1_31_idx (t1_3_idt1_3 ASC),
INDEX fk_t1_1_has_t1_3_t1_11_idx (t1_1_idt1_1 ASC),
CONSTRAINT fk_t1_1_has_t1_3_t1_11
FOREIGN KEY (t1_1_idt1_1)
REFERENCES t1_1 (idt1_1)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_t1_1_has_t1_3_t1_31
FOREIGN KEY (t1_3_idt1_3)
REFERENCES t1_3 (idt1_3)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

架构2

CREATE TABLE IF NOT EXISTS t2_1 (
name VARCHAR(45) NOT NULL,
data VARCHAR(45) NULL,
PRIMARY KEY (name))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS t2_2 (
idt2_2 INT NOT NULL AUTO_INCREMENT,
t2_1_name VARCHAR(45) NOT NULL,
data VARCHAR(45) NULL,
PRIMARY KEY (idt2_2),
INDEX fk_t2_2_t2_11_idx (t2_1_name ASC),
CONSTRAINT fk_t2_2_t2_11
FOREIGN KEY (t2_1_name)
REFERENCES t2_1 (name)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS t2_3 (
idt2_3 INT NOT NULL AUTO_INCREMENT,
data VARCHAR(45) NULL,
PRIMARY KEY (idt2_3))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS t2_1_has_t2_3 (
t2_1_name VARCHAR(45) NOT NULL,
t2_3_idt2_3 INT NOT NULL,
PRIMARY KEY (t2_1_name, t2_3_idt2_3),
INDEX fk_t2_1_has_t2_3_t2_31_idx (t2_3_idt2_3 ASC),
INDEX fk_t2_1_has_t2_3_t2_11_idx (t2_1_name ASC),
CONSTRAINT fk_t2_1_has_t2_3_t2_11
FOREIGN KEY (t2_1_name)
REFERENCES t2_1 (name)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_t2_1_has_t2_3_t2_31
FOREIGN KEY (t2_3_idt2_3)
REFERENCES t2_3 (idt2_3)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

最佳答案

t1 和 t3 之间的多对多关系在某些方面效率低下。请参阅my blog .

我经常使用 UNIQUE key 进行 PK。我审阅了大量我设计的表格;只有 1/3 的 PK 具有 AUTO_INCRMENT。一些注意事项(假设 InnoDB):

  • 每个辅助 key 包含PK的所有列;这可能导致体积庞大。
  • 由于 PK 的“聚类”,通过 PK 查找行比通过辅助键查找行更快。
  • FOREIGN KEY 是有代价的——需要进行查找来检查隐含的“约束”。通常,代码的编写方式不会发生 FK 违规,从而使 FK 产生不必要的开销。 (其他人说 FK 很“好”。)
  • 一个有一千行的表是如此之小,所以这些问题并不是很重要。一百万行将使它们变得重要。十亿行,我们需要讨论更多的事情。

回到你的问题...

INT 为 4 个字节; VARCHAR 是可变的,您尚未提供平均长度。因此,很难比较。您的架构将会变得更加复杂。您将添加更多列和更多索引,因此我关于二级索引的评论的相关性尚未确定。您可能认为 45 还不够。等等等等

底线:抛硬币决定从哪个架构开始,然后在架构成熟时从中学习。

关于mysql - 应该使用替代 PK 加唯一列还是使用唯一列的自然 PK?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37337672/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com