开发转兼职DBA(一):只会写SQL的那几年
开发转兼职DBA(一):只会写SQL的那几年
非科班野生程序员,深耕政务信息化20年。这篇文章是一个系列的开始——讲我怎么从一个只会写CRUD的开发,被生产事故一步步逼成兼职DBA的。先从只会写SQL的那几年说起。
文章目录
- 开发转兼职DBA(一):只会写SQL的那几年
- 先说清楚:这个系列写给谁
- 系列内容
- 我的前数据库时代
- 第一次被打脸
- DML与DDL:开发者的两把刀
- DML(Data Manipulation Language)
- DDL(Data Definition Language)
- 缺的那一课:执行计划
- 那个阶段的水平总结
- 为什么开发者需要懂一点DBA
先说清楚:这个系列写给谁
大厂有专职DBA——应用DBA管SQL审核,系统DBA管安装部署,运维DBA管监控告警,架构DBA管分库分表。开发者只管写代码,慢了提工单找DBA。
但我们不是大厂。我们是小团队。开发是你,测试是你,出了事运维还是你。没有工单系统,没有DBA兜底,数据库挂了半夜爬起来只能自己上。
大厂的开发者不需要知道这些。小团队的不知道就得出事。
这个系列讲的,就是小团队里,开发需要知道多少DBA知识才扛得住。不是教你怎么当专业DBA,是被生产环境逼出来的生存技能。
系列内容
- 只会写SQL的那几年(本篇)——DML/DDL与执行计划
- 执行计划教我做事——从全表扫描到索引优化
- 数据库起不来了——WAL、事务与redo日志
- 又起不来了——MVCC、undo与回滚段
- 从救火到防火——参数、内存、监控、备份
- 换了个数据库,问题还是那些问题——跨库通用的底层原理
- 不是SQL的锅——从操作系统层面排查数据库问题
我的前数据库时代
2000年代初,我用VC和PowerBuilder写政务系统。数据库就是Oracle,我的认知水平大概是这样的:
SELECT*FROMkc22WHEREsfzh='110101199001011234';INSERTINTOkc22(xm,sfzh)VALUES('张三','110101199001011234');UPDATEkc22SETxm='李四'WHEREsfzh='110101199001011234';DELETEFROMkc22WHEREsfzh='110101199001011234';增删改查,会写。复杂一点的多表联查,用PowerBuilder的DataWindow画一下,SQL自动生成。存储过程偶尔写,游标偶尔用。DDL就是CREATE TABLE,建表时照着需求文档抄字段。
我觉得我懂数据库了。
第一次被打脸
社保系统上线跑了半年,某天用户打电话来:查询一个人要等30秒。
我第一反应:数据量大了。查了一下,kc22表30万行。30万行很多吗?不多。但查询就是慢。
我当时的SQL长这样:
SELECT*FROMkc22WHERExmLIKE'%张%';不知道索引是什么,不知道LIKE '%张%'会导致全表扫描,不知道执行计划是什么东西。甚至不知道有"执行计划"这个概念。
DBA?项目里没有DBA。我是开发,测试是我,运维也是我,出事了还是我。
DML与DDL:开发者的两把刀
回头看,那个阶段我对数据库的理解,就停留在DML和DDL两个层面。
DML(Data Manipulation Language)
数据操作语言——增删改查:
-- 增INSERTINTOkc22(xm,sfzh,xb)VALUES('张三','110101199001011234','1');-- 删DELETEFROMkc22WHEREsfzh='110101199001011234';-- 改UPDATEkc22SETxm='李四'WHEREsfzh='110101199001011234';-- 查SELECT*FROMkc22WHERExb='1'ORDERBYxm;80%的开发者对数据库的理解就到这。能写SQL,能跑出结果,任务完成。
再进一步,会写多表关联:
SELECTa.xm,a.sfzh,b.mcASxbmcFROMkc22 aLEFTJOINdm_xb bONa.xb=b.dmWHEREa.xmLIKE'张%';再进一步,会写子查询、聚合:
SELECTxb,COUNT(*)AScntFROMkc22GROUPBYxbHAVINGCOUNT(*)>1000;到这里,大部分开发的SQL能力就封顶了。
DDL(Data Definition Language)
数据定义语言——建表、改结构:
CREATETABLEkc22(id NUMBERPRIMARYKEY,xm VARCHAR2(50),sfzh VARCHAR2(18),xb VARCHAR2(1));ALTERTABLEkc22ADD(lxdh VARCHAR2(20));DROPTABLEkc22;建表照着需求文档写,字段类型凭感觉选。NUMBER、VARCHAR2、DATE,三件套走天下。
不知道什么叫范式,不知道什么叫反范式。主键知道要加,外键有时加有时不加。索引?建表的时候Oracle不是自动有主键索引吗?够了吧。
缺的那一课:执行计划
让我慢30秒的那个查询,如果当时懂执行计划,一眼就能看出问题:
EXPLAINPLANFORSELECT*FROMkc22WHERExmLIKE'%张%';SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY);结果会告诉你:
| Id | Operation | Name | Rows | Cost | |----|-------------------|------|-------|------| | 0 | SELECT STATEMENT | | 30000 | 200 | | 1 | TABLE ACCESS FULL| KC22 | 30000 | 200 |TABLE ACCESS FULL——全表扫描。30万行,一行一行扫。LIKE '%张%'前面的通配符导致索引无法使用。
如果改成:
SELECT*FROMkc22WHERExmLIKE'张%';加了索引之后:
| Id | Operation | Name | Rows | Cost | |----|----------------------------|---------|------|------| | 0 | SELECT STATEMENT | | 500 | 5 | | 1 | TABLE ACCESS BY INDEX ROWID| KC22 | 500 | 5 | | 2 | INDEX RANGE SCAN | IDX_XM | 500 | 2 |走索引了。Cost从200降到5。
这就是执行计划——数据库告诉你,它打算怎么执行你的SQL。
但在那个阶段,我不知道这件事。查询慢了,我的应对方式是:重启一下数据库试试。
那个阶段的水平总结
| 我知道的 | 我不知道的 |
|---|---|
| SELECT/INSERT/UPDATE/DELETE | 执行计划是什么 |
| CREATE TABLE/ALTER TABLE | 索引怎么加、什么时候加 |
| WHERE条件怎么写 | 全表扫描、索引扫描的区别 |
| 简单的多表JOIN | SQL执行的先后顺序 |
| Oracle是个数据库 | Oracle内部在干什么 |
就是一个纯粹的SQL消费者。能用,但不理解。
为什么开发者需要懂一点DBA
小团队,没有专职DBA。
数据库出了问题——查询慢了、锁表了、表空间满了、甚至数据库起不来了——找谁?找开发。
你不会,用户就等着。领导就催着。出了事故,责任是你的。
所以不是因为我想学DBA,是因为不学就扛不住。
大厂的开发者看到这个系列可能会觉得:这些不是DBA的事吗?是的,在大厂是。但在小团队里,没有DBA,只有你。
下一篇,讲我是怎么被执行计划教做人的——从全表扫描到索引优化,从事后补救到建表时就考虑查询性能。
标签:#DBA #Oracle #执行计划 #DML #DDL #政务信息化 #开发转DBA
