SQL理论多引用

本文关键字:引用 理论 SQL | 更新日期: 2023-09-27 18:16:57

我正在设计一个数据库,并有理论问题,关于哪种解决方案更好地运行查询,在Microsoft SQL server上更快或更简单的关系。

假设,我们有以下表格:Congress, Person, Session, Room等等。不要在意名字。这些只是一些基本的独立实体

-----------------------------------------------------------------
| Congress      | Person        | Session       | Room          |
-----------------------------------------------------------------
| CongressID    | PersonID      | SessionID     | RoomID        |
| Name          | Name          | Name          | Name          |
| ...           | ...           | ...           | ...           |
-----------------------------------------------------------------

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

所以还有2个表: PersonRight

---------------------------------
| Right         | PersonRight   |
---------------------------------
| RightID       | PersonRightID |
| Name          | PersonID      |
| ...           | RightID       |
| ...           | ...           |
---------------------------------

现在只缺一样东西了。表示与其他实体的关系的方式或表。我知道三种不同的工作方式,但我没有足够的经验来决定哪一种是最好的。

1。关系的方式?

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

关系:右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          |
| ...             | ...             | ...             |
-------------------------------------------------------

2。列式?

2.1列方式1

Upgrade:对于每个新实体,向表"Right"添加一个新列

关系:右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        |
-----------------
2.2列方式2

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

关系:右1:N实体

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

Cons:每个新实体影响所有其他行,列数可能会混淆

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           |
| ...              | ...              |
---------------------------------------

3。参考方式

Upgrade:对于每个新实体,用新的ReferenceTypeID

向右引用添加新行

关系:右1:N实体

优点:只有一个新表和动态引用

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

Explanation: 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  | ...              |
| ...              | ...              | ...              |
----------------------------------------------------------

现在给所有的sql专家。

处理这项任务的最好或更好的解决方案/方法/方法是什么?如果您有其他办法,请告诉我。

我要找的是:一般的优点和缺点,sql性能,实现困难与EntityFramework和其他一切你知道或考虑它。

谢谢!

SQL理论多引用

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

SQL解决方案

如果您同意在每次添加新实体或由于其他原因与RDBMS绑定时提交no-no,则有两个选择:

如果您关心您的实体(Congress, Session, Room)表模式

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

如果你不关心你的实体表模式

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

NoSQL解决方案

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

您不需要在每次添加新的实体类型时都进行模式/EF更新,也不需要担心关系。您的Person对象的所有权限都将嵌套在里面,并将以完全相同的方式存储在文档存储中。