为了账号安全,请及时绑定邮箱和手机立即绑定

键/值数据库的二级索引

键/值数据库的二级索引

Go
幕布斯7119047 2023-06-05 17:11:32
比方说,我有这样的数据结构 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 connectionenc := 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,我想在电子邮件上创建二级索引,这样我就不必扫描数据库中存在的所有条目来查找与电子邮件对应的特定条目。我做了什么:我创建了一个名为 SIndex 的键,并在其中存储了一个 map[string][string] 数据结构,其中键是电子邮件,值是 uuid。每次有新条目进入时,此 Sindex 都会更新以适应新的 uuid 和电子邮件。这是一个糟糕的方法:因为随着数据的增长,需要获取和解码对应于 Sindex 的整个地图,如果电子邮件不存在,则向 Sindex 添加一个新密钥,对其进行编码并再次存储。B树会更适合。我的问题:在数据库本身中存储二级索引数据是否正确,如果不是,我应该使用什么策略来实现二级索引,我知道二级索引的选择受数据的影响很大但是有没有好的开箱即用索引B-Tree、HashMaps 以外的算法?
查看完整描述

1 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

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

您应该将电子邮件作为键,将 UUID 作为值。另一种选择是使用电子邮件作为数据库的密钥,而不是使用 UUID。这样您就不需要使用二级索引。

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

除了 B-Tree、HashMaps 之外,还有什么好的开箱即用的索引算法吗?

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

所以,关于用于索引的数据结构,它是否好,真的取决于用例。例如,如果您需要进行范围搜索,您可以使用 B-Tree(大多数 DBMS 默认使用)、B+ 树(MySQL InnoDB 默认使用)和 Skip List(Redis 使用此数据结构进行排序放)。

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


查看完整回答
反对 回复 2023-06-05
  • 1 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信