数据库选择快速更新

时间:2012-06-25 23:30:13

标签: database performance database-design

我们有很多这样的课程(数百万)

class WordInfo
{
     string Value;
     string SomeOtherFeatures;
     List<Point> Points;
}

以下代码

 private Dictionary<string, WordInfo> _dict;

   public void ProcessData(IEnumerable<Tuple<string,int,int> words)
   {
        foreach(var word in words)
        {
             if(_dict.ContainsKey(word.Item1))
             {
                 _dict[word.Item1].Points.Add(new Point(word.Item2,word.Item3));
             }
             else
             {
                 _dict.Add(word.Item1, new WordInfo(....))
             }
        } 
   }


   Main()
   {
       while(true)
       {
           IEnumerable<Tuple<string,int,int> data = GetDataSomewhere();
           ProcessData(data); 
       }
   }

正如您所看到的,此代码必须24 \ 7才能正常工作。主要问题是我不知道如何在数据库中表示_dict(我存储信息的地方)。我需要每秒处理1000-5000字。关系数据库对我的任务不利,对吧? NoSQL怎么样?我需要快速UPDATE和INSERT操作。另外我需要快速检查db中是否存在单词(SELECT)。因为我有数百万条记录,所以也不是一件容易的事。你能建议什么?可以根据文件编写我的自定义解决方案吗?

1 个答案:

答案 0 :(得分:2)

关系数据库应该能够轻松地每秒插入/更新1000-5000字,假设您没有创建太多的事务。

事务是ACID,“D”表示持久:当客户端收到事务提交的通知时,可以保证事务的影响已经存在于永久存储中(所以甚至如果在那个确切的时刻发生停电,交易将不会被“擦除”)。实际上,这意味着DBMS必须等待磁盘完成物理写入。

如果将每个插入/更新包装在自己的事务中,则还必须对每个插入/更新执行此等待。 OTOH,如果你在一次交易中包装许多插入/更新,你将不得不每整个“块”支付这个价格。


此外,由于B-Tree indexes的强大功能,检查数百万其他行中是否存在特定行是一个非常擅长的任务数据库。


至于数据库结构,你需要类似的东西:

enter image description here

你会像这样处理它(伪代码):

BEGIN TRANSACTION;

foreach(var word in words)
{
     try {
         INSERT INTO WORD (WORD_VALUE, SOME_OTHER_FEATURES) VALUES (word.Item1, ...);
     }
     catch (PK violation) {
         // Ignore it.
     }

     try {
         INSERT INTO POINT (WORD_VALUE, X, Y) VALUES (word.Item1, word.Item2, word.Item3);
     }
     catch (PK violation) {
         // Ignore it.
     }
} 

COMMIT;

(注意:我假设你在最初插入之后永远不会更新SOME_OTHER_FEATURES。如果你这样做,上面的逻辑会更复杂。)

如果您的DBMS支持它,请考虑将这两个表聚集在一起(aka。index-organized)。此外,如果您的DBMS支持它,请压缩POINT主索引(WORD_VALUE)的前沿,因为与该词相关的所有点都包含相同的值。


BTW,上面的模型使用所谓的识别关系和自然键。使用代理键和非识别关系的替代模型是可能的,但会使您需要的处理类型复杂化。