Log*_*man 7 database database-design foreign-keys relational-database
我的应用程序具有可属于组的用户的通知设置.组管理员可以定义整个组的设置,以便在任何用户执行操作时,将通知管理员.管理员还可以定义单个用户的设置,这将覆盖组设置.
现在我有一个包含列的数据库:group_id, action1, action2, action3, ....这些操作是布尔值,用于确定当用户在其组中执行该操作时是否通知管理员.
我可以创建一个由User模型而不是Group模型拥有的单独的表,但是将完全相同的数据存储在一个完全独立的表中并保存更改group_id为user_id.
另一种选择是添加user_id到我已经拥有的表中,并允许空值group_id.在确定用户的通知设置时,应用程序将首先根据用户选择设置,然后回退到group_id非空的设置.这感觉效率低下,因为数据库中会有很多空值,但这对我来说肯定需要的工作量更少.
这种情况的设计是否比我描述的两种设计更有效?
Bra*_*vic 12
通常,有两种策略可以处理这样的情况:
实质上,每个可能的父表都将在子表中拥有自己的独立外键,并且有一个CHECK强制执行其中一个非NULL.由于FK仅在非NULL字段上强制执行,因此只会强制执行其中一个FK.
例如:

(用户和组之间的关系省略)
CHECK (
(group_id IS NOT NULL AND user_id IS NULL)
OR (group_id IS NULL AND user_id IS NOT NULL)
)
Run Code Online (Sandbox Code Playgroud)
从公共超类型继承用户和组,然后将设置连接到超类型:

有关继承(也称为类别,子类,子类型,泛化层次结构等)的更多信息,请查看" ERwin方法指南 "的"子类型关系"一章.不幸的是,现代DBMS本身并不支持继承 - 有关物理实现它的一些想法,请看一下这篇文章.
这是一个重型解决方案,可能不仅仅适用于两个表(组和用户),但对于许多表来说可能非常"可扩展".