在项目作业中,我希望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
语句中定义staffID
或INSERT
:
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
始终是唯一的,因此我不明白为什么这不应该起作用。我想在这里实现什么解决方案?
答案 0 :(得分:1)
我会尝试回答你的问题,直到我解释发生了什么。
首先,您想要的功能在MyISAM存储引擎中可用(有点,有一点扭曲)。但是,交易和参照完整性不可用。
现在为auto_increment
- 它为行提供唯一值。但是,它通过考虑并发性来实现这一点 - 这意味着如果两个或更多人连接并执行某些工作,auto_increment
将在这种情况下为两个人正确计算,如果他们正在访问同桌。
这意味着每个插入的auto_increment
只会增加。与任何记录都没有任何关系,这就是为什么auto_increment
很快并且您获得100%确定性的唯一标识符。
另一个有用的事情是InnoDB根据这个数字执行聚类。换句话说,它使用此数字来执行其内部数据结构平衡,以便在稍后阶段提供性能(读取/更新记录)。
现在为什么这很重要 - 如果你改变这个数字,InnoDB会以任何方式重新平衡它的B-Tree,这需要一些时间。这意味着 - 永远不会触及主键值。
但是,所有这些都不是真正相关的。与以下内容相关的是 - 为什么您需要staffID
进行更改?如果按原样保留,可能会发生任何不好的事情。
答案 1 :(得分:0)
它与auto_increment无关。
我认为你应该以不同的方式设计你的表格。你现在设计的是一对多关系,但你需要多对多。
这样'工作人员1'可以成为两个购物中心的员工。您应该创建链接shopping_center
和staff
以下是对表结构的更正。
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 |
+----------+---------+---------------+