用户反馈系统的正确数据库模型(一个有趣的案例)

Proper database model for a user feedback system (an interesting case)

我正在使用 PHP 和 Yii 框架开发应用程序。我一直在考虑针对给定功能的最 suitable 数据库结构,这就是我想出的。然而,我并不是 100% 肯定应该这样做,所以我决定询问社区。

应用说明:

注册用户可以参加活动。每个事件都可以有一个 用户数量不限,调用"participants of the event").

活动结束后,每位参与者都可以对同一活动的所有其他参与者发表反馈。

数据库结构:

由于每个活动可以有无限数量的用户并且用户可以参与无限数量的活动,我创建了一个 table "Participant",它解决了多对多关系

其他table不言自明。

这是最重要的事情:

一个活动的每个参与者可以有最大的反馈数量等于除给定参与者之外的同一事件的参与者数量(例如,如果活动有 5 个参与者,则给定参与者可以收到 4 个反馈来自同一事件的参与者)。

我要强调一下,只有同一事件的参与者才能对给定的参与者留下反馈(而且只有一个)。

以下是我为确保数据库的完整性而采取的步骤:

  1. 我在 "Participant" table 中创建了 "id" 列,以便为参与特定活动的每个用户提供唯一 ID。此 ID 是复合的(user_id 和 practice_id 连接在一起)。因此,参与事件 14 的用户 23 的参与者 ID 为 14-23。

你可能会问为什么我决定用这个 ID 创建一个单独的列而不是像这样简单地定义主键:

PRIMARY KEY (user_id, event_id)

继续阅读。

活动结束后,每个参与者都可以留下对其他人的反馈。现在,这个参与者ID可以被反馈table.

中的外键"sender_id"和"recipient_id"引用

进一步的,反馈的主键table也是由"the sender_id"和"recipient_id"组合而成的,所以如果用户23想对用户45(均参与事件71),反馈主键为:71-45-71-23.

这种方法使我们能够在数据库级别确保没有参与者对同一参与者留下两次反馈,并且用户不能两次参与同一事件。

问题:

这是一个糟糕的设计。只需制作一个 2 列主键和 2 列外键即可。这是一个称为 "encoding information in keys" 的基本反模式,(因此)称为 "smart"、"intelligent" 或 "concatenated" 键。 "dumb" 一把好钥匙。

Eg::

Despite it now being easy to implement a Smart Key, it is hard to recommend that you create one of your own that isn't a natural key, because they tend to eventually run into trouble, whatever their advantages, because it makes the databases harder to refactor, imposes an order which is difficult to change and may not be optimal for your queries, requires a string comparison if the Smart Key includes non-numeric characters, and is less effective than a composite key in helping range-based aggregations. It also violates the basic relational guideline that every column should store atomic values

Smart Keys also tend to outgrow their original coding constraints

此外,不需要这样做。

许多 DBMS 允许 "computed columns" 从其他列自动计算其值。要使一个成为主键或外键,您通常需要它 "persisted",即像普通列一样占用内存,而不是像视图一样在需要时才计算。 MySQL 没有这些,但是 5.7.5 有一些功能,它们被称为 "generated columns",可以是 "stored"。但不要对 PK 或 FK 执行此操作!

实际设计问题正在处理 database/SQL subtypes/hierarchies/inheritance/polymorphism