启用/禁用/删除数据库行及其引用的最佳实践?

sme*_*its 11 sql database database-design data-modeling

处理删除或启用/删除行及其引用表的最佳实践是什么?

例如,假设我有一个非常简单的'论坛'应用程序.

我有一个users包含我的webapp帐户的表,其中threads包含用户创建的线程,以及一个comments包含用户对线程评论的注释的表.

现在,假设在注册时我想在激活其帐户之前验证用户的电子邮件.这是最好的方法吗?什么是最佳做法?也许通过一个只返回带字段的行的视图is_active=true?使用2个分离的表pre_users(包含仍需要验证的用户)和users(经过验证的表)?

同样,您将如何处理想要暂停其帐户的用户?它的主题和评论?您是否会添加另一个标志is_suspended,并更新视图以考虑该标志?如果它不是一个视图,而是两个单独的表,我怎么能处理引用呢?

另外,删除一个帖子.假设在线程删除时我不希望实际删除该线程,因为我不希望发布注释的用户突然看不到他们的注释.怎么处理这个?

这类问题的最佳做法是什么?

rea*_*anb 10

对于活动状态不影响唯一性的表(例如,用户通过用户名或电子邮件地址标识,不可能有同一事物的活动和非活动版本)我使用可空的日期时间字段来表示状态.例如,对于您的users表,我有一个verified_at列,该列最初设置为null,并且当用户验证其帐户时的当前日期/时间.用户帐户暂停也可以这样做.如果用户重新激活其帐户,我们只需将suspended_at字段设置为null.

如果您需要更多状态值而不是简单的是/否,我将使用单独的字段来更改状态值和日期/时间.

如果要跟踪更新历史记录(例如激活/暂停),最好在单独的表中执行此操作.在这种情况下,您可以从users表中引用当前激活记录,这将更有效地使用表的索引而不是查询状态列.

在某些情况下,状态会影响唯一性.例如,在论坛中,用户可能能够存储任意数量的签名或化身,但是一次只能有一个是活动的.在这些情况下,最好将当前数据与历史数据分开.例如,用于签名的表,以及在users表中用于引用活动签名的外键.您应该能够更新任何行的状态,而无需关心其他行中的值.

避免级联状态,它们会破坏以前的子项状态,并且在许多情况下使状态字段的使用几乎毫无意义.而是在查询时与父表联接以过滤顶级状态.

最后,数据中的状态是时间数据建模方向的一个步骤.我建议阅读这个主题.