2011-03-29 56 views
2

我正在使用SQL Server来存储有关每个用户的几位信息。一些项目(例如用户名/密码)很少会改变,但其他项目每隔几秒改变一次(例如经度/纬度)。继续在SQL Server中更新同一行是否很糟糕?

我希望这个系统在使用时,大部分工作日的,由几个hundered用户。因此, 每个用户每天10,000次更新到此表。

他们是不利的存储不断变化的信息和大多数静态信息在同一行?我应该将静态信息保存在一张表中,并在另一张表中更改信息?

+1

我知道这并不完全回答这个问题,但是是否需要这么多的写入请求?您是否可以不使用某种形式的差异触发来编写是否帮助减少工作量? – Hawxby 2011-03-29 20:45:05

+0

@Hawxby,这是一个很好的观点。希望这会很快发生在我身上:)无论我决定做什么,我都会这样做。 – Wilka 2011-03-29 21:07:18

回答

3

只要逻辑上属于一起,您可以将所有信息保留在一张表中。您冒着用这种方式锁定用户行的风险,尽管乐观锁定大部分时间都适用。

但是,您应该只更新更新的字段。如果你对表上不同的数据项有这样的单独需求,你应该写专门的数据访问这些更新例程。

的好处是,你只需要数据从/到数据库,这将减少延迟和网络上,客户端和数据库负载转移。

3

您在当前解决方案扩大时更新,并登录在同一时间正在发生时,可能会遇到问题。如果您使用松散的SELECT *语句,登录的性能可能会降低,否则您甚至可能会面临锁定。

如果更新经/纬度是从多个源完全动态的,你应该考虑将其存储在一个新的表,甚至可能使每次更新的新行。如果多个源不断更新同一行,您肯定会面临性能/锁定问题。创建新行似乎违反直觉,但它可以让您几乎同时从多个来源导入数据,并使用时间戳或类似的方式查询数据以查找最新更新,同时仍然保持更新查询非常精简和快速。通过时间戳可以自动快速修剪。

+0

每个用户只会更新一行,并且只有该用户(即一个设备)将更新该行 - 所以不应该存在任何锁定问题。 – Wilka 2011-03-30 08:57:56

0

根据访问该数据库的应用程序的使用,你可以,如果你打算经常更新单个记录遇到锁定问题。此外,为了理智,维护和可扩展性,您可能需要查看normalization

0

如果您更新的列是集群索引的一部分(假设存在),那么您将为SQL Server造成相当多的开销,因为它会重新排列表/索引结构以维护聚类序列。如果它们是非聚集索引的一部分,则会导致维护索引结构的开销。

在这两种情况下,统计数据也都会发挥作用。您的统计信息可能会过时,从而导致查询/存储过程出现次优执行计划:您可能会以比其他方式更频繁地运行更新统计信息。不参与指数

更新固定长度列应该在的地方发生,因为数据行的大小不会改变。更新不参与索引的可变长度列或可空列会随着数据行长度的改变而导致页面拆分(更不用说由页面拆分引起的索引维护开销)。

1

如果您使用当前值覆盖LAT/LON,那么您将失去潜在的有价值/有用的数据。好,我认为,简单地插入新行到PersonLocation表:

 id autoincrementing integer 
     personid int fk references persons(id) [indexed non-unique to speed queries on person location history) 
     lat float 
     lon float 
     asof datetime default getdate() 

编辑:如果你需要经常得到当前的位置,你可以考虑在指数(PERSONID,日期时间)。

+1

+1某些地方有一些法律规定,如果数据库中存在频繁变化的信息,最终用户将需要历史记录。 – 2011-03-29 20:56:55

+0

只要存在可用于此时间序列信息的商业用途并且只要存储空间不是问题,这就是一个很好的建议。 – 2011-03-29 20:56:57

+1

@Joel:浮点数和整数不占用太多空间,而且数据的实用性在今天并不总是很明显。但是可能会有比OP的想法更多的用户,所以你的观点很好。我假设用户在跟踪当前位置时没有问题,所以位置历史记录也没有问题。其他好的建议是获得用户的权限来跟踪他们的位置。 – Tim 2011-03-29 21:00:24

0

每天10,000次更新不是您永远不必担心的事情。一分钟10000更新可能开始成为一个问题。对数据库进行建模以保持简单,并且不要因为性能原因而使用模型。 Oded关于只更新正在更改的列的建议是正确的,无论您的更新量是多少,因为无论您更新的频率如何,您仍然希望尊重带宽。