SQL Server Change Data Capture 是一项从 SQL Server 事务日志中读取历史数据并将其存储在特殊表中的功能。
通过使用特殊的表值函数 (TVF),它允许用户查询这些数据,从而可以获取特定表上的所有更改或仅获取特定时间内更改导致的净更改。
CDC具有一定的优势
它也有一些缺点:
我已经阅读了很多关于 CDC 的文章,虽然我现在知道如何使用它,但我仍然不确定它是否适合我。
我经常听说 CDC 是一个审计工具,但这不是SQL Server 审计的用途吗?它们是用于同一任务的不同工具吗?或者CDC可以用于其他用途吗?
我目前的情况是,我被要求构建一个可靠的数据框架,该框架应该是未来多个应用程序的基础。确切的要求是模糊的,但其中之一是它应该能够跟踪数据历史并将旧条目与其他表中的所有相关数据一起恢复。我现在正在评估 CDC 作为一种选择,但不确定这是否是可行的方法,因为我真的找不到任何推荐的用例。
虽然我很欣赏针对我的特定场景的建议,但答案应该提供有关何时或何时不使用 Change Data Capture 的一般建议。
该表看起来像这样,它是 SCD 类型 2:
+-----------+------------------+------------------------+
| id (text) | version (serial) | created_at (timestamp) |
+-----------+------------------+------------------------+
Run Code Online (Sandbox Code Playgroud)
对于 99% 的查询,我们将搜索整个表并按附加列和连接表进行过滤。对于这些查询,我们只对每个唯一 ID 的记录的最新版本感兴趣。我们还将按created_at和其他列进行排序。
为了方便查找最新记录,我正在考虑添加一most_recent (boolean)列,如此处答案中所述:
然而我意识到我们已经有了created_at告诉我们这些信息的列 - 我们可以在搜索查询中使用 DISTINCT 子句并按创建日期排序,如 @Svet 的答案所述:
但是,我们随后必须按我们实际想要用来显示数据的列对结果重新排序。
从长远来看,添加额外的“当前”字段似乎更简单,并且性能会更高,但这也是不好的做法吗?
我知道 SQL Server 2016 让我们使用 SYSTEM_VERSIONING 像:
CREATE TABLE EmpSalary
(
EmpID int NOT NULL PRIMARY KEY CLUSTERED
, SalaryAmt decimal (10,2) NULL
, SalaryBeginDT datetime2 GENERATED ALWAYS AS ROW START NOT NULL
, SalaryEndDT datetime2 GENERATED ALWAYS AS ROW END NOT NULL
, PERIOD FOR SYSTEM_TIME (SalaryBeginDT, SalaryEndDT)
)
WITH (SYSTEM_VERSIONING = ON);
Run Code Online (Sandbox Code Playgroud)
同样要停用此功能,只需更改表:
ALTER TABLE EmpSalary SET (SYSTEM_VERSIONING = OFF );
Run Code Online (Sandbox Code Playgroud)
我的问题是如何检查表的 SYSTEM_VERSIONING 是否打开,然后更改表?
Oracle 以外的其他数据库是否有ora_rowscn(http://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns007.htm)等价物,或者您是否必须在您的字段、代码和存储过程中自己实现它们?
ora_rowscn是附加到使用某些特定设置创建的 Oracle 中所有表的伪列,在执行乐观离线锁定时使用。
我是数据库设计师,在我当前的项目中,我正在实现在 RDBMS 中同时编辑数据行所需的版本控制功能。项目要求说,数据编辑会话可以持续几个小时或几天,直到执行提交。此外,在不同用户同时修改相同数据时产生的冲突应该以手动和半自动解决的可能性进行处理。换句话说,所需的编辑工作流类似于面向文档的版本控制系统(例如 SVN 或 Git)中使用的工作流。因此,传统的 OLTP 方法和冲突解决策略(MVCC、乐观/悲观锁)不能满足我的约束。我对现有工具进行了一些观察,这些工具为分支版本历史记录和多版本工作流提供了可能性:
SQL:2011 没有解决我的问题,因为它提供了对“线性”编辑历史的支持,而不是我正在寻找的分支。ESRI 和 Oracle 的解决方案是不错的候选者,但我很失望它们都具有用于操作版本的供应商特定接口。目前似乎没有人可以为关系数据的分支版本控制提供行业标准的解决方案(就像 SQL:2011 为时态表和线性版本历史所做的那样)。作为一名新来的数据库研究员,我想了解:
我想我可以尝试深入挖掘并提出一些标准模型或子语言来处理类似 Git 的版本控制,但我不知道从哪里开始。
ESRI 的空间数据库管理系统称为地理数据库( more ),使用一种称为版本控制的技术。
版本代表整个地理数据库的时间快照,并包含地理数据库中的所有数据集。
版本不是地理数据库的单独副本。相反,版本和其中发生的事务在系统表中进行跟踪。这将用户的工作隔离在多个编辑会话中,允许用户在不锁定生产版本中的功能或立即影响其他用户且无需制作数据副本的情况下进行编辑。
http://help.arcgis.com/en/geodatabase/10.0/sdk/arcsde/concepts/versioning/basicprinciples/state.htm
将数据集(要素类、要素数据集或表)注册为版本时,会创建两个增量表:A(或添加)表,记录插入和更新,D(或删除)表,存储删除。每次更新或删除数据集中的记录时,都会向其中一个或两个表中添加行。因此,版本化数据集由原始表(称为基本表或业务表)加上增量表中的任何更改组成。当您进行填充增量表的编辑时,地理数据库会跟踪您连接到的版本。当您查询或显示某个版本中的数据集时,ArcGIS 会组合原始表和增量表中的相关行,以提供该版本数据的无缝视图。
老实说,我发现文档相当模糊;它并没有告诉我该技术的实际工作原理,或者它基于传统数据库理论的哪一部分。
我想不会有很多 DBA SE 社区成员对 ESRI 的版本控制技术有经验。所以我不会问诸如“它是如何工作的?”之类的问题。
相反,我想知道,在非空间数据库世界中是否有与 ESRI 版本控制类似的技术?
处理包含多个版本的数据记录时有两种策略。一种是将当前记录放在一张表中,将其过去的版本放在历史表中。
另一种是将所有版本放在同一个表中,并在当前版本上添加一个标志。
我已经看到了每种策略的争论,并且我已经看到社区在不同的帖子中同意这两种策略。
如果没有正确答案,如何决定采取哪种策略?我可以看到将所有记录保留在同一个表中以简化查询(所有记录都在一个表中)和一般情况下表较少的优点。
另一方面是,您拥有这些巨大的表,其中包含大量记录,具体取决于表之间的版本数量和复杂关系。
Pro 历史表数据库设计是否需要修订?数据库历史记录更改,相同还是不同的表?
正如文档所述,每次在整个数据库范围内使用全局自动递增数字更新行时,rowversion数据类型都会自动更新。
我的问题如下:假设我对具有rowversion列的表有 10000 个并发更新。由于所有人都尝试以原子方式访问和更新该全局号码,因此我想所有这些都以“串行”方式处理,与不需要访问该号码的表相比,这可能会降低性能。
它是否正确?。