SQL理论多重参考

Ste*_*rka 5 c# sql sql-server database-design entity-framework

我正在设计一个数据库并且有理论问题,关于哪个解决方案更适合运行查询,在microsoft sql server上更快或者更简单.

GIVEN

可以说,我们有以下表格: 国会,人物,会议,会议室等等.不要介意给定的名字.这些只是一些基本的独立实体.

-----------------------------------------------------------------
| Congress      | Person        | Session       | Room          |
-----------------------------------------------------------------
| CongressID    | PersonID      | SessionID     | RoomID        |
| Name          | Name          | Name          | Name          |
| ...           | ...           | ...           | ...           |
-----------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

另外,我们有一个名为"Right"的表.权利具有名称,可以定义对一个或多个基本实体的访问权限.每个人都可以分配这些权利.

所以还有2个表: RightPersonRight

---------------------------------
| Right         | PersonRight   |
---------------------------------
| RightID       | PersonRightID |
| Name          | PersonID      |
| ...           | RightID       |
| ...           | ...           |
---------------------------------
Run Code Online (Sandbox Code Playgroud)

被)追捧

现在只缺少一件事.表示与其他实体的关系的方式或表.我知道三种不同的方式都会起作用,但我没有足够的经验来决定哪一方是最好的.

1.关系方式?

升级:对于每个新实体,添加一个新表

关系:右1:N个实体

优点:添加新实体不会以任何方式影响其他实体,实体的外键

缺点:许多表可能包含CreatedDate或rowguid等冗余列.

SQL示例 ::

select *
from Right r
left join RightCongress rc on r.RightID     = rc.RightID
left join RightSession  rs on r.RightID     = rs.RightID
left join RightRoom     ro on r.RightID     = ro.RightID
left join Congress      ec on rc.CongressID = ec.CongressID
left join Session       es on rs.SessionID  = es.SessionID
left join Room          er on ro.RoomID     = er.RoomID 

-------------------------------------------------------
| RightCongress   | RightSession    | RightRoom       |
-------------------------------------------------------
| RightCongressID | RightSessionID  | RightRoomID     |
| RightID         | RightID         | RightID         |
| CongressID      | SessionID       | RoomID          |
| ...             | ...             | ...             |
-------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

2.列方式?

2.1列方式1

升级:对于每个新实体,向表"右"添加一个新列

关系:右1:1实体

优点:不需要新表,小型声明,实体外键

缺点:每个新实体都会影响所有其他行,可能只有1:1的关系,列数可能会令人困惑

SQL示例 ::

select *
from Right r
left join Congress ec on r.CongressID = ec.CongressID
left join Session  es on r.SessionID  = es.SessionID
left join Room     er on r.RoomID     = er.RoomID

-----------------
| Right         |
-----------------
| RightID       |
| Name          |
| CongressID    |
| SessionID     |
| RoomID        |
-----------------
Run Code Online (Sandbox Code Playgroud)

2.2列方式2

升级:对于每个新实体,向表"RightReference"添加一个新列

关系:右1:N个实体

优点:1:N关系,只有一个新表,小语句,实体的外键

缺点:每个新实体都会影响所有其他行,列数可能会令人困惑

SQL示例 ::

select *
from Right r
inner join RightReference rr on r.RightID on rr.RightID
left join Congress ec on rr.CongressID = ec.CongressID
left join Session  es on rr.SessionID  = es.SessionID
left join Room     er on rr.RoomID     = er.RoomID

---------------------------------------
| Right            | RightReference   |
---------------------------------------
| RightID          | RightReferenceID |
| Name             | RightID          |
| ...              | CongressID       |
| ...              | SessionID        |
| ...              | RoomID           |
| ...              | ...              |
---------------------------------------
Run Code Online (Sandbox Code Playgroud)

3.参考方式

升级:对于每个新实体,使用新的ReferenceTypeID向RightReference添加一个新行

关系:右1:N个实体

优点:只有一个新表和动态参考

缺点:匿名引用并始终记住构建查询的索引,没有实体的外键

说明:ReferenceID是引用的实体/行的主ID,如表Congress,Session等.所以你不能建议它引用哪个表.因此,有ReferenceTypeID.它指向一个名为ReferenceType的转换表,其中每个表都存储有唯一的id.也许可以使用系统方法OBJECT_ID.

SQL示例 ::

select *
from Right r
inner join RightReference rr on r.RightID = rr.RightID
left join Congress ec on rr.ReferenceID = CongressID and rr.ReferenceType = 1
left join Session  es on rr.ReferenceID = SessionID  and rr.ReferenceType = 2
left join Room     er on rr.ReferenceID = RoomID     and rr.ReferenceType = 3

----------------------------------------------------------
| Right            | RightReference   | ReferenceType    |
----------------------------------------------------------
| RightID          | RightReferenceID | ReferenceTypeID  |
| Name             | RightID          | Name             |
| ...              | ReferenceID      | ...              |
| ...              | ReferenceTypeID  | ...              |
| ...              | ...              | ...              |
----------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

现在给所有的sql专家.

什么是最好或更好的让我们说最先进的解决方案/方式/方法来处理这项任务?如果您有其他方式,请告诉我.

我正在寻找的是:一般优势和不利,SQL性能,EntityFramework的实施困难以及您知道或考虑的其他一切.

谢谢!

Rad*_*umb 1

通常,在处理关系数据库时,任何需要更改架构的操作都是禁忌,因为您必须在 SQL 服务器上执行潜在危险的操作、更新 EF 以及您可能正在使用的任何模型,并可能重新部署用作数据库的任何应用程序。您的数据库的前端。

SQL 解决方案

如果您愿意在每次添加新实体时都拒绝,或者由于其他原因与 RDBMS 相关联,那么您有两个选择:

如果您关心您的实体(国会、会议、房间)表架构

列方式#2 可能是最好的主意,因为它将关系数据与实际表数据分开。为实体和权限之间的关系创建一个单独的表,并为每个可能的entityId 放置一个索引。在您的示例中,您需要 ConferenceId、SessionId 和 RoomId 列的索引。

如果您不关心实体表架构

将所有实体表合并为一个大型实体表,其中包含 Id 列和 XML 列,其中包含所有实际实体信息(例如类型)。实体和权利之间的单一关系很好。

NoSQL 解决方案

如果您可以走这条路,它可能会更适合您正在寻找的灵活结构。您仍然需要更新访问文档存储的代码,但从您的建议来看,这似乎是不可避免的,除非您有一些非常灵活但容易出错的代码。

您不需要在每次添加新实体类型时进行架构/EF 更新,也不需要担心关系。您的 Person 对象将把所有权限都嵌套在内部,并以这种方式存储在文档存储中。