我的场景是有一个记录和报告一些重要设置的表,用户可以在我们维护的一组站点中更改这些设置(每个站点都有自己的DB)。在设计表时(将部署在每个DB上),我对是否需要Primary Key感到困惑。我有一个名为SiteID的列,日志表中的每一行都有SiteId、newVal of Setting、oldVal of setting、Change date。我将使用它查看站点上更改的历史、按日期筛选更改等。因此,在这个场景中,显然SiteId本身不能是一个PK,但是我真的需要添加一个像LogId这样的新列才能生成一个复合的PK吗?我在这漏掉了什么吗?
发布于 2016-03-10 21:07:43
您需要专注于您的用例。
如果您可以避免数据重复(例如,从应用程序端),并且知道您需要的数据,以及您需要的索引类型等等,那么您可以很容易地避免这种情况;主要是如果您谈论的是大规模的报告扫描,以及数据复制没有问题的时候。
在许多MPP数据库(以报告为目标的数据库,例如Vertica)中,主键是可选的。因此,如果您知道您的数据和用例,您可以避免主键。
发布于 2016-03-10 07:45:34
没有重复行的表总是至少有一个候选键。我们可以选择一个通过PRIMARY KEY来声明,任何其他的都可以通过UNIQUE NOT NULL进行声明。(UNIQUE NOT NULL是从PRIMARY KEY声明中获得的约束。)如果您不告诉DBMS您的候选键,那么它就无法帮助您减少错误,方法是防止重复,或者通过在其列上隐式定义索引来提高性能。
从您的问题中不清楚如何记录给定的新值和旧值的设置是为了什么。如果您的列是siteId、setting、newValue、oldValue & changeDate,那么您的表中有一个候选键(siteID, setting, changeDate)。作为唯一的候选键,它是主键。如果设置值标识设置,使您的列为siteId、newValue、oldValue和changeDate,那么您就有两个候选键,(siteID, newValue, changeDate)和(siteID, oldValue, changeDate)。每个人都应该得到一个UNIQUE NOT NULL约束。一个可以通过主键声明。
如果您添加了另一列的唯一/代理项/id值,那么该表将有另一个候选键。和以前一样,通过一个UNIQUE NOT NULL约束约束所有这些约束,其中一个约束可以通过PRIMARY KEY表示。添加这样一个唯一的/代理项/id列是有原因的,但这并不是因为没有主键,除非表有重复的行。
发布于 2016-03-11 23:22:31
所有实体表都应该有一个PK,而不是所有表。历史记录/日志表通常没有PK,因为它们代表的是事件,而不是实体。(相反,他们不需要PK。我看到它们用一个(通常是自动生成的)定义,但我还没有看到查询中使用的值。据我所知,它们是完全多余的。)
历史记录和日志表所具有的是时间戳字段和表示发生了什么事件的字段。记录的其余部分将包含某种类型的实体信息,包括实体PK,以及与事件有关的其他数据--类似于指定值的前后值(如OP )。
时间戳列将与实体ID一起编入索引(因此可以检查在某一时间段内在指定实体上发生的所有事件)和/或事件ID (因此可以检查在某个时间段内发生指定事件的所有实体)。这都取决于表中所需的信息类型。
https://stackoverflow.com/questions/35906055
复制相似问题