很多人一听“NoSQL”,第一反应就是“不支持SQL”、“没结构”、“没法建索引”。尤其是做网站或者开发App时,数据一多就卡,有人就开始怀疑:是不是因为用了MongoDB这类NoSQL数据库,才没法加索引?
NoSQL也支持索引,而且很常用
其实,NoSQL数据库不仅支持索引,很多场景下还特别依赖索引提升查询速度。比如你在手机App里搜附近的人,后台用的可能是MongoDB,数据量几十万上百万,如果没有索引,每次都要扫全表,用户等半天都出不来结果。
MongoDB、Cassandra、Redis这些主流NoSQL系统都提供了创建索引的功能。以MongoDB为例,你可以对任意字段甚至嵌套字段建索引:
db.users.createIndex({"username": 1})
// 对地理位置建2dsphere索引
db.places.createIndex({"location": "2dsphere"})
建完之后,按用户名查人,或者查附近5公里的店铺,响应速度立马从几秒降到几十毫秒。
和传统数据库有点不一样
虽然能建索引,但NoSQL的索引机制和MySQL这类关系型数据库还是有区别的。比如MongoDB默认只给 _id 字段建唯一索引,其他字段要自己手动加。而且索引越多,写入速度越慢,因为每次插入数据都得同步更新索引树。
再比如Cassandra,它用的是分区键+聚簇键的结构,索引设计更讲究策略。盲目加二级索引可能导致性能反而下降。
还有些NoSQL系统比如Redis,本身是内存数据库,大多数操作是O(1)级别的,用哈希、列表直接定位,严格来说不算传统意义上的“索引”,但实现的效果是一样的——快。
实际使用中别忽略这几点
你在开发一个用户注册登录系统,用MongoDB存账号信息。如果只靠程序代码遍历查找,用户一多肯定扛不住。正确的做法是对 email 和 phone 字段分别建唯一索引,既能加速查询,又能防止重复注册。
但也要注意,不是每个字段都该加索引。比如用户资料里的“个人简介”,很少用来查询,加了索引纯属浪费内存和磁盘空间。
另外,复合索引也有讲究。像 (status, created_time) 这种组合,适合查“最近一周待审核的订单”,但如果只查 created_time,这个复合索引可能就用不上。
所以别一听NoSQL就觉得“原始”“简陋”。现代NoSQL数据库在索引支持上已经非常成熟,关键是得会用。