Database design 对数据库数据进行历史比较的最佳方法是什么?
我有一个数据库,里面有一个组织的员工名单。有一个主employee表和多个联接表 我希望开始跟踪此数据的每周和每月指标,以便我可以执行以下操作: 3月1日:员工人数100人(2月增加1-2人)Database design 对数据库数据进行历史比较的最佳方法是什么?,database-design,tracking,Database Design,Tracking,我有一个数据库,里面有一个组织的员工名单。有一个主employee表和多个联接表 我希望开始跟踪此数据的每周和每月指标,以便我可以执行以下操作: 3月1日:员工人数100人(2月增加1-2人) 4月1日:员工人数101人(3月增加3-2人) 5月1日:员工人数105人(4月增加10人-6人) 我正在努力寻找最好的方法来做这件事。我是否: 在每个月的第一天拍摄完整的数据库快照,让我的应用程序查询多个数据库以生成这些报告 尝试跟踪某些db触发的历史记录表中的所有更改,并尝试聚合这些信息以尝试建立每个
4月1日:员工人数101人(3月增加3-2人)
5月1日:员工人数105人(4月增加10人-6人) 我正在努力寻找最好的方法来做这件事。我是否:
如果您只是在计划中运行这个,那么我将创建一个数据汇总表。。。每月运行一次进程进行计数,并在汇总表中添加一行表示数据。这样,您就可以回顾历史并生成所需的任何统计数据。您可能想考虑以比您计划报告的频率更频繁地生成这些数据(例如,每周)。只要您的分辨率高于报告期,您就应该拥有所需的所有数据。如果您只是想跟踪新员工的雇用或终止时间,那么您应该首先向员工表本身添加相关字段:
HireDate date NOT NULL
和TerminationDate NULL
然后,在任何一天确定员工人数(以及详细信息)都非常容易:
SELECT EmployeeID, EmployeeName, ...
FROM Employees
WHERE HireDate <= @EndDate
AND (TerminationDate IS NULL OR TerminationDate > @BeginDate)
然后用触发器保持:
CREATE TRIGGER tr_Employees_History
ON Employees
FOR INSERT, UPDATE
AS BEGIN
INSERT EmployeeHistory (TransactionDate, TransactionType, EmployeeID, ...)
SELECT
GETDATE(),
CASE
WHEN d.EmployeeID IS NULL THEN 1
WHEN (i.TerminationDate IS NOT NULL) AND
(d.TerminationDate IS NULL) THEN 3
ELSE 2
END,
i.EmployeeID, i.EmployeeName, ...
FROM inserted i
LEFT JOIN deleted d
ON d.EmployeeID = i.EmployeeID
END
我假设您不删除员工记录,只设置一个终止日期
;如果改为删除(请不要这样做),则需要编写类似的delete
触发器,而不是i.TerminationDate…行时的第二个案例
现在为您的历史记录表添加种子:
INSERT EmployeeHistory (TransactionDate, TransactionType, EmployeeID, ...)
SELECT HireDate, 1, EmployeeID, ...
FROM Employees
注意-如果您没有HireDate
,则只需将其替换为GETDATE()
-您的历史记录将仅从您播种它的那一刻起有效
现在,如果要获取历史“快照”,可以执行以下操作:
CREATE FUNCTION dbo.GetEmployeeSnapshot(@ReportDate datetime)
RETURNS TABLE
AS RETURN
WITH History_CTE AS
(
SELECT
TransactionType, EmployeeID, EmployeeName, ...,
ROW_NUMBER() OVER (ORDER BY TransactionDate DESC) AS RowNum
FROM EmployeeHistory
WHERE TransactionDate <= @ReportDate
)
SELECT *
FROM History_CTE
WHERE RowNum = 1
AND TransactionType IN (1, 2) -- Filter out terminated employees
以及更新过程:
CREATE PROCEDURE dbo.UpdateHeadcountHistory
AS
DECLARE @ReportDate datetime
SET @ReportDate = GETDATE()
INSERT HeadcountHistory (HeadCount)
SELECT @ReportDate, COUNT(*)
FROM dbo.GetEmployeeSnapshot(@ReportDate)
将最后一个存储过程作为计划作业的一部分运行,然后您将获得所需特定聚合的非规范化报告表
任何比这更复杂的事情,我想你应该开始研究数据仓库。但是如果我想深入查看历史日期的详细信息,我怎么能“返回”呢如果您想知道历史日期的详细信息,那么除了将相应的列复制到另一个表中之外,您没有其他选择。这将是一个相当不寻常的要求,我想问你为什么需要这样的历史知识水平??什么平台?例如,SQL Server 2008具有内置的更改跟踪.SQLServer 2005,但是如果这是一个2008的解决方案,那么我将考虑升级,我建议详细说明数据大小和您希望在数据上运行什么样的查询,这可能会引发一些想法。
CREATE TABLE HeadcountHistory
(
ReportDate datetime NOT NULL
CONSTRAINT PK_HeadcountHistory PRIMARY KEY CLUSTERED,
HeadCount int NOT NULL
)
CREATE PROCEDURE dbo.UpdateHeadcountHistory
AS
DECLARE @ReportDate datetime
SET @ReportDate = GETDATE()
INSERT HeadcountHistory (HeadCount)
SELECT @ReportDate, COUNT(*)
FROM dbo.GetEmployeeSnapshot(@ReportDate)