数据库索引是一种单独的、物理的数据库结构,用于对数据库表中一列或多列的值进行排序。它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。
索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引的方式与您使用书籍中的索引的方式很相似:它搜索索引以找到特定值,然后顺指针找到包含该值的行。
索引的底层是 B 树,B 树的中间元素不储存数据,只储存索引,数据存储在 B 树的叶子节点处,一个节点可以存放多个数据,查找一个节点的时候可以有多个元素,大大提升查找效率,这就是为什么数据库索引用的就是 B 树,因为索引很大,不可能都放在内存中,所以通常是以索引文件的形式存储在磁盘上。数据库索引可以大大加快查询的速度,因为在数据十分庞大的时候,索引可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据。索引类型包括聚集索引、非聚集索引和联合索引等。聚集索引是在数据库中,所有行数都会按照主键索引排序;非聚集索引就是给普通字段加上索引;联合索引是好几个字段组成的索引。
PostgreSQL 支持多种类型的索引,包括 B-Tree 索引、哈希索引、GIST 索引、SP-GiST 索引、GIN 索引和 BRIN 索引。每种索引类型都有其独特的优点和适用场景。
我们这边先不细究各种各样的索引有什么用,先了解它的使用方式:
testdb=# select * from company;
id | name | age | address | salary
----+------+-----+----------------------------------------------------+--------
2 | CC | 23 | BeiJing | 100000
4 | Eoe | 27 | BeiJing | 100000
3 | Dod | 25 | BeiJing | 100000
5 | Fof | 25 | Guangzhou | 65000
6 | Gog | 27 | Shenzhen | 85000
(5 rows)
testdb=# create index city_index on company(address);
CREATE INDEX
这边那就是给company的表中的address这一列,加上了一个名叫city_index的指引,当我们查找通过where address 进行条件搜索时,能够更快地返回结果。
testdb=# drop index city_index;
DROP INDEX
如果我们对于address的筛选太少,或者说总得数据太少。我们就没必要添加索引
单列索引就是以表内的某一个列上创建索引,比如刚刚的例子就是以address创建索引
create index single on company(address);
组合索引相对单列索引而言,就是基于多个列创建的索引,如果创建索引(a, b, c),那么在筛选条件a,ab或者abc时就会更加便捷。
create index combine on company(name, age);
唯一索引不允许在列中插入重复的值,因此只适合于每一行都不一样的字段。
create unique index onlyone on company(id);
局部索引只是在表的子集上构建,子集是通过表达式定义的,只要满足条件的行都会被添加上索引。
create index part on company(条件表达式)
一般来讲,数据库会自动给主键添加上索引,插入的表的顺序和索引的顺序是一致的,因此给递增的主键加上索引是最方便且最便捷的。
建立索引是基于大数据量,并且筛选查询非常频繁的情况下,通过牺牲磁盘空间和插入更改的速度从而加快查询速度的方式。例如,假设有一个包含 1000 行数据的表,其中某一列的值都是唯一的。如果没有索引,查询该列的值需要扫描整个表,耗时较长。如果建立了该列的索引,数据库就可以通过索引快速定位到该列的值,从而提高查询效率。但是这样不免会给磁盘,以及修改数据时带来较大的开销。
我们在建表之后,由于业务的扩展或者其他的原因,经常要对已经建好的表进行修改,这时候就可以使用alter table添加和删除列与随机约束。
#修改age列从int转化为vvarchar(50)
alter table compnay alter column age varchar(50);
#添加新的列
alter table company add column email varchar(100);
#删除旧的列
alter table company drop column email;
#修改某个值的默认值
alter table company alter column salary set default 100;
#添加非空约束
alter table compnay alter column salary not null;
删除表,更准确地说是清空表,和delete不同,delete后整张表都没了,但是truncate只是删除表的数据,不删除表的结构。效果是可以立即释放空间,在大型表上非常有用。
直接看例子把。
testdb=# select * from company;
id | name | age | address | salary
----+------+-----+----------------------------------------------------+--------
2 | CC | 23 | BeiJing | 100000
4 | Eoe | 27 | BeiJing | 100000
3 | Dod | 25 | BeiJing | 100000
5 | Fof | 25 | Guangzhou | 65000
6 | Gog | 27 | Shenzhen | 85000
(5 rows)
testdb=# truncate table company;
TRUNCATE TABLE
testdb=# select * from company;
id | name | age | address | salary
----+------+-----+---------+--------
(0 rows)
PostgreSQL 视图 (View) 是一种虚拟表,它不存储数据,而是从一个或多个基本表中动态地检索数据。通过创建视图,可以简化复杂的查询,并且可以在不直接访问基本表的情况下从视图中查询数据。
testdb=# select * from students;
id | name | age | gender | class_id
----+--------+-----+--------+----------
1 | 张三 | 18 | 男 | 1
2 | 李四 | 19 | 女 | 1
3 | 王五 | 20 | 男 | 2
4 | 赵六 | 18 | 女 | 2
5 | 陈七 | 19 | 男 | 3
6 | 孙八 | 20 | 女 | 3
7 | 周九 | 18 | 男 | 4
8 | 吴十 | 19 | 女 | 4
9 | 郑十一 | 20 | 男 | 5
10 | 王十二 | 18 | 女 | 5
11 | 何一 | 23 | 女 | 5
12 | 和二 | 32 | 男 | 5
(12 rows)
testdb=# create view adult as select id, name, age from students where age > 19;
CREATE VIEW
testdb=# select * from adult;
id | name | age
----+--------+-----
3 | 王五 | 20
6 | 孙八 | 20
9 | 郑十一 | 20
11 | 何一 | 23
12 | 和二 | 32
(5 rows)
drop view adult;