在数据库中的参考表中创建一个代表"所有其他记录"的记录是否是个好主意?

leo*_*ora 7 database sql-server asp.net-mvc database-design database-schema

我有一个带有SQL Server后端的asp.net-mvc网站.我正在简化我的情况以突出显示并隔离问题.我在DB中有3个表

  1. 文章表(id,名称,内容)
  2. 位置表(id,名称)
  3. ArticleLocation表(id,文章ID,位置ID)

在我的网站上,当您创建文章时,您可以从多选列表框中选择您希望该文章发送的位置.

大约有25个地点,所以我在辩论添加一个名为"全球"的新位置作为快捷方式,而不是让人从列表框中选择25个不同的项目.我仍然可以将此作为前端的快捷方式,但现在我正在辩论是否有利于此流入后端.

因此,如果我有一篇全局文章,而不是在ArticleLocation表中有25条记录,我只会有一条,然后我会在前端做一些技巧来选择所有项目.我想知道这是一个非常糟糕的主意.

我能想到的事情让我感到紧张:

  1. 如果我创建一篇文章并选择全局但后来最后添加了3个新位置该怎么办?如果没有这种全局设置,这3个位置将无法获得文章,但是以新的方式,他们会.我不确定什么是更好的,因为第二件事实际上可能是你想要的,但它有点不那么明确.

  2. 我对报告有要求,我想过滤所有全球文章.想象一下,我需要一篇文章.IsGlobal()方法.现在我想我可以说,如果一个项目与位置表中的所有记录具有相同的位置数量,我可以将其转换为被认为是全局的,但是再次因为人们可以添加新的位置,我觉得这种方法有点不稳定.

有没有人对这个困境有任何建议,围绕在真正反映"所有记录"的参考数据表中创建记录.感谢任何建议

HAB*_*ABO 9

根据要求,这是我的评论提升为答案.这也是扩展它的机会.

我将我的答案限制在一个只有一个位置列表的系统中.我做过公司层级的事情:公司,部门,地区,州,县,办事处和员工或其他一些人.它变得丑陋.

在OP的问题的情况下,似乎AllLocationsArticles表中添加一点使得意图清楚.标志设置为1的任何文章都会显示在所有位置,无论它们何时创建,并且不需要在ArticleLocation表中包含任何条目.如果作者不希望文章自动显示在将来的位置,则仍可以将文章明确添加到所有现有位置.

实施涉及更多工作.我将向和表添加INSERTUPDATE触发以强制执行规则,即该位已设置且没有相应的行,或者该位是明确的,并且可以显式设置位置.(这是个人偏好让数据库在可行的情况下防御"坏数据".)ArticleArticleLocationAllLocationsArticleLocation

根据您的需要,表值函数是隐藏一些脏工作的好方法,例如dbo.GetArticleIdsForLocation( LocationId )可以在AllLocations内部处理标志.您可以在存储过程和ad-hoc查询中JOIN使用它Article.在其他情况下,视图可能是适当的.

欢迎您借用的另一个功能("从朋友那里窃取!")是让管理员的登录页面成为"例外"页面.在这个地方,我展示的东西从大规模的火焰灾难到简单的peccadillos.在这种情况下,与零位置相关联的文章将被视为非关键的内容,但值得检查.

在每个位置明确显示的文章可能会对添加新位置的人感兴趣,因此我可能会有一个网页.可能应更新某些文章以明确说明新位置,或重新考虑更改为所有位置.

  • @DanLing - 我倾向于在UI中添加一个复选框,以允许用户明确地将文章指定为适用于所有位置,现在和将来.选中时,它应禁用其他选项,无论是多选列表还是每个位置的复选框数组.是的,它更复杂,但它应该让用户非常清楚他们正在做一些与众不同的事情.根据位置的数量和文章的典型分散,我可能还有按钮来检查所有或没有.[POLS](http://en.wikipedia.org/wiki/Principle_of_least_astonishment). (2认同)

Dam*_*vic 6

是不是一个好主意......代表"所有其他记录"?

在桌子上代表一棵树是不是一个好主意?树的代表"所有其他记录".

树和层次结构并不简单,但有很多例子,文章和书籍可以解决这个问题 - 比如Celko的树和SQL中的层次结构 ; Karwin的SQL反模式.

所以你实际拥有的是一个层次结构(可能只是一棵树) - 它可能有助于从一开始就解决问题.该Global从你的例子只是另一个Location(树的根),所以当增加一个新的位置,你可以决定它是否将是一个孩子Global或没有.


事实

  • 位置(LocationID)存在.
  • 位置(LocationID)包含在父位置(LocationID)中.
  • 文章(ArticleID)存在.
  • 文章(ArticleID)位于Location(LocationID).

约束

  • Each 位置包含在at most one 父位置中.It is possible that for some 父位置,more than one 位置包含在that 父位置中.

  • It is possible that some 文章位于more than one 位置 and that for some 位置,more than one 文章位于that 位置.


合乎逻辑

在此输入图像描述


这样,您可以将任何位置分配给文章 - 但必须在需要时将其解析为叶级别.

层次结构(树)在这里以"天真的方式"表示; 使用闭包表,嵌套集或枚举路径 - 或者,如果你喜欢递归...