键/值数据库的二级索引

时间:2019-02-04 12:06:43

标签: database go database-design leveldb

可以说,我的数据结构如

 type User struct {
      UUid string 
      Username string
      Email String 
      Password string 
      FirstName string 
      LastName string
}

我正在将Users [] User存储到levelDB中的键/值数据库中。唯一密钥将是UUid,然后将用户结构赋予该用户密钥并根据该UUID进行存储。

var network bytes.Buffer // Stand-in for a network connection
enc := gob.NewEncoder(&network)
err := enc.Encode(user)
   if err != nil {
      log.Println("Error in encoding gob")
      return "", err
 }
err = dbSession.DBSession.Put([]byte(user.UserID), network.Bytes(), nil)

由于所有条目的键都是唯一的uuid,因此我想在电子邮件上创建二级索引,这样就不必扫描数据库中存在的所有条目来查找与电子邮件相对应的特定条目。 / p>

我做了什么: 我创建了一个称为SIndex的键,并在其中存储了map [string] [string]数据结构,其中的键将是电子邮件,值将是uuid。每次有新条目进入时,此Sindex都会更新,以容纳新的uuid和电子邮件。

这是一个不好的方法: 因为随着数据的增长,需要获取和解码与Sindex对应的整个地图,如果不存在电子邮件,请向Sindex添加新密钥,对其进行编码并再次存储。

B树比较合适。

我的问题:将二级索引数据存储在数据库本身中是否正确,如果不是,我应该使用什么策略来实现二级索引,我知道二级索引的选择会受到数据的很大影响,但是有什么好处吗? B-Tree,HashMaps之外的其他框索引算法?

1 个答案:

答案 0 :(得分:1)

  

在数据库本身中存储二级索引数据是否正确

是的,没关系。但是,正如乔纳斯(Jonas)在评论中指出的那样,您应该将电子邮件作为密钥,并将UUID作为值。另一种选择是使用电子邮件作为数据库的密钥,而不是使用UUID。这样,您无需使用二级索引。

提高性能的另一种策略是,可以使用内存数据库(例如Redis)(或者可以使用LevelDB本身将数据存储在内存中)来存储二级索引(电子邮件作为键,而UUID作为值)。

  

除了B-Tree,HashMaps之外,还有没有其他好的现成索引算法?

无论如何,B树和HashMap是数据结构,而不是算法。实际上,您所做的并不是使用HashMap进行索引,它只是将HashMaps存储为密钥的值。索引通常取决于DBMS的实现(我们只能从它们提供的选项中进行选择)。

因此,关于用于索引的数据结构是否良好,实际上取决于用例。例如,如果需要进行范围搜索,则可以使用B-Tree(大多数DBMS默认使用),B +树(MySQL InnoDB默认使用)和Skip List(跳过)(Redis使用此数据结构对其进行排序)组)。您可以阅读有关使用Redis Sorted Set here进行二级索引的更多信息。

对于您的情况,您只需要将电子邮件存储为密钥,将UUID存储为值。哈希表通常用于此目的。大多数DBMS使用此数据结构来进行主键访问,而时间复杂度仅为O(1)。而且我相信LevelDB的实现也基于此数据结构。