简体   繁体   English

数据库规范化的麻烦

[英]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. 我已经在数据库中有一个regions表,因为组织内的兄弟会必须位于一个区域内。 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. newsletters表现在使用与regions表中相关id相关的外键。

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? 我已经考虑过将外键列设置为0表示它是一份全国性的时事通讯,但是如果他确定他想要实现另一种类型的时事通讯会怎么样? 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. 我已经考虑在newsletters表中添加一个额外的列,它将引用另一个表,它可能包含这些新类型,但这对我来说似乎有点奇怪,而且似乎有点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. 我已经考虑过使用UNION ,这可能会有效,但这意味着两个表都必须包含相同的列,这似乎过于严格,而且不是很有前途。

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. newsletters表不应具有与区域相关的外键,因为它可以在没有区域的情况下存在。 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. 提前谢谢了。

--"The newsletters table now sports a foreign key with correlates to the relevant id in the regions table."-- - “简报表现在使用与区域表中相关ID相关的外键。” -

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. 即使当前的现实是1对1或1对多。 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. 它将支持未来的案例,例如1个地区接收多个新闻通讯,或1个通讯发送到多个地区。 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. 不需要额外的“IsNational”标志。 It has flexibility to make "almost national" newsletters that exlclude 1 or 2 regions. 它可以灵活地制作出“1个或2个地区”的“几乎全国性”的新闻通讯。 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. 允许他们轻松地将所有区域标记为1个动作的简报。

Table: Region
Cols: ID, RegionName, State, etc...

Table: NewsLetter
Cols: ID, NewsLetterName, ect...

Table: Map_Region_NewsLetter
Cols: ID, RegionID, NewsLetterID

What I would do is have an additional table, say newsletter_region , that has its own ID, a foreign key to the region and another to the newsletter. 我要做的是有一个额外的表,比如newsletter_region ,它有自己的ID,是该地区的外键,另一个是时事通讯。 This way, if there's an entry in this table it means that said newsletter is a regional newsletter and if there's none, it's a national newsletter. 这样,如果此表中有条目,则表示所述时事通讯是区域时事通讯,如果没有,则为全国时事通讯。

Be careful with this approach though. 不过要小心这种方法。 A third type of newsletter might put your database schema in shambles. 第三种类型的新闻通讯可能会使您的数据库架构陷入混乱。 I believe it's better to rethink the schema and adjust it for scaling. 我认为最好重新考虑架构并调整它以进行缩放。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM