火柴人武林大会
156.74M · 2026-02-04
学会了表的基本操作后,要是想让查询更快、访问数据更省事,那“索引”和“视图”这俩好帮手可得好好学一学。说起来,索引就像咱们看书时的目录,翻找内容能省不少劲;视图呢,更像是个专属数据窗口,不仅能把复杂的查询逻辑藏起来,还能控制哪些数据能被看到。今天咱就专门聊聊“ksql命令行操作索引与视图”,从它们的作用、创建方法,到怎么查看、维护,最后怎么删除,一步步拆成实实在在的操作步骤,再配上例子和避坑小提示,保证新手朋友也能看懂、能用起来。
索引和视图都得依托已有的表才能用,所以咱得先做好下面这些准备工作(大家可以参考第四篇“表的运作”的相关内容),别到时候操作半天,因为少了基础依赖弹出一堆错误提示,那就麻烦了。
先用ksql连上本地的KingbaseES数据库,再切换到之前创建的test_schema模式里。接着得确认一下目标表在不在,就拿sys_user表举例,要是没有,要么重新建一个,要么换个新例子表,总之得保证后面的操作能顺利进行。
-- 1. 连接数据库(若未连接)
ksql -d kingbase -U system
-- 2. 切换到 test_schema 模式
SET search_path TO test_schema, public;
-- 3. 确认目标表存在(如 sys_user 表)
dt sys_user;
-- 若不存在,创建示例表(用于后续索引/视图操作)
CREATE TABLE IF NOT EXISTS sys_user (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
phone CHAR(11) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) TABLESPACE test_ts;
执行完要是显示Table "test_schema.sys_user" does not exist,那就先执行上面的CREATE TABLE语句建表,有了表,后面的操作才有载体。
为了后面能测试索引的查询速度,也能看看视图展示数据的样子,得给sys_user表加些模拟数据。最好多加点,比如上千条,这样更贴近真实使用场景。
-- 批量插入10条测试数据(可复制扩展)
INSERT INTO test_schema.sys_user (name, phone, email)
VALUES
('张三', '13800138000', 'zhangsan@test.com'),
('李四', '13900139000', 'lisi@test.com'),
('王五', '13700137000', 'wangwu@test.com'),
('赵六', '13600136000', 'zhaoliu@test.com'),
('孙七', '13500135000', 'sunqi@test.com'),
('周八', '13400134000', 'zhouba@test.com'),
('吴九', '13300133000', 'wujiu@test.com'),
('郑十', '13200132000', 'zhengshi@test.com'),
('钱一', '13100131000', 'qianyi@test.com'),
('冯二', '1300130000', 'fenger@test.com');
执行后要是提示INSERT 0 10,那就说明数据插成功了,后面的测试就有了基础。
在KingbaseES里,想让查询变快,索引可是核心手段。你想啊,要是表的数据量大,比如有10万条以上,没索引的话,查询就得“全表扫描”,一条一条找,多慢啊;但有了索引就不一样了,相当于有了“目录”,直接定位到数据,速度能快成百上千倍。接下来咱就按“创建→查看→维护→删除”的顺序好好说说。
新手朋友得先搞明白不同索引有啥用,可别瞎创建。要知道,索引不是越多越好,多了反而会增加数据更新、插入的开销。
要是经常按手机号查用户,那给sys_user表的phone列建个普通索引就很合适。
-- 语法:CREATE INDEX 索引名 ON 表名(字段名);
CREATE INDEX idx_sys_user_phone ON test_schema.sys_user(phone);
CREATE INDEX,那就说明索引建好了。给sys_user表的email列建个唯一索引也不错,既能保证邮箱不重复,查邮箱的时候也能更快。
-- 语法:CREATE UNIQUE INDEX 索引名 ON 表名(字段名);
CREATE UNIQUE INDEX idx_sys_user_email ON test_schema.sys_user(email);
email的UNIQUE约束,就不用再特意给email建唯一索引了,约束本身就会生成索引。要是经常按“姓名+创建时间范围”查数据,那给sys_user表的name和create_time列建个复合索引就很实用。
-- 语法:CREATE INDEX 索引名 ON 表名(字段1, 字段2);
CREATE INDEX idx_sys_user_name_createtime ON test_schema.sys_user(name, create_time);
建完索引,得用ksql命令看看索引列表、关联的表还有详细信息,推荐大家用di和dt+这两个命令,很好用。
执行di就能列出当前模式下的所有索引,能快速确认索引是不是建成功了。
di
执行结果示例关键信息解读:
Table:能看到索引关联的表,确认是不是sys_user表;Columns:能知道索引对应的字段,是单字段还是多字段;sys_user_pkey:这个是主键自动创建的索引,不用咱们手动建。要是想查看某张表的所有索引,比如sys_user表,执行d+ 表名就行。
d+ test_schema.sys_user
执行结果示例(索引部分): 这样能直接看到表关联的所有索引,包括索引类型(是PRIMARY KEY、UNIQUE还是普通索引)和对应的字段,清晰又直观,一眼就能看明白。
索引用久了,因为数据经常被删除、更新,可能会出现“碎片化”的情况,就是索引文件里有不少空白空间,这时候就得重建索引来改善。另外,要是想给索引重命名,或者删掉没用的索引,也有对应的方法。
要是感觉索引查询变慢了,重建索引就能整理碎片,让性能恢复。不过要注意,要是表很大,最好离线执行,别影响正常业务。
-- 语法:REINDEX INDEX 索引名;
REINDEX INDEX idx_sys_user_phone;
-- 进阶:重建表的所有索引(更高效)
REINDEX TABLE sys_user;
REINDEX,就说明重建完成了。要是索引名不符合规范,比如想把idx_sys_user_phone改成idx_sys_user_mobile,直接重命名就行。
-- 语法:ALTER INDEX 旧索引名 RENAME TO 新索引名;
ALTER INDEX idx_sys_user_phone RENAME TO idx_sys_user_mobile;
d+ test_schema.sys_user,就能看到索引名已经更新了。要是某个字段查询频率变低了,或者因为索引导致数据插入、更新变慢,那就得把没用的索引删掉。不过要注意,主键索引和跟唯一约束相关的索引不能直接删,得先把约束删掉才行。
-- 语法:DROP INDEX IF EXISTS 索引名;
DROP INDEX IF EXISTS idx_sys_user_name_createtime;
IF EXISTS:加这个是为了避免索引不存在的时候报错,只会提示个警告,很贴心;d+ test_schema.sys_user,确认索引已经删掉了就行。WHERE SUBSTR(phone,1,3) = '138'这种写法,会让索引失效。改成WHERE phone LIKE '138%'就好,前缀匹配是能用到索引的。视图其实是“虚拟表”,它是根据SQL查询结果生成的,本身不存实际数据,数据还在原始表里。但它的用处可不小,能“隐藏复杂查询逻辑”,还能“控制数据可见范围”,比如只让用户看到某些列。下面咱就按“创建-查看-操作-删除”的顺序来讲。
新手朋友容易把“表”和“视图”搞混,我给大家打个通俗的比方:
视图的核心使用场景有这几个:
sys_user表里的name和phone字段,把email这种敏感信息藏起来,用视图就能做到。咱创建一个“用户基础信息视图vw_sys_user_basic”,里面只包含id、name、phone列,把email这种敏感信息藏起来。
-- 语法:CREATE VIEW 视图名 AS SELECT 语句;
CREATE VIEW vw_sys_user_basic AS
SELECT id, name, phone
FROM test_schema.sys_user;
CREATE VIEW,就说明视图建好了。再创建一个“2024年创建的用户视图vw_sys_user_2024”,筛选出create_time在2024年的用户,里面包含name、email、create_time列。
CREATE VIEW vw_sys_user_2024 AS
SELECT name, email, create_time
FROM test_schema.sys_user
WHERE create_time >= '2024-01-01 00:00:00'
AND create_time < '2025-01-01 00:00:00';
要是想确保视图里的数据不能被改,比如报表视图,那就加个WITH READ ONLY选项。
CREATE VIEW vw_sys_user_report AS
SELECT name, phone, create_time
FROM test_schema.sys_user
WITH READ ONLY;
UPDATE vw_sys_user_report SET name='张三',就会报错“cannot update a read-only view”,根本改不了。建完视图,得用ksql命令看看视图列表、定义还有关联的表,推荐用dv和d+这两个命令。
执行dv就能列出当前模式下的所有视图,能快速确认视图是不是建成功了。
要是忘了视图的筛选条件,想确认一下视图的底层SQL,执行d+ 视图名就行。
d+ vw_sys_user_2024
执行结果示例(定义部分): 这样能直接看到视图完整的SQL定义,后面想修改或者验证逻辑都很方便。
视图最主要的操作是“查询”,修改和删除都有特定的规则,可不能随便来。
查询视图数据的语法和查表一模一样,不用额外学新东西。
-- 查询基础视图数据
SELECT * FROM vw_sys_user_basic;
-- 查询2024年用户视图,按创建时间排序
SELECT * FROM vw_sys_user_2024 ORDER BY create_time DESC;
vw_sys_user_basic里就看不到email列。要是想调整视图的筛选条件或者包含的列,比如把vw_sys_user_2024改成包含2023年的数据,不用删了视图重新建,直接用CREATE OR REPLACE修改就行。
CREATE OR REPLACE VIEW vw_sys_user_2024 AS
SELECT name, email, create_time
FROM test_schema.sys_user
WHERE create_time >= '2023-01-01 00:00:00'
AND create_time < '2025-01-01 00:00:00';
d+ vw_sys_user_2024,确认视图定义已经更新了就行。要是某个视图不用了,就把它删掉。放心,删除视图不会影响原表数据,只是把视图的定义删掉了。
-- 语法:DROP VIEW IF EXISTS 视图名;
DROP VIEW IF EXISTS vw_sys_user_report;
dv,确认视图已经删掉了就可以。READ ONLY,只要有下面这些情况,也没法改数据:
DISTINCT(去重)、GROUP BY(分组)、HAVING(筛选分组);COUNT、SUM;JOIN)来的;sys_user表没了,那对应的视图就成了“无效视图”,再查这个视图就会报错“relation does not exist”。JOIN时用到的关联列,一定要提前建好索引。报错信息:
ERROR: duplicate key name "idx_sys_user_phone"
原因:这明显是同名的索引已经存在了,比如之前已经创建过idx_sys_user_phone。
解决方案:
di看看索引名,确认是不是真的重复了;DROP INDEX idx_sys_user_phone;,然后再建新的。报错信息:
ERROR: relation "vw_sys_user_basic" does not exist
原因:
vw_sys_user_basic写成了vw_sys_user_basci;test_schema模式下,但当前的搜索路径是public。
解决方案:dv确认一下正确的名称;SET search_path TO test_schema, public;;要么查询的时候用“模式名.视图名”的全称,比如SELECT * FROM test_schema.vw_sys_user_basic;。报错信息:
ERROR: cannot update a read-only view "vw_sys_user_report"
原因:这是因为创建视图的时候加了WITH READ ONLY选项,就是禁止修改的。
解决方案:
要是想允许修改,就重新创建视图,把WITH READ ONLY去掉:
CREATE OR REPLACE VIEW vw_sys_user_report AS
SELECT name, phone, create_time FROM sys_user;
不过要注意,重新创建之前得确认这个视图没有其他修改限制,比如不含GROUP BY、聚合函数这些。
今天把索引和视图的核心操作都讲透了,核心要点总结一下:
vw_sys_user_2024视图对应的sys_user原表建个create_time索引,视图的查询效率能提升不少。学会了索引和视图,你在KingbaseES里查数据就能又快又方便了。下一篇咱就讲“用户与权限管理”,让数据库访问更安全,实现“不同用户看不同数据”的精细控制。