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

时间:2015-04-24 11:42:39

标签: mysql database combinations auto-increment

在项目作业中,我希望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功能,因为我没有在centerID语句中定义staffIDINSERT

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始终是唯一的,因此我不明白为什么这不应该起作用。我想在这里实现什么解决方案?

2 个答案:

答案 0 :(得分:1)

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

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

现在为auto_increment - 它为行提供唯一值。但是,它通过考虑并发性来实现这一点 - 这意味着如果两个或更多人连接并执行某些工作,auto_increment将在这种情况下为两个人正确计算,如果他们正在访问同桌。

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

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

现在为什么这很重要 - 如果你改变这个数字,InnoDB会以任何方式重新平衡它的B-Tree,这需要一些时间。这意味着 - 永远不会触及主键值

但是,所有这些都不是真正相关的。与以下内容相关的是 - 为什么您需要staffID进行更改?如果按原样保留,可能会发生任何不好的事情。

答案 1 :(得分:0)

它与auto_increment无关。

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

这样'工作人员1'可以成为两个购物中心的员工。您应该创建链接shopping_centerstaff

的中间表

以下是对表结构的更正。

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 |
+----------+---------+---------------+