使 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
语句中定义 centerID
或 staffID
):
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 |
+----------+---------+-----------------------------+
但我想要的是 staffID
在 centerID
更改值时重置为 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_center
和 staff
这是对您的 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
来改变?如果你保持原样,就不会发生什么坏事。
在我的项目分配中,我希望 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
语句中定义 centerID
或 staffID
):
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 |
+----------+---------+-----------------------------+
但我想要的是 staffID
在 centerID
更改值时重置为 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_center
和 staff
这是对您的 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
来改变?如果你保持原样,就不会发生什么坏事。