Unf*_*lux 6 mysql database-design polymorphic-associations database-schema laravel
我的工作其中有一些类型的数据库(如在User
,Appointment
,Task
它可以有零个或多个等)Notes
与每个类型相关联。
我遇到的实现这些关系的可能解决方案是:
许多人认为这是遵循 Active Record 模式的框架最容易实现的解决方案,并且似乎是最常见的实现,我会添加一个表,其数据为morphable
:
Mynotable_type
将允许我区分相关的类型 ( User
, Appointment
, Task
) Note
,而 thenotable_id
将允许我获取type
相关type
表中的单个记录。
优点:
缺点
或者,我可以为每种类型创建一个表,该表仅负责Notes
与该类型相关联。该type_id
外键可以让我快速获取个人type
记录。
被许多在线人视为代码异味,许多文章主张避免多态关系而支持替代方案(例如此处和此处)。
优点:
缺点:
type_notes
表多态关系当然是两个实现选项中更简单的一个,但是缺少外键约束并因此潜在的一致性问题感觉是错误的。
每一个表notes
的关系(user_notes
,task_notes
外键等)似乎是正确的方式(与设计模式保留),但可能会导致大量的表(除了其他types
可有notes
或添加相似类型notes
[例如events
])。
感觉我的选择要么是简化表结构但放弃外键并增加查询开销,要么增加具有相同结构的表数量但简化查询并允许外键。
鉴于我的情况,以上哪一个更合适,或者我应该考虑其他选择吗?
Bil*_*win 11
什么是“表膨胀”?您是否担心桌子太多?我使用过的许多实际数据库都有 100 到 200 个表,因为这就是它所需要的。
如果你正在关注的增加多个表,那么你为什么有单独的表User
,Appointment
和Task
?如果您有一个多值属性User
,例如每个用户有多个电话号码,您会为电话创建一个单独的表,还是尝试以某种方式将它们全部合并到用户表中?或者有一个用于用户电话、约会受邀者和任务里程碑的多态“属于其他事物的事物”表?
答案:不,您将创建一个Phone
表,并使用它来仅引用该User
表。如果约会有被邀请者,那么它有自己的表(可能是约会和用户之间的多对多)。如果任务有里程碑,那也有自己的表。
正确的做法是像对应用程序中的对象类型建模一样对数据库表进行建模。您可能喜欢阅读CJ Date的《SQL 和关系理论:如何编写准确的 SQL 代码第 3 版》这样的书,以了解有关表如何类似于类型的更多信息。
您已经本能地知道无法创建外键的事实是一个危险信号。外键必须正好引用一个父表。这应该是一个线索,表明制作多态外键不是有效的关系数据库设计。一旦您开始将表及其属性视为具体类型(如 SQL 和关系理论中所述),这将变得显而易见。
如果必须创建一个音符表,你可以把它引用称为“显着的”一个表,就像是一个超类User
,Appointment
和Task
。然后这三个表中的每一个也将引用 的主键Notable
。这模仿了多态的面向对象结构,您可以让类 Note 通过其超类类型引用对象。
但恕我直言,这比它需要的更复杂。我只想创建单独的表UserNotes
,AppointmentNotes
和TaskNotes
。我并没有因为多三个表而烦恼,它使您的代码更加清晰和可维护。
归档时间: |
|
查看次数: |
3093 次 |
最近记录: |