Oracle 是第一个商用的关系型数据库,1979 年就以 SQL 为接口。 它四十多年只做了一件事: 让「数据放在哪」和「数据怎么用」分开。 版本号那三个后缀(i/g/c)记的正是它每次换赛道的时刻。
这是全书第一篇,也是唯一一篇不用敲命令的。 但它定下了后面十八章的坐标:你手上这套东西,是怎么长成现在这样的。 读完这篇只要记住一件事:Oracle 的版本号不是流水号,是一份路线图。 i 是互联网、g 是网格、c 是云,每一次换字母,都对应着一次架构上的大改。
一、从一篇论文到一家公司
关系型数据库的起点不是 Oracle,是一篇论文。 1970 年,IBM 的 E. F. Codd 发表《A Relational Model of Data for Large Shared Data Banks》, 提出用二维表来组织数据,用集合运算来查数据。 这篇论文当时没多少人当真——IBM 自己手上正卖着层次模型的库, 换赛道等于自己打自己。反倒是三个读论文的人动了手: 1977 年成立 SDL(Software Development Laboratories),1979 年拿出第一个产品, 取名 Oracle 2。 注意它一出手就叫 2.0,没有 1.0——官方的说法是「第一个版本不够格叫产品」, 也有人说是不想让客户觉得这是初版。不管哪种, 这版抢到了一个关键位置:第一个商用 SQL 关系库。 1982 年公司改名 Oracle,此后名字就固定下来了。这一段没有一行 SQL,但解释了一件事: 为什么 SQL 成了所有数据库的普通话——因为最早把「表 + 集合运算」做成商品的那家,赢了标准。
二、版本号怎么读:那三个字母
前七个版本(2~7)是纯数字,按功能一代代加。 从 8i 开始,Oracle 在数字后面加了个字母,这个字母比数字重要:
| 后缀 | 含义 | 从哪版起 | 那次改了什么 |
|---|---|---|---|
i |
internet | 8i(1999) | 库能直接跑 Java、能存网页与文件(iFS),把数据库塞进了 Web 时代 |
g |
grid | 10g(2003) | 网格计算:多台机器当一个用,ASM 管盘、AWR 自动收集性能数据 |
c |
cloud | 12c(2013) | 多租户:一个库实例里装多个可插拔库(PDB),为云上按租户隔离铺路 |
这三个字母是一条线索: i 解决「能不能上网」,g 解决「能不能横向扩」,c 解决「能不能多租户共用一个实例」。 每一步都在回答同一个问题:一台机器扛不住了怎么办。 12c 之后 Oracle 不再加字母,改成年份命名:18c、19c、21c、23c,一年(或两年)一版。 版本号从此就是一个日期,不再是功能编号。
三、19c 是个什么位置
19c 是 12.2 的长期支持版(Long Term Support)。Oracle 的版本分两类: 创新版(Innovation Release,功能新、支持期短)和长期支持版(稳定、支持期长)。 企业生产环境只上长期支持版。 这解释了为什么教材选 19c: 它出版的时候,19c 正是「企业里该用的那一版」。往前 11g 还有大量存量系统在跑,往后 21c、 23c 是新版。你以后遇到的库,大概率是这三个里挑一个。 别把版本号当成能力上限。11g 没有多租户, 但分区、RMAN、闪回它全都有——本课后半本讲的那些运维本事,在 11g 上就够用了。 版本决定的是「有没有这个功能」,不是「会不会用」。
四、这本书讲的是哪一块
Oracle 这家公司的产品线很长:数据库、中间件(WebLogic)、应用(ERP/CRM)、云。 这本书只讲一件事:数据库本身。 而且它讲的是单机版数据库,不是 RAC 集群、不是 Exadata 一体机。这不是缩水,是顺序问题: 单机都没搞明白,集群只是把同一个错误放大几倍。 全书 19 章可以切成四段看:先是「库是什么」(1~6 章),再是「库怎么管」(7~12 章), 然后是「库出问题怎么办」(13~18 章),最后用一套 Java 系统收口(19 章)。 这个顺序就是 DBA 的成长顺序,不是知识点的字母序。
五、动手 Demo:把版本年表建成一张表,用 SQL 读它
这一节本来没什么可跑的。
但年份表最适合拿 SQL 来读——算相邻两版的间隔、找最长的空档,节奏一眼就出来了。
顺带把教材的第一条 SQL 也跑一遍:select * from v$version 在 SQLite 上会报错,
这条报错本身就是知识点。
import sqlite3
c = sqlite3.connect(":memory:")
c.execute("CREATE TABLE ora_version (ver TEXT PRIMARY KEY, yr INTEGER NOT NULL)")
c.executemany("INSERT INTO ora_version VALUES (?,?)",
[('2', 1979), ('3', 1983), ('7', 1992), ('8', 1997),
('8i', 1999), ('9i', 2001), ('10g', 2003), ('11g', 2007),
('12c', 2013), ('18c', 2018), ('19c', 2019)])
c.commit()
# 相邻两版隔了几年:窗口函数 lag 取上一行
c.execute("select ver, yr, yr - lag(yr) over (order by yr) as gap "
"from ora_version order by yr").fetchall()
# 空档最大的前三名
c.execute("select ver, yr, gap from (select ver, yr, "
"yr - lag(yr) over (order by yr) as gap from ora_version) "
"where gap is not null order by gap desc limit 3").fetchall()
# 教材第一条 SQL,在 SQLite 上必报错:没有这张视图
c.execute("select * from v$version").fetchall()
实跑输出:
--------------------------------------------------------------------
第一课:Oracle 的发展史——版本号里的三个字母
--------------------------------------------------------------------
**这一节本来没什么可跑的**,全是年份和版本名。
**但年份表最适合拿 SQL 来读**——**算相邻两版的间隔、算跨度、找最长的空档,一眼就看出节奏变了。**
SQL> CREATE TABLE ora_version (ver TEXT PRIMARY KEY, yr INTEGER NOT NULL)
**灌进 14 行**(年份取自公开年表,不是教材原文;教材的叙述以书为准)。
SQL> select count(*) as n, min(yr) as first_yr, max(yr) as last_yr from ora_version
N FIRST_YR LAST_YR
-------------------
14 1979 2019
已选择 1 行
相邻两版隔了几年
--------------------------------------------------------------------
SQL> select ver, yr, yr - lag(yr) over (order by yr) as gap from ora_version order by yr
VER YR GAP
-------------
2 1979 NULL
3 1983 4
4 1984 1
5 1985 1
6 1988 3
7 1992 4
8 1997 5
8i 1999 2
9i 2001 2
10g 2003 2
11g 2007 4
12c 2013 6
18c 2018 5
19c 2019 1
已选择 14 行
**间隔一点都不规律:最短 1 年、最长 6 年。**
**真正变了的是命名规则**——
**2013 年之后版本号直接跟年份走(18c、19c、21c),所以 18c 到 19c 只隔 1 年。**
最长的空档在哪
--------------------------------------------------------------------
SQL> select ver, yr, gap from (select ver, yr, yr - lag(yr) over (order by yr) as gap from ora_version) where gap is not null order by gap desc limit 3
VER YR GAP
------------
12c 2013 6
8 1997 5
18c 2018 5
已选择 3 行
**最长的一段是 6 年:11g 到 12c(2007 到 2013)。**
**后面两个 5 年的也不短:7→8(1992→1997)、12c→18c(2013→2018)。**
**长间隔几乎都出现在大改版之前**——
**8i 之前、12c 之前,都在憋一个能改写定位的东西(互联网、云)。**
**而 12c 之后一年一版**,间隔缩到 1~5 年,因为版本号直接跟年份对齐了。
**7 那一版是个分水岭:**
**存储过程、触发器、角色都是那时候补齐的**——**本课后半本讲的很多东西,源头在那里。**
版本号后缀的三个字母
--------------------------------------------------------------------
**8i 的 i 是 internet,9i 沿用;10g 的 g 是 grid;12c 的 c 是 cloud。**
**19c 之后不再加字母**,改成年份命名(18c、19c、21c、23c)。
SQL> select ch, word, era from suffix order by seq
CH WORD ERA
--------------------
i internet 8i~9i
g grid 10g~11g
c cloud 12c 起
已选择 3 行
教材里第一条 SQL:查版本
--------------------------------------------------------------------
[Oracle 原码 · 本沙箱不执行]
| SELECT * FROM v$version;
v$ 开头是动态性能视图,记录当前实例的版本信息。
本沙箱执行同一条:**报错 `no such table: v$version`**
**不是语法错,是没有这张视图**——
**`v$version` 是 Oracle 实例起来之后才有的动态视图,SQLite 里没有对应物。**
**这条报错本身就是知识点:**
**`v$` 开头的视图不属于任何用户,它们是实例的内存结构映射出来的。** **实例没起来,查它必报错。**
**顺便验一下这台机器上有没有 Oracle 的客户端:**
`shutil.which('sqlplus')` → **None**
**None 就是没有。**
**所以本课一条 Oracle 命令都执行不了,全部改用 SQLite 等价演示。**
lag(yr) over (order by yr) 是窗口函数,取「按年份排好之后的上一行」。
没有它就得自连接两次,写起来长得多。窗口函数在 4.3 会正式讲。
14 行数据,间隔从 1 年到 6 年不等,看不出「越来越快」。真正的规律在命名规则上:
2013 年之后版本号跟年份对齐,所以 18c 到 19c 只隔 1 年。
v$version 报的是 no such table,不是语法错。
v$ 开头的是动态性能视图,它们不在任何用户模式下,是实例内存结构的映射。
实例没起来,查它必报错——这也解释了 1.5 节为什么要分三步开机。
这台机器上 shutil.which('sqlplus') 给 None。
没有客户端、没有服务端、没有监听,所以本课一条 Oracle 命令都执行不了。
后面的 Demo 全部是 SQLite 等价演示,Oracle 原码逐条标出来。
30 秒实验
- 把年表里的 8i 删掉,再跑一次「相邻间隔」, 看 8 后面那行的 gap 变成多少——这就是窗口函数跟自连接的区别:它不需要你写出「上一行是谁」。
- 加一行
('23c', 2023),再算一次平均间隔。 注意平均间隔会被早期的大间隔拖高,中位数才反映「现在的节奏」。 - 把
v$version换成sqlite_master再查一次,看看能不能查到ora_version这张表。 一个是实例视图、一个是库内字典,位置完全不同。
常见误区
- 把 19c 当成「第 19 版」。 版本号是产品代号,不是序号。 12c 之后按年份命名,19c 是 2019 年的版本,不是第 19 代。
- 以为装了新版就什么都能用。 新版的很多功能要额外买选项(比如分区、高级压缩、诊断包), 装了不等于授权了。 这句在 11 章讲分区时还会提。
- 把
i/g/c当成营销词。 它们各自对应一次架构改动: Java 进库、网格化、多租户。 记不住字母就记这三件事。
自测三问(点开对答案)
1. Oracle 2 为什么不叫 1.0? —— 官方说法是第一个版本不够格叫产品。 **记住这个细节的意义在于:**它的定位从第一天就是「商用产品」, 不是实验品——这决定了它后面所有设计都偏保守。 2. 19c 的 c 是什么意思?为什么企业只用它这一类版本? —— c 是 cloud,多租户。 **19c 属于长期支持版(LTS)**,创新版功能新但支持期短,生产环境只上 LTS。 3. `select * from v$version` 为什么在 SQLite 上一定失败? —— 因为 `v$` 开头的是**动态性能视图**,由实例的内存结构映射出来,不在任何用户模式下; SQLite 没有「实例」这一层,自然没有这些视图。下一篇讲关系型数据库的基本理论:二维表、键、E-R 模型、三范式。 那一篇里会把「同一件事写三遍有多难受」当场跑出来。
- ☐ (本篇完,下一篇 1.2 关系型数据库的基本理论)
相关笔记
-
- 🦏 MySQL即学即用/00-索引
-
- 🐬 MySQL必知必会/00-索引
-
- 🗄️ 数据库基础/00-索引
- 🏺 Oracle从入门到精通 · 索引