【问题标题】:Detect if a table in my database has changed for optimization need检测我的数据库中的表是否因优化需要而更改
【发布时间】:2013-02-18 23:59:20
【问题描述】:

我正在使用 Sql Server Compact 并正在构建一个 MVC 应用程序。

在获取我的数据时,许多表都建立了许多链接,最终会演变成复杂的循环和较长的加载时间,因为每次加载数据时都要获取数据并建立链接。

所以我认为优化是一个好主意,而实现这一目标的一种方法是在加载任何数据之前检查数据是否发生了变化。如果为真,则进行总加载,否则引用实际存在的数据结构。

有没有办法检查我的数据库表中的数据是否发生了变化?也许是一种方法?

谢谢!

【问题讨论】:

  • 选择正确的答案!

标签: c# asp.net-mvc database optimization


【解决方案1】:

正如斯派罗在their answer here 中所说:

简单的方法是添加一个 TIMESTAMP 类型的可为空的列,使用 触发器:

ON UPDATE CURRENT_TIMESTAMP。

因此,插入不会改变,因为列接受 nulls,您可以通过以下方式仅选择新的和更改的列:

SELECT * FROM `table` WHERE `mdate` > '2011-12-21 12:31:22'

每次更新一行时,此列都会自动更改。

以下是更多信息: http://dev.mysql.com/doc/refman/5.0/en/timestamp.html

要查看已删除的行,只需创建一个将记录日志的触发器 每次删除到另一个表:

DELIMITER $$
CREATE TRIGGER MyTable_Trigger
AFTER DELETE ON MyTable
FOR EACH ROW
BEGIN
  INSERT INTO MyTable_Deleted VALUES(OLD.id, NOW());
END$$

或者您可以对所有表格结果执行哈希函数(MD5,SHA1)并将其保存为MD5(table); 如果MD5(table);的值改变了,表就改变了!

// Serialize the table
DataContractSerializer serializer = new DataContractSerializer(typeof(DataTable));
MemoryStream memoryStream = new MemoryStream();
XmlWriter writer = XmlDictionaryWriter.CreateBinaryWriter(memoryStream);
serializer.WriteObject(memoryStream, table);
byte[] serializedData = memoryStream.ToArray();

// Calculte the serialized data's hash value
SHA1CryptoServiceProvider SHA = new SHA1CryptoServiceProvider();
byte[] hash = SHA.ComputeHash(serializedData);

// Convert the hash to a base 64 string
string hashAsText = Convert.ToBase64String(hash);

【讨论】:

  • 哇!想要!我最终会深入研究这个,所以你很高兴告诉我:)我很感激!
  • 你知道有什么方法可以在我的数据类的其他时间戳中用 C# 进行检查吗?
  • 我在我的答案中添加了其他方式检查它!
  • 如果您复制他人的话,您必须提供正确的署名。我已经编辑了上面的内容,以表明您的答案的第一部分是从哪里得出的。以后,请务必自己做。
【解决方案2】:

您知道,当我构建一个离线解决方案时,人们可以离线更改数据,然后在晚上将其同步备份,我找到了确定我们的配置数据的最佳方法(就像你正在处理)是在每一行都持有一个timestamp。之所以如此有效,是因为我可以构建一个表,根据对每个表的简单 MAX 查询来索引这些 timestamp 值。因此该表可能如下所示:

CREATE TABLE TimestampIndex (
    TableName SYSNAME PRIMARY KEY,
    LastChange TIMESTAMP
)

然后我可以运行基本查询并在它们离线时填充该表:

IF EXISTS (SELECT TableName FROM TimestampIndex WHERE TableName = 'Table1')
    UPDATE TimestampIndex SET LastChange = (SELECT MAX(ts) FROM Table1)
ELSE
    INSERT INTO TimestampIndex (TableName, LastChange) SELECT 'Table1', MAX(ts) FROM Table1

然后当他们重新上线时,我可以简单地执行以下操作:

IF NOT EXISTS (SELECT TableName FROM TimestampIndex WHERE TableName = 'Table1' AND LastChange = (SELECT MAX(ts) FROM RemoteDb.dbo.Table1))
BEGIN
    -- there must be changes to make then
END

【讨论】:

  • 这和我的回答原理一样吗?
  • @OneManCrew,类似。但请记住,我是在您添加的同时添加的,所以我什至没有阅读您的。其次,您的原则更细粒度,而我的原则更高,如果表存在更改,则需要 OP 重新加载所有配置。它对于持续检查的性能更高,而对于配置数据的粒度加载可能性能更低。但是,根据我的经验,我发现问题不是加载数据,而是加载每个表。但是,它不太可能需要您投反对票;)
猜你喜欢
  • 2015-01-13
  • 1970-01-01
  • 2021-04-06
  • 2012-08-13
  • 1970-01-01
  • 2018-02-25
  • 2011-02-27
  • 1970-01-01
  • 2011-02-03
相关资源
最近更新 更多