好的,实际上每个基于数据库的应用程序都必须处理“非活动”记录。要么是软删除,要么将某些内容标记为“忽略”。我很好奇在“活动”列(或状态列)上是否有任何激进的替代想法。

例如,如果我有一个人员列表

CREATE TABLE people (
  id       INTEGER PRIMARY KEY,
  name     VARCHAR(100),
  active   BOOLEAN,
  ...
);

这意味着要获取活跃人员列表,您需要使用

SELECT * FROM people WHERE active=True;

是否有人建议将非活动记录移至单独的表中,并在适当的位置进行 UNION 来连接这两个表?

好奇心袭来……

编辑: 我应该澄清,我是从纯粹主义的角度来看这个问题的。我可以看到数据归档对于大量数据可能是必要的,但这不是我的出发点。如果您执行 SELECT * FROM people ,那么对我来说这些条目在某种意义上是“活跃的”是有意义的

谢谢

有帮助吗?

解决方案

您在活动标志上对表进行分区,以便活动记录位于一个分区中,而非活动记录位于另一个分区中。然后为每个表创建一个活动视图,该视图会自动在其上显示活动过滤器。数据库查询引擎自动将查询限制在其中包含活动记录的分区,这比使用该标志上的索引要快得多。

以下是如何在Oracle中创建分区表的示例。 Oracle没有布尔列类型,因此我为Oracle目的修改了表结构。

CREATE TABLE people
(
   id       NUMBER(10),
   name     VARCHAR2(100),
   active   NUMBER(1)
)
PARTITION BY LIST(active)
(
   PARTITION active_records VALUES (0)
   PARTITION inactive_records VALUES (1)
);

如果您愿意,可以将每个分区放在不同的表空间中。您也可以对索引进行分区。

顺便说一句,这似乎是问题,作为一个我需要问的新手,处理意外重复的程序是什么?

编辑:根据评论中的要求,提供了在Oracle中创建分区表的示例

其他提示

嗯,为了确保您在大多数情况下只绘制活动记录,您可以创建仅包含活动记录的视图。这样就可以更容易地忽略活动部分。

我们在大多数表中使用枚举('ACTIVE','INACTIVE','DELETED'),所以我们实际上有一个三向标志。我觉得它在不同的情况下对我们很有用。您的里程可能会有所不同。

移动不活跃的东西通常是一个愚蠢的想法。这是一个很大的开销,有很多潜在的bug,一切都变得更复杂,就像unarchiving东西等。你如何处理相关数据?如果您移动所有这些,则必须修改每个查询。如果你不移动它,你希望得到什么好处?

这导致了下一点:为什么要移动它?当大小加倍时,正确索引的表需要一个额外的查找。任何性能提升都必定可以忽略不计。为什么你会想到它,直到你实际遇到性能问题的遥远未来时期?

我认为严格地将其视为一段数据然后原始帖子中显示的方式是正确的。活动标志数据直接取决于主键,应该在表中。

该表保存有关人员的数据,无论其数据的当前状态如何。

活跃的旗帜有点难看,但它很简单并且效果很好。

您可以按照建议将它们移动到另一个表格。我建议查看活动/非活动记录的百分比。如果您有超过20或30%的非活动记录,那么您可以考虑将它们移动到其他位置。否则,这不是什么大问题。

是的,我们愿意。我们目前有“active ='T / F'”我们很多表中的列,主要是显示'最新'行。插入新行时,前一个T行标记为F以保留它以供审计。

现在,我们将转向2表方法,当插入新行时,前一行将移至历史表。这为大多数情况提供了更好的性能 - 查看当前数据。

成本略高于旧方法,以前你必须更新和插入,现在你必须插入和更新(即不是插入新的T行,而是用所有新数据修改现有行),因此,成本只是传递整行数据而不是只传入更改。这几乎不会产生任何影响。

性能优势在于您的主表索引要小得多,并且您可以更好地优化表空间(它们不会增长太多!)

你的架构中这样的二进制标志是一个不好的想法。考虑查询

SELECT count(*) FROM users WHERE active=1

看起来很简单。但是当你拥有大量用户时会发生什么,所以需要为这个表添加一个索引。再次,它看起来很直接

ALTER TABLE users ADD INDEX index_users_on_active (active)

除非!!这个索引没用,因为这个列的基数正好是两个!任何数据库查询优化器都会忽略此索引,因为它的基数较低,并进行表扫描。

在使用有用的标记填充模式之前,请考虑如何访问该数据。

https://stackoverflow.com/questions/108503/mysql-advisable-number -of-行

我们经常使用活动标记。如果您的数据库非常大,我可以看到将非活动值迁移到单独的表中的值。

当有人想要查看所有记录,无论是活动还是非活动时,您只需要表的联合。

在大多数情况下,指示删除的二进制字段就足够了。通常有一种清理机制会在一段时间后删除那些已删除的记录,因此您可能希望使用已删除的时间戳启动架构。

转移到另一张桌子并将它们重新启动需要时间。根据离线记录的数量以及您需要将其恢复的频率,这可能是也可能不是一个好主意。

如果它们被埋没后大部分都不会回来,并且仅用于摘要/报告/任何内容,那么它将使您的主表变小,查询更简单且可能更快。

我们使用这两种方法来处理非活动记录。我们使用的方法取决于具体情况。对于基本上是查找值的记录,我们使用Active位字段。这允许我们停用条目以便它们不被使用,但也允许我们通过关系维护数据完整性。

我们使用“移动到分离表”。不再需要数据且数据不属于关系的方法。

这种情况确实决定了解决方案,其中包括:

如果该表包含用户,那么几个“标记”表示用户。可以使用字段。一个用于删除,禁用等。或者如果空间有问题,那么禁用的标志就足够了,如果它们被删除则实际删除该行。

它还取决于存储数据的策略。如果有保存数据的策略,那么在很长一段时间后很可能需要一个单独的表。

不 - 这是一件很常见的事情 - 根据具体要求提供一些变化(但你已经覆盖了它们):

1)如果你希望有一个完整的BUNCH数据 - 比如多TB或更多 - 立即存档已删除的记录并不是一个坏主意 - 尽管你可能会使用标记为已删除的组合方法,然后复制到存档表。 / p>

2)当然,硬删除记录的选项仍然存在 - 虽然我们的开发人员往往是数据包 - 老鼠 - 我建议您应该查看业务流程并确定是否现在还需要保留数据 - 如果有的话 - 这样做......如果没有 - 你应该可以随意将这些东西扔掉.....根据具体的业务情景。

从'纯粹主义的角度'看,现实模型不区分视图和表格 - 两者都是关系。因此,如果实体被正确命名,那么使用使用鉴别器的视图是非常有意义和有效的。人/ ActivePerson。

另外,从'纯粹主义的角度'来看,这个表应该被命名为person,而不是人,因为关系的名称反映了一个元组,而不是整个集合。

关于索引布尔值,为什么不:

ALTER TABLE users ADD INDEX index_users_on_active (id, active) ;  

这不会改善搜索吗?
但是我不知道答案中有多少取决于平台。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top