我有两个表,分别是主键为Hotel_ID
的酒店和主键为Staff_ID
的员工。
酒店表还具有另一列,Manager_ID
引用了Staff_ID
的Staff。
员工表使用其列H_ID
引用Hotel_ID来指示员工在哪家酒店工作。
我一直在试图找出是否有可能限制Manager_ID
的允许值,以便仅可以将同一家酒店的工作人员任命为经理。
我知道这里有一个交叉引用,但我的理解是这应该不是问题。有人可以告诉我如何将其合并到Hotel表的create语句中吗?
答案 0 :(得分:0)
您可以在role
表中创建标志或staff
列,以指示此人是经理还是在酒店中扮演特定角色。您将不再需要Manager_Id
表中的hotel
列。这些表可能看起来像这样:
Hotel
- Id
- Name
Staff
- Id
- Hotel_Id
- IsManager
- Firstname
- Lastname
添加新内容时,可以设置IsManager
标志,以表明此人是酒店的经理,由Hotel_Id
列中的ID标识。
答案 1 :(得分:0)
您可以添加多列外键,以不仅选择人员ID,还可以选择hotel_id
表中分配的hotel
。这将导致看起来很奇怪的表结构,如下所示:
Hotel
- Id
- Name
- Manager_Id
- Hotel_Id
Staff
- Id
- Hotel_Id
- IsManager
- Firstname
- Lastname
这看起来特别奇怪,因为您在Hotel
表中有两次相同的ID。为了使其正常工作,当使用Id
列时,您必须添加触发器以验证Hotel_Id
和Hotel_Id
的值是否相同。并且由于您有某种圆形参考(Staff
通过Hotel
引用了Hotel_Id
表,Hotel
通过Staff
引用了Manager_Id
表)您必须运行ALTER TABLE
语句以添加其他列Manager_Id
和Hotel_Id
。查询可能看起来像这样:
CREATE TABLE Hotel
(
Id INT AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(30)
);
CREATE TABLE Staff
(
Id INT AUTO_INCREMENT PRIMARY KEY,
Hotel_Id INT NOT NULL,
FirstName VARCHAR(30),
LastName VARCHAR(30),
FOREIGN KEY (Hotel_Id) REFERENCES Hotel(Id),
INDEX (Id, Hotel_Id)
);
第二个索引用于Hotel
表中的外键:
ALTER TABLE Hotel ADD Manager_ID INT NULL;
ALTER TABLE Hotel ADD Hotel_ID INT NULL;
ALTER TABLE Hotel ADD FOREIGN KEY (Manager_ID, Hotel_ID) REFERENCES Staff(Id, Hotel_Id);
不幸的是,您不能在CHECK CONSTRAINT
列的值上使用Id
。如果可以的话,可以编写如下内容:
ALTER TABLE Hotel ADD CONSTRAINT CHK_Hotel CHECK (Hotel_ID = Id OR Hotel_Id IS NULL);
这将验证来自Hotel_Id
表的Staff
列必须与Id
列相同。但是,您将收到以下错误消息:
检查约束“ CHK_Hotel”无法引用自动递增列。
您必须为INSERT
和UPDATE
查询添加触发器(请参阅类似Constant column value in MySQL table的问题)以进行检查。
以下示例查询显示了外键的工作方式:
INSERT INTO Hotel (Name) VALUES ('Some Hotel Name');
SELECT * FROM Hotel;
+----+-----------------+------------+----------+
| Id | Name | Manager_ID | Hotel_ID |
+----+-----------------+------------+----------+
| 1 | Some Hotel Name | NULL | NULL |
+----+-----------------+------------+----------+
INSERT INTO Staff (Hotel_Id, FirstName, LastName) VALUES (1, 'John', 'Doe');
SELECT * FROM Staff;
+----+----------+-----------+----------+
| Id | Hotel_Id | FirstName | LastName |
+----+----------+-----------+----------+
| 1 | 1 | John | Doe |
+----+----------+-----------+----------+
UPDATE Hotel SET Manager_Id = 1, Hotel_Id = 1 WHERE Id = 1;
SELECT * FROM Hotel;
+----+-----------------+------------+----------+
| Id | Name | Manager_ID | Hotel_ID |
+----+-----------------+------------+----------+
| 1 | Some Hotel Name | 1 | 1 |
+----+-----------------+------------+----------+
UPDATE Hotel SET Manager_Id = 1, Hotel_Id = 2 WHERE Id = 1;
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`Hotel`, CONSTRAINT `Hotel_ibfk_1` FOREIGN KEY (`Manager_ID`, `Hotel_ID`) REFERENCES `Staff` (`Id`, `Hotel_Id`))