I’m trying to design a SQL schema to represent a folder structure for e-mail, however I’m having some difficulty and while there are a number of other questions on stack overflow regarding SQL schemata to represent hierachical folder/email structures, none seem to answer all the questions I have.
My requirement is as follows:
- Each user has a mailbox and this mailbox contains a number of
compulsory folders (e.g. Inbox or Sent). - Each mailbox may also contain custom folders that the user can create to organise their mail.
- Folders can appear in a heirachy but compulsory folders MUST be at the root level.
There are a number of things that I would like to enforce at database level, but have been unable to accomodate them all.
- Compulsory folders may only appear once per mailbox. It should be impossible to insert another compulsory folder into the same mailbox.
- In terms of hierachy, parent and child folders must all belong to the same mailbox.
So far I have two tables, a “Folders” table which will contain all folders for all mailboxes and a “SystemFolders” table which contains the definitions of compulsory tables:
CREATE TABLE Folders(
ID Int
, Mailbox_ID Int
, Name varchar(25)
, Parent_ID Int
, SystemFolder_ID Int
, PRIMARY KEY (ID)
);
CREATE TABLE SystemFolders(
ID Int
, Name varchar(25)
, PRIMARY KEY (ID)
);
My problem now is how to add the constraints.
- How can I enforce hierachical integrity (parent or child folders must all belong to same mailbox)?**
- How can I ensure that only one system folder of each type can exist within the context of a single mailbox?**
Ideally the solution would not be specific to any particular flavour of SQL. Any help appreciated.
Because you are replicating a file structure, not just the system folders but all folders in a particular level will have to have unique names. You can enforce this by creating a uniqueness constraint. This syntax should work on most systems:
Update: To also require a unique SystemFolder_ID, just add another constraint as above, but on SystemFolder_ID:
For each mailbox, there can be no duplicate names in a particular folder.
This is more complicated. You might be able to do it with check constraints, though it would be dependent on your implementation (and it might not be a very good idea). Another, probably better, option would be creating a trigger for this. In either case, you would have to verify both the parent of a particular row and all children of a particular row. If you don’t do both, then later modifications could indirectly corrupt things.