三个字段合起来,限制的是整组重复
Week 10 的 ASMC 售票模型用 Ticket 连接购票人 Patron、场次 Concert 和座位 Seat。每条 Ticket 记录某个人买了哪场的哪个座位,购买日期也放在这条记录上。
如果用 Patron_ID、Concert_ID、Seat_ID 合成主键,数据库拒绝的是这三个值完全相同的两行。换一个购票人,整组值就变了,即使场次和座位都没有变,第二条记录仍能写进去。
下面是这个主键会接受的两条示例记录。
| 购票人 | 场次 | 座位 |
|---|---|---|
| P01 | C01 | S08 |
| P02 | C01 | S08 |
同一个座位在同一场被记在两个人名下,三个字段组成的主键却没有重复。主键选了哪些字段,就只会检查哪些字段的组合。
独立票号与售票限制分别处理
改用 Ticket_ID 作为主键,会给每张票一个独立编号。上面的两行只要拿到不同票号,仍然都能保存。票号本身没有规定同一个场次、座位组合只能出现一次。
ASMC 给出的六条关系规则没有明说同场同座只能卖一次。若增加这条运营规则,就给 Concert_ID 和 Seat_ID 加联合 UNIQUE 约束:
UNIQUE(Concert_ID, Seat_ID)
它比较整组场次与座位。已有 C01、S08 后,再存一条 C01、S08 就会被拒绝,无论购票人和票号是否不同。Patron_ID、Concert_ID 和 Seat_ID 仍作为外键保留,让这张票连到对应的人、场次和座位。
同一个座位还要能卖给另一场
只把 Seat_ID 设为 UNIQUE,会让 C01 卖出的 S08 无法再用于 C02。限制范围扩大到了所有场次,连合法的跨场次售票也被挡住。
检查这个设计时,可以沿用同一个座位试两次。C01、S08 再卖一次,应被新增的联合约束拒绝;C02、S08 则应允许,因为场次已经不同。两次结果合起来,才能说明约束限制的是同场重售,并保留了跨场次使用座位的能力。






