我正在尝试创建一个用于将事件存储到company
-object 的日志表,恐怕我可能走错了路。我得出的结论是我应该在同一列中记录不同的数据类型,但感觉不对。我将用 2 个表解释基本用例;company
和user
。
company
- id int
- name nvarchar
- description
user
- id int
- name nvarchar
- company int (references company.id)
现在,假设我想在company
-object 上记录不同类型的事件。我会创建一个名为的日志表company_log
并将company_log_type
事件存储在那里。这些表看起来像这样:
company_log
- id int
- old_value nvarchar
- new_value nvarchar
- log_type int (references company_log_type.id)
company_log_type
- id int
- name
有趣事件的例子是
- 公司名称已更改
- 公司描述已更改
- 一个用户被添加到公司
- 用户已从公司中删除
对于前两个事件,我将存储事件类型、旧值和新值。只要我停在这里,它就可以正常工作。但是,如果我想记录 2 个以前的事件,我需要能够在同一列中存储不同的数据类型。更改看起来像这样:
old_value new_value log_type
----------------------------------------------
Acme PiedPiper CompanyNameChanged
NULL 132 UserAdded
97 NULL UserRemoved
在这一点上,我需要存储公司名称的文本旧/新值,以及最近添加的用户的 ID。你可能会看到我已经走错了方向,这就是我寻求帮助。我有两个问题:
我应该只使用sql_variant
-datatype,还是如果这被认为是糟糕的设计,那么存储这些日志事件的明智方法是什么?
提前致谢。
sql_variant 类型存在限制和困难。有关详细信息,请参阅 MSDN:SQL 变体
正如您已经“感觉”到的那样,您可能还会陷入稍后转换和转换的问题。有关示例,请参阅显式转换 SQL Server 数据类型的 10 个理由。
如果可能的话,我会尽量避免这种情况和任何其他情况的变体。
但是您的基本问题不是变体类型,而是您的表格设计。即使您的日志表中只有整数值,我仍然会考虑将其更改为更规范化的值。
但是,在考虑了您的问题之后,我想到了另一种可能值得一试的方法:为什么不将日志表设计为与原始表相同。
例如:
这样,您可以在每次更改原始行时添加一个新行,并将前一行添加到日志表中。这将为您提供行的完整历史记录,而不会出现任何数据类型问题。
您还可以将日志记录限制为特定列的更改。我想你需要触发器来实现它。
它会给你多个日志表,但如果你保持它们相似
log_type
,log_stamp
你仍然可以查询它们的任何更改(跟踪表)的整个历史UNION
。我发现了另一个问题,其中非常详细地解释了这个问题和其他可能的解决方法:How to store historical records in a history table in SQL Server