数据库设计:NULL的FK - 好还是坏?

时间:2011-11-11 07:43:44

标签: mysql database database-design

假设我有一个“消息”表,其中我想存储我的应用程序支持的所有可能消息。例如,在类似FB的应用程序中,可能存在“媒体消息”(例如照片,视频,音频),“媒体专辑消息”,“私人消息”等。建模的一种方法是:

Table: message
- messag_id (PK)
- user_id (FK, this is the sender of the message)
- message

TABLE: media_message
- media_message_id (PK, receiver of the message implied by the owner of the media)
- message_id (FK)

TABLE: media_album_message
- media_album_message_id (PK, receiver of the message implied by the owner of the media album)
- message_id (FK)

TABLE: private_message
- private_message_id (PK)
- message_id (FK)
- user_id (FK, receiver of the message)

... etc.

因此,对于每个“类型”的消息,我需要创建某种“映射表”。

这样的事情会起作用吗?

TABLE: message
- message_id (PK)
- receiver_user_id (FK)
- sender_user_id (FK) 
- message
- media_album_id (FK, NULL allowed)
- media_id (FK, NULL allowed)

我认为通过这种设计,我仍然可以强制执行参照完整性。如果media_album_idmedia_id都是NULL,那么我可以假设它是一个“私有”消息(或者在应用程序层中实现一些类似的逻辑)。如果它甚至是不利的一面,那就是总是会有不使用的列。然后,也许这会更好地扩展 - 更少的JOIN等等。

思想?

2 个答案:

答案 0 :(得分:1)

FK是两个表之间的参照约束设置,以确保数据完整性。话说回来,FK不能为NULL。如果是media_album_id& media_id可以为空,那么它们不应该是FK。

答案 1 :(得分:1)

坏。避免可以为空的“外键”。它们有许多缺点。

当外键包含null时,并不总是强制执行引用行的约束。但是,不同DBMS之间的默认行为不一致。某些DBMS支持配置选项以更改可以为空的外键的行为,而有些则不支持。因此,从数据完整性的角度来看,SQL开发人员和用户可能不清楚可以为空的外键约束实际意味着什么。使用相同的产品在DBMS产品之间或甚至在不同服务器之间移植数据库可能会产生不一致的结果。

数据库设计工具,集成工具和其他软件并不总是正确支持它们,并且它们产生的结果可能是错误的。

外键经常在连接和其他查询逻辑中使用,这使得那些认为约束有效的用户会遇到问题。

从逻辑上讲,可以为空的“外键”约束并没有太多的逻辑意义。根据SQL标准,即使被引用的表为空,也不会违反这样的约束。这与使用空的最常见的理由之一相矛盾 - 它代表了“未知”的情况。如果没有X的有效值,那么任何“未知”X当然不能是有效值 - 而SQL将允许它!

最后,这是不必要的。您始终可以构造表,以便不需要null。因此,为了简单和准确,最好不要使用空值而不是将它们放入其中。