数据库设计:鉴别器与关于约束的单独表格

时间:2012-08-14 22:25:36

标签: database entity-framework schema

我一直在两种方式来回打击,并且无法解决我认为更好的问题(或者看看为什么我可能会采用错误的方式)。

我为3种不同类型的用户提供了3个不同的网站,但它们共同构成了整个系统。例如,员工的管理员门户,客户的客户门户和供应商的供应商门户。在这里,我将这些不同的实体表示为“域”。

每个域都有自己的一组用户和自己的一组角色 - 因为每个门户的业务性质是不同的,用户也是如此,每个门户中的相关角色也是如此(例如,一个门户有报告,另一个没有,所以一个门户网站有“报告”角色。)

我没有包含这样一个事实,即我将User off子类型化为“StaffUser”,因为它包含普通用户不需要的其他表的字段和引用(例如Team,Department等)。

-----------------             -----------------
| Domain        |             | Role          |
-----------------  <--------- -----------------
| DomainId (PK) |             | RoleId (PK)   |
|               |             | DomainId (FK) |
-----------------             -----------------
        >                              >
        |                              |
        |                              |
        |                              |
-----------------             -----------------
| User          |             | User_Role     |
-----------------  <-------   -----------------
| UserId (PK)   |             | UserId (PK)   |
| DomainId (FK) |             | RoleId (PK)   |
-----------------             -----------------

在上面的示例中,我可以拥有 n 域,每个域都有 n 用户和 n 角色和用户可以与角色相关联。 4张桌子,非常简单,一切都有鉴别器价值。

在我的Web应用程序中(为了论证我使用.NET MVC和Entity Framework),当我希望为用户分配角色时,我选择与用户相同的Domain类型的所有角色,并保存配对我想要。

但是,如果在选择域的代码生成中出现某种问题(有人在域类型上使用了错误的枚举),现在我们突然将一个域类型的用户与另一个域的角色进行匹配类型......混乱随之而来。

这种情况如何可以预防?可以在SQL中强制执行吗?我担心不太可能发生的事情吗?我看到的SNAFU比我那时更荒谬。

那么,如果我将一个table-per结构放入其中该怎么办:

-----------------
| Domain        |
-----------------
| DomainId (PK) |
-----------------
        >
        |
        |
        |
-----------------             ------------ ----            ---------------
| DomainA       |             | DomainARole   |            | Role        |
------------ ----  <--------  -----------------  --------> ---------------
| DomainId (PK) |             | RoleId (PK)   |            | RoleId (PK) |
|               |             | DomainId (FK) |            |             |
-----------------             -----------------            ---------------
        >                              >
        |                              |
        |                              |
        |                              |
----------------              ---------------------------
| DomainAUser  |              | DomainAUser_DomainARole |
----------------   <-------   --------------------------|           
| UserId (PK)  |              | UserId (PK)             |
| DomainId (FK)|              | RoleId (PK)             |
----------------              ---------------------------
        |
        |
        |
        >
----------------
| User         |
----------------
| UserId (PK)  |
----------------

在此示例中,DomainARole继承自User的Domain,DomainAUser inherts。如果我们想要添加更多域,我们需要为每种类型添加一个新表,这可能是很多表(在我的情况下,不管怎样,其中不会有超过3个“域”)。这是不必要的过度复杂吗?

第一个好处是DomainAUser只能拥有一个DomainARole ......它在那里被引用。我再也不用担心将两对与鉴别器相匹配,因为一切都整齐地分成了几个表。

第二个好处是,未来需求会发生变化(DomainAUser需要DomainBUser不需要的额外字段)我有适当的表格并且它很灵活。

我错过了一种简单的方法来解决这个问题吗?目前我一直赞成第二个更重的桌面版本。

有没有办法使用鉴别器来强制执行我需要的约束?我是不是太复杂了?我真的无法决定。

1 个答案:

答案 0 :(得分:0)

不要为此使用继承。当您想要将“常规”用户变为管理员时会发生什么? (或者客户进入供应商等?)你不能,因为对象不能改变他们的类型。你留下了丑陋的选择,比如删除和重新创建用户。如果一个用户在两个域中工作怎么办?继承不能支持这一点。

有时候人们会试图在他们的系统中声称这种情况从未发生过,但在现实世界中它确实如此,而继承实际上并不会在这里给你带来太大的影响。为什么要付出使用价格?

相反,您应该将“DomainAUser”信息设置为一个单独的表,并具有从User到DomainAUser的关联/导航,因此将存在User.DomainA属性,对于非DomainA用户将为null。