使 AUTO_INCREMENT 在更改父 ID 时重置自身

Make AUTO_INCREMENT reset itself on change of Parent ID

在我的项目分配中,我希望 PRIMARY KEY 的一部分在另一部分更改值后重置。例如:

CREATE TABLE shopping_center(
    centerID INTEGER AUTO_INCREMENT,
    centerName CHAR(50),
    CONSTRAINT center_PK PRIMARY KEY(centerID));

CREATE TABLE staff(
    staffID INTEGER AUTO_INCREMENT,
    centerID INTEGER,
    name VARCHAR(50),
    CONSTRAINT staff_PK PRIMARY KEY(staffID, centerID));

ALTER TABLE staff
    ADD CONSTRAINT staff_FK
    FOREIGN KEY(centerID) 
    REFERENCES shopping_center(centerID);

在这种情况下,MySQL 的 AUTO_INCREMENT 功能无法正常工作。当我插入这些值时(请记住 ID 上的 AUTO_INCREMENT 功能,因为我没有在 INSERT 语句中定义 centerIDstaffID):

INSERT INTO shopping_center (centerName) VALUES("A Shopping Center");
INSERT INTO shopping_center (centerName) VALUES("Another Shopping Center");

INSERT INTO staff (centerID, name) VALUES(1, "Staffmember 1 in centerID 1");
INSERT INTO staff (centerID, name) VALUES(1, "Staffmember 2 in centerID 1");
INSERT INTO staff (centerID, name) VALUES(2, "Staffmember 1 in centerID 2");
INSERT INTO staff (centerID, name) VALUES(2, "Staffmember 2 in centerID 2");

我得到这个结果:

SELECT centerID, staffID, name FROM staff; 
+----------+---------+-----------------------------+
| centerID | staffID | name                        |
+----------+---------+-----------------------------+
|         1|        1| Staffmember 1 in centerID 1 |
|         1|        2| Staffmember 2 in centerID 1 |
|         2|        3| Staffmember 1 in centerID 2 |
|         2|        4| Staffmember 2 in centerID 2 |
+----------+---------+-----------------------------+

但我想要的是 staffIDcenterID 更改值时重置为 1。这是我想要的结果(注意staffID值的变化):

SELECT centerID, staffID, name FROM staff; 
+----------+---------+-----------------------------+
| centerID | staffID | name                        |
+----------+---------+-----------------------------+
|         1|        1| Staffmember 1 in centerID 1 |
|         1|        2| Staffmember 2 in centerID 1 |
|         2|        1| Staffmember 1 in centerID 2 |
|         2|        2| Staffmember 2 in centerID 2 |
+----------+---------+-----------------------------+

由于在这种情况下所需的 PRIMARY KEY 始终是唯一的,我不明白为什么这不起作用。我想在这里实现的目标有解决方案吗?

与auto_increment无关。

我认为您应该以不同的方式设计 table。你现在设计的是一对多关系,但你需要多对多。

这样'Staff member 1'就可以成为两家购物中心的员工。您应该创建中间 table 链接 shopping_centerstaff

这是对您的 table 结构的更正。

CREATE TABLE shopping_center(
centerID INTEGER AUTO_INCREMENT,
centerName CHAR(50),
CONSTRAINT center_PK PRIMARY KEY(centerID));

CREATE TABLE staff(
staffID INTEGER AUTO_INCREMENT,
name VARCHAR(50),
CONSTRAINT staff_PK PRIMARY KEY(staffID, centerID));

CREATE TABLE shopping_center2staff(
centerID INTEGER,
staffID INTEGER,
CONSTRAINT center_PK PRIMARY KEY(centerID, staffID));

ALTER TABLE shopping_center2staff
ADD CONSTRAINT staff_FK
FOREIGN KEY(staffID) 
REFERENCES staff(staffID);

ALTER TABLE shopping_center2staff
ADD CONSTRAINT center_FK
FOREIGN KEY(centerID) 
REFERENCES shopping_center(centerID);

INSERT INTO shopping_center (centerName) VALUES("A Shopping Center");
INSERT INTO shopping_center (centerName) VALUES("Another Shopping Center");

INSERT INTO staff (name) VALUES("Staffmember 1");
INSERT INTO staff (name) VALUES("Staffmember 2");

INSERT INTO `shopping_center2staff` (centerID, staffID) VALUES(1,1);
INSERT INTO `shopping_center2staff` (centerID, staffID) VALUES(1,2);
INSERT INTO `shopping_center2staff` (centerID, staffID) VALUES(2,1);
INSERT INTO `shopping_center2staff` (centerID, staffID) VALUES(2,2);

SELECT sc2s.centerID, sc2s.staffID, name 
FROM shopping_center2staff as sc2s
JOIN `staff` as s on sc2s.staffID = s.staffID
JOIN `shopping_center` as sc on sc2s.centerID = sc.centerID
order by sc2s.centerID; 

结果将是

+----------+---------+---------------+
| centerID | staffID | name          |
+----------+---------+---------------+
|        1 |       1 | Staffmember 1 |
|        1 |       2 | Staffmember 2 |
|        2 |       1 | Staffmember 1 |
|        2 |       2 | Staffmember 2 |
+----------+---------+---------------+

我会尽力回答你的问题,直到我解释发生了什么。

首先,您想要的功能在 MyISAM 存储引擎中可用(有点不同)。但是,事务和参照完整性不可用。

现在 auto_increment - 它为行提供唯一值。然而,它通过考虑 concurrency 来做到这一点 - 这意味着如果两个或更多人连接并执行一些工作,那么 auto_increment 将在这种情况下为两个人正确计算,如果他们正在访问相同的 table.

这意味着 auto_increment,对于每次插入,只会递增。与任何记录都没有关系,这就是为什么 auto_increment 很快并且您可以 100% 确定地获得唯一标识符。

发生的另一个有用的事情是 InnoDB 根据这个数字执行聚类。换句话说,它使用这个数字来执行其内部数据结构平衡,以便在稍后阶段提供性能(读取/更新记录)。

为什么这很重要——如果你改变这个数字,InnoDB 将重新平衡它的 B 树,这需要一些时间来完成。这意味着 - 永远不要触摸主键值

然而,所有这些都不是真正相关的。相关的是以下 - 为什么 你需要 staffID 来改变?如果你保持原样,就不会发生什么坏事。