The*_*uad 8 sql-server-2008 normalization database-design sql-server
我正在构建一个跟踪计算机设备和其他硬件设备的库存数据库。在任何设备生命周期的某个时刻,它都会退役并被归档。归档后,需要对其进行跟踪,因为它已从服务中移除并妥善处置。我最初使用活动数据库的精确副本设计了归档机制,该副本将使用从活动数据库中删除时的触发器接收其数据。存档数据库包括所有相关表的副本,因为由于某些外来相关记录不再相关,因此用户不应访问它们以用于新设备,但需要使用存档表进行引用完整性和查询。请记住,此处存档的概念不仅仅是保存历史记录或日志。归档是业务流程的一部分,
下面的 ERD 使用该Inventory.DeviceType
表作为示例,其中所有条目和更新都复制到该Archive.DeviceType
表中。当用户不再能够输入某种设备类型的库存记录时,它会从Inventory.DeviceType
表中删除,但保留在存档表中。此模式用于所有表以确保存档引用有效数据,因此是所有表的副本。
活动表示例(省略其他相关表)
归档表示例(省略其他相关表)
问题
我想弄清楚如果我不知道设备是活动的还是存档的,我将如何查询数据库?例如,如果用户有一个序列号并想查找有关设备的信息,而他们不知道它是否已存档。
选项 1:基于联合创建一个视图?
选项 2:如果第一个查询没有返回任何内容,则查询活动数据库,然后查询存档?
传奇还在继续……
一位同事建议我删除存档数据库并使用软删除方案。我使用这个想法构建了一个模型,然后开始遇到许多其他问题。
以下是使用软删除方案的相同表。
软删除示例
使用此设置,通过将IsArchived
field设置为 true 并输入ArchivedDate
. 我可以轻松查询任何设备是否处于活动状态或已存档。(请忽略该IsActive
字段,因为它用于不相关的概念)。
请注意电话子类型表,我必须在其中传播 DeviceID 和 IsArchived 标志的索引,因为活动设备的电话号码必须是唯一的。我也必须对其他子类型表执行此操作。我不知道这是一个好还是坏的设计。
这部分真的让我很困惑......
在外键值可以标记为已删除的情况下,处理软删除的最佳做法是什么。我唯一能想到的就是创建一个例程来搜索与已删除数据相关的所有记录,并为用户创建一个报告来解决差异。例如,如果位置表与设备表相关,并且某些位置被软删除,则设备指的是不再存在且必须移动的位置。
顺便说一下,我使用的是 MS SQL Server 2008 R2,我计划在我的应用程序中使用 Entity Framework 4。我更看重数据库的可维护性而不是性能。
感谢您的阅读。
我会说,如果您的用户需要查询存档数据,那么使用bit
标志或soft delete
更容易。如果用户不再需要这些数据,那么我会使用存档表。
根据您上面的描述,我建议使用该Soft Delete
版本。我可以从我们的一个系统中的经验告诉您,我们使用存档模式将旧数据移至其中,但只会导致问题,因为用户需要访问数据。所以它导致UNION ALL
在我们必须运行的每个查询上使用。
由于这些问题,我们停止了该路线并转向软删除,这要容易得多。
我们bit
向所有需要的表添加了一个标志,然后WHERE
在查询数据时将其包含在子句中。
一个建议是确保此字段在您INSERT
数据时具有默认值。如果您正在使用,IsArchived
那么列上的默认值将为 false,因为您不希望它立即存档。