Here is some vanilla SQL:
CREATE TABLE RoomTypes
(
RoomType VARCHAR(12) NOT NULL,
UNIQUE (RoomType)
);
CREATE TABLE Zones
(
Zone VARCHAR(10) NOT NULL,
UNIQUE (Zone)
);
CREATE TABLE Rooms
(
RoomType VARCHAR(12) NOT NULL,
Zone VARCHAR(10) NOT NULL,
Name VARCHAR(30) NOT NULL,
UNIQUE (RoomType, Zone, Name),
FOREIGN KEY (RoomType) REFERENCES RoomTypes (RoomType),
FOREIGN KEY (Zone) REFERENCES Zones (Zone)
);
CREATE TABLE NumberedRooms
(
RoomType VARCHAR(12) NOT NULL,
Zone VARCHAR(10) NOT NULL,
Name VARCHAR(30) NOT NULL,
CHECK (RoomType = 'Numbered'),
UNIQUE (Name),
UNIQUE (RoomType, Zone, Name),
FOREIGN KEY (RoomType, Zone, Name)
REFERENCES Rooms (RoomType, Zone, Name)
);
CREATE TABLE AncillaryRooms
(
RoomType VARCHAR(12) NOT NULL,
Zone VARCHAR(10) NOT NULL,
Name VARCHAR(30) NOT NULL,
CHECK (RoomType = 'Ancillary'),
UNIQUE (Zone, Name),
UNIQUE (RoomType, Zone, Name),
FOREIGN KEY (RoomType, Zone, Name)
REFERENCES Rooms (RoomType, Zone, Name)
);
The CHECK
constraints will not be tested by mySQL e.g. do the tests yourself using triggers. Consider adding other tests e.g. that attribute Name
in table NumberedRooms
represents an integer.
The idea that every row in the supertype table Rooms
will have exactly one row in the union of AncillaryRooms
and NumberedRooms
. This is merely implied e.g. have 'helper' procs to add rows to both super- and subtype tables as a single operation and use triggers to ensure it is done.
Note NumberedRooms
has a simple key Name
alone, whereas AncillaryRooms
has a compound key on (Zone, Name)
. All three (non-lookup) tables have a key on (RoomType, Zone, Name)
throughout, allowing further subtype tables to referencing them and maintain integrity by further testing for valid RoomType
values.
creating a sub collection should offer better read performance
see http://docs.mongodb.org/manual/core/data-modeling/
I think it would be a good idea to add an id to each subdocument so it is easier to access it (because from your schema you may have identical items)
like:
{
username: "joe",
password: "...",
items: [
subid:{
text: "This is a task",
completed: 1
},
...
]
},
...
you can use subid = ObjectId()
to autogenerate ids, or create this in your application.
I don't think there is a problem with having thousands of items in a document just remember that the maximum document size is 16 megabytes.
Best Answer
It's best not to use the name of a "type" as an id - it is better to use generated id's and have a key called "type" in each document where you have a string value of "Home" etc