Search code examples
mysqldatabasenormalization

Trouble with database normalisation


First of all, let me apologise in advance if this is a question with an obvious answer. I haven't Googled for a solution, as I really have no idea what to Google for.

As a favour to a friend who is a member of a charitable organisation, I have built him a fairly complex Web site. When I received the original specs for the site, he said that he wanted the facility to publish regional newsletters. I already had a regions table in the database, since fraternities within the organisation must reside within a region. No problem, I implemented that without a hitch. The newsletters table now sports a foreign key with correlates to the relevant id in the regions table.

Now he's come back to me and said that they'd also like the facility for a national newsletter, and I'm not quite sure what to do. I've considered setting the foreign key column to 0 to indicate that it's a national newsletter, but what would happen if he decided there was another type of newsletter that he wanted to implement? I think this is generally a bad idea.

I've considered adding an extra column to the newsletters table, which would reference to another table, which would perhaps contain these new types, but that seems a bit odd to me, and seems a bit hackish.

I've considered duplicating the values into another table (including the regions), but I can't help but feel that violates the very principle behind normalisation.

I've thought about using a UNION, and that might work, but it would mean both tables would have to contain the same columns, which seems far too restrictive, and not very future proof.

I'm wondering how others might deal with this situation, and if anyone has ever had to deal with it. I'd like my app to be as futureproof as possible, and I don't want to paint myself into any corners, but so far every solution I have thought of seems to have a drawback.

I would really appreciate any assistance anyone might be so kind as to offer.

Many thanks in advance.

EDIT:

Typical! No sooner had I posted, I had a eureka moment, but I'd still like some feedback on it, if possible.

The newsletters table shouldn't have a foreign key which correlates to regions, since it can exist without a region. I'm thinking that each newsletter could have a column for type (regional and national), then I was thinking of having a pivot table that would link any regional newsletters to their appropriate region.

This makes a lot of sense to me, but I suspect that my reasoning may be flawed, so I'd still appreciate feedback if anyone's willing.

Many thanks in advance.


Solution

  • --"The newsletters table now sports a foreign key with correlates to the relevant id in the regions table."--

    I would suggest making the relationship between newsletters and regions many-to-many (via a mapping table). Even if the current reality is 1-to-1 or 1-to-many. A mapping talbe will support the current reality. And it will support future cases such as 1 region receiving multiple newsletters, or 1 newsletter sent to several regions. Sounds like you're working on a living spec so I'd go for the flexibility.


    --"they'd also like the facility for a national newsletter"--

    Is "national" defined as the sum of all regions? If so, then the many-to-many relation can support a national newsletter via data. No extra "IsNational" flags needed. It has flexibility to make "almost national" newsletters that exlclude 1 or 2 regions. Behavior is controled through data, not columns.

    UPDATE: Make sure the UI supports national newsletters in a convenient way. Allow them to easily tag all on regions to a newsletter in 1 motion.

    Table: Region
    Cols: ID, RegionName, State, etc...
    
    Table: NewsLetter
    Cols: ID, NewsLetterName, ect...
    
    Table: Map_Region_NewsLetter
    Cols: ID, RegionID, NewsLetterID