SQL Server DB&需要应用程序设计级别建议。数据库或应用程序中的约束?

时间:2010-01-26 13:35:32

标签: c# sql-server database

我需要一些建议来实现业务规则 - 是将其保存在数据库中(使用TRIGGER)还是应用程序代码。

--- Table structure:---

# ORG - Master table for Organizations 
# USER - Master table for Users (each user belongs to an Org so there's a field OrgId which is FK ro ORG) 
# SITE - Master table for Sites

# ORGSITE - {OrgId, SiteId} links Site(s) with Org(s) 
# USERSITE - {UserId, SiteId} links Site(s) with User(s)

约束是:“只有用户可以访问该网站,才能访问该网站。”


现在,它发生在应用程序中,在第1天我们将Site1与Org1相关联,然后我们就能将Site1与User1相关联(User1属于Org1)。在第2天,我删除了Site1和&之间的关系。来自ORGSITE的Org1(这要求我也从USERSITE表中删除相应的User1& Site1关系)。

这是在应用代码中处理的。所以,现在我的问题是我保持上述约束处理的地方 -

APPROACH#1:

在ORGSITE表和USER表上部署TRIGGER,它将处理以下活动:

  1. 删除ORGSITE后删除(删除 相应的USERSITE记录)

  2. USER的后续更新(如果是用户的     Org被更改然后删除所有他的     来自USERSITE的记录)

  3. APPROACH#2:

    处理代码中的所有内容 - 点击触发这些数据库操作的事件,并从USERSITE中删除记录(必要时)。需要通过交易进行管理。

    APPROACH#3:

    简单地说,在USERSITE表中添加一个新字段OrgSiteId,它是对ORGSITE的'Auto Increment PK:Id'的FK ref。接下来,我将为USERSITE.OrgSiteId FK部署级联删除。这将处理大部分事情并使其隐含!

    希望我好好解释。 APPROACH#3真的会起作用吗?如果不是 - 您的偏好是什么?为什么?

    感谢您的时间。

4 个答案:

答案 0 :(得分:4)

如果您认为有人会直接从数据库(例如某个DBA)运行查询,那么您应该在触发器中处理它。如果您通过应用程序执行此操作,则必须始终通过应用程序执行此操作。

答案 1 :(得分:3)

我建议:

  • 删除UserSite表
  • 创建一个名为UserSite的视图

    选择a.UserId,b.SiteID 来自用户a LEFT JOIN b.OrgSite ON b.orgid = A.Org

这将返回用户可以看到的网站,如果他或她看不到任何

,则返回NULL

答案 2 :(得分:1)

组织是否具有层次性?是否有ORG.parent_org_id字段?

如果是这样,你的问题就会变得有点困难,因为你可能需要一个人能够看到所有与他们的组织或他们的组织子女相关的网站(有点像文件系统中的文件夹权限)。

如果您的数据库支持递归JOIN或common table expressions,那么上面Sparky的视图解决方案仍然适用于这种情况。 ANSI标准的方法是使用CTE(仅支持SQL 2005及更高版本和PostgreSQL)。 Oracle和其他数据库具有相同递归功能的非标准语法。

答案 3 :(得分:0)

你可以使用触发器;这是一个可行的选择。我个人不会使用级联删除,因为这可能是危险的。

我倾向于选择代码选项,因为它允许我进行特定的错误处理,日志记录和引用检查。你有一些触发器,但这是我个人的偏好。另外,这使得逻辑与您的其他应用程序更改代码,因此所有逻辑都在一个地方,而不是分解为应用程序/数据库。但同样,这是我个人的偏好;触发器是一个非常好的和可行的选择。

HTH。