Reputation: 836
Note: This question may possibly be poorly asked as my knowledge of SQL is quite limited.
We have 3 tables, BUILDINGS, FLOORS, ROOMS.
BUILDINGS contains the columns: Building_ID(its primary key), and Name(its name)
FLOORS contains the columns: Floor_ID(its primary key), Name(its name), and Building_ID(foreign key to BUILDINGS' primary key)
ROOMS contains the columns: Room_ID(its primary key), Name(its name), Building_ID(foreign key to BUILDINGS' primary key), and Floor_ID(foreign key to FLOORS' primary key)
My problem is, if I have two buildings, 1 and 2, and two floors, 1 and 2, if floor 1 belongs to building 1, and floor 2 belongs to building 2 (that is building 2 has no floor 1, and building 1 has no floor 2) it is possible to add a room which is in building 1, floor 2, even though this should not exist.
How can I correct my structure to ensure only valid rooms may be added? And if I were to scale out again, another table DESKS which would have an associated BUILDING, FLOOR, and ROOM would this solution still work?
Upvotes: 2
Views: 41
Reputation: 3523
The issue is one of normalization. In your ROOMS table, do not include the foreign key Building_ID. The connection between ROOM and BUILDINGS is via the FLOORS table. A second connection is unnecessary, since any queries you run can join through those tables to get the building name.
Upvotes: 1
Reputation: 48197
You create 3 tables. Room only need to reference floor. And browsing floors you will know buildings
CREATE TABLE Building
(`building_id` int, `name` varchar(6))
;
CREATE TABLE floor
(`floor_id` int, `building_id` int, `name` varchar(7))
;
CREATE TABLE room
(`room_id` int, `floor_id` int, `name` varchar(9))
;
Querys
SELECT *
FROM Building;
SELECT *
FROM Building B;
INNER JOIN floor F
ON B.building_id = F.building_id
;
SELECT *
FROM Building B;
INNER JOIN floor F
ON B.building_id = F.building_id
INNER JOIN Room R
ON F.room_id = R.room_id
;
And for DESKS
CREATE TABLE desks
(`desk_id` int, `room_id` int, `name` varchar(9))
;
SELECT *
FROM Building B;
INNER JOIN floor F
ON B.building_id = F.building_id
INNER JOIN Room R
ON F.floor_id = R.floor_id
INNER JOIN Desk D
ON R.room_id = D.room_id
;
Upvotes: 4