我正在研究一个从用户那里接收有关公共交通的数据的数据库。用户可以发送许多信息,但在数据库中强制执行完整性的重要性是:
到目前为止,我在服务器中强制执行完整性,但性能不是很好,我希望这在db本身中发生。 我想实现一种机制,每当用户发送一些信息时,检查数据库中是否存在提供的数据并且是否正确:例如,我想检查她是否提供了具有正确类型的正确现有车辆,并且是否正确停止。
事实上,车辆可以是两种类型(公共汽车或地铁),它可以有一个号码。对于每辆车,都有一个停靠点列表。所以我认为车辆列表应该是一张桌子,车辆。 止损列表位于另一个表格内,停止。
每辆车都有一个整数数组,指的是Stops的主键。
我一直在努力为此找到一个有效的解决方案。有人说要实现外键约束,但我真的不知道如何做到这一点。 其他人说要实施触发器。 我该怎么办?谢谢!
答案 0 :(得分:0)
三张桌怎么样?你有车辆,车站和特定车辆到达特定车站的事实。
BEGIN;
CREATE TABLE vehicles (
vtype char,
vnum int,
PRIMARY KEY (vtype, vnum)
);
CREATE TABLE stops (
vtype char,
stopnum int,
location text,
PRIMARY KEY (vtype, stopnum)
);
CREATE TABLE vehicle_stops (
vtype char,
vnum int NOT NULL,
stopnum int NOT NULL,
CONSTRAINT valid_vehicle FOREIGN KEY (vtype, vnum) REFERENCES vehicles,
CONSTRAINT valid_stop FOREIGN KEY (vtype, stopnum) REFERENCES stops,
PRIMARY KEY (vtype,vnum,stopnum)
);
INSERT INTO vehicles VALUES
('B', 453),
('S', 111);
INSERT INTO stops VALUES
('B', 1001, 'Trafalgar Square'),
('B', 1002, 'Marylebone'),
('S', 2001, 'Charing Cross'),
('S', 2002, 'Embankment');
INSERT INTO vehicle_stops VALUES
('B', 453, 1001),
('B', 453, 1002),
('S', 111, 2001),
('S', 111, 2002);
INSERT INTO vehicle_stops VALUES ('B', 111, 2001);
ROLLBACK;
我们去了 - 453路公交车前往特拉法加广场和马里波恩,111地铁列车(或我们称之为伦敦的地铁列车)前往查林十字路口和堤岸。
vehicle_stops上的外键将阻止您输入不良的车辆/停止组合(如最后一次插入)。
答案 1 :(得分:0)
使用外键约束将是一种合理的方法。 (虽然使用触发器可以实现类似的效果,但明显滥用该机制。)
为了获得上帝的表现,最重要的是首先要有一个可重复的模式。
如果您的公共汽车和地铁号码相同(公共汽车4和地铁-4都存在),您只需要关注车辆类型和您的数据。然后使用车辆编号键入车辆表中的类型就足够了。 (车辆号码已经暗示了这种类型。)
如果可能发生数字冲突,您需要同时拥有两个键。
我会假设有不同车辆停在那里的车站。然后有一个与车辆和停靠点相关的匹配表(来自停止表)将是反映这种关系的合理方式。
匹配ztale的主键是数据表的完美外键,因为这意味着车辆存在并停止,并确保车辆在给定停止时停止。
所以你会有(用于说明的伪代码):
数据表:
foreign key (pk_vehicle_stop_match) REFERENCES vehicle_stop_match(pk)
vehicle_stop_match表:
foreign key (fk_vehicle) REFERENCES vehicles(pk)
foreign key (fk_stop) REFERENCES stops(pk)
如果车辆类型不是每个车辆编号唯一,则车辆的主钥匙将包括车辆编号和车辆类型