🦏 第1章 数据库简介
📄 一句话概括

注释只有两种写法能进脚本:--(两个减号加空格)和 /* */。 # 是 MySQL 客户端认、SQLite 不认,脚本里别用。 Demo 真撞了三次墙:# 报 unrecognized token: "#"、 一次送两句报 You can only execute one statement at a time、 SELECT 与 select 给同一个数 2。

📝 本章和前面几章的关系

前四篇讲的是「装和连」,这一篇讲「怎么写」——注释、分号、大小写、示例库,四件小事, 但每一件都能让人卡半天。 它是全书的书写公约,后面 18 章不再重复这些规矩。

一、注释:三种写法,两种通用

-- 是标准 SQL 注释,注意 MySQL 要求两个减号后面跟一个空格, --注释 在 MySQL 里不合法(SQLite 反而认)。写成 -- 注释 两边都过。 # 是 MySQL 特有的行注释,命令行里常用。 但它不是标准 SQL,SQLite、PostgreSQL 都不认——脚本里用它,换库就报错。 /* */ 是块注释,可以跨行, 两边都认,还能用来临时屏蔽一整段。 MySQL 还有一种 /*! */ 是「版本条件执行」,那是给兼容性用的,本课不讲。

二、分号:语句的句号

一条语句以分号结尾, 这是客户端的约定——它靠分号判断「这句发完了」。 少一个分号,客户端就一直等你继续敲。 客户端可以一次发一批(编辑器里全选运行),但 Python 的驱动一次只收一条: execute 遇到两句会报 You can only execute one statement at a time, 要整批发得用 executescript。 这条差异很实用:以后写脚本报这个错,不用怀疑 SQL 写错了,是发送方式不对。

三、大小写:关键字随便,值不行

SQL 关键字不分大小写:SELECT、select、Select 一个意思。 本书统一大写写关键字、小写写表名字段名,纯粹为了好读。 但有两处真的在乎大小写:一是字符串里的值('张伟' 和 '张伟 ' 是两个值); 二是 Linux 上的表名(lower_case_table_names=0 时 Students 和 students 是两张表)。 Windows 上默认不区分,换到 Linux 就翻车。 稳妥做法:表名、字段名一律小写加下划线(order_detail),永远不用大小写来区分对象。

四、本书的示例库:六张表,一条线到底

本课自造了一套六张表的库:classes(班级)、students(学生)、scores(成绩)、 goods(商品)、orders(订单)、order_detail(订单明细)。 为什么自造:教材的案例库不在手上, 但结构照它的思路来——两三条线(学生线、商品线)互相能连上, 这样第 10 章讲多表、第 19 章做案例时都有真数据可算。 数据量刻意做小:12 个学生、36 条成绩、10 件商品、14 张订单、17 条明细。 小到能手算验证,大到能看出规律——每个数都能在正文里被验算一遍。

五、小结

教材小结:SQL 语句以分号结尾,可以用 --、#、/* */ 写注释,关键字不分大小写; 书中示例按章节顺序逐步建立。 本课补三条:一是脚本里只用 -- 和 /* */,# 留给 MySQL 命令行; 二是 Python 驱动一次只送一条语句,整批要用 executescript; 三是表名字段名一律小写,别拿大小写当区分。

六、动手 Demo:四种写法,三次撞墙

Demo 六段:试三种注释、试一次送两句、试关键字大小写,最后看示例库长什么样。 中间三处报错都是真撞出来的,不是我写给你看的。

import sqlite3
c = sqlite3.connect(":memory:")

c.execute("CREATE TABLE t1 (id INTEGER)   -- 行注释")
c.execute("CREATE TABLE t2 (id INTEGER)   # MySQL 认,SQLite 不认")
c.execute("CREATE TABLE t3 ( /* 块注释 */ id INTEGER )")

# 一次只送一条语句
c.execute("INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2)")
c.executescript("INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2)")

# 关键字不分大小写
c.execute("SELECT COUNT(*) FROM t1")
c.execute("select count(*) from t1")

实跑输出:

--------------------------------------------------------------------
第五课:这本教程的几条书写约定
--------------------------------------------------------------------

  注释有三种写法,SQLite 只认其中两种
  SQL> CREATE TABLE t1 (id INTEGER) -- 这是行注释,两个减号加空格
  完成
  SQL> CREATE TABLE t2 (id INTEGER)   # 这也是行注释
  报错:unrecognized token: "#"

  SQL> CREATE TABLE t3 ( /* 块注释 */ id INTEGER )
  完成
  **结论:写进脚本的注释只用** `-- ` **和** `/* */` **,`#` 留给 MySQL 命令行里临时敲。**

  一条语句以分号结尾;几条语句可以一起发
  SQL> INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2)
  报错:You can only execute one statement at a time.
  **这是 Python 驱动的一条规矩:一次只送一条。**图形工具的运行键不一样,
  它把编辑区里所有语句整批发出去。
  SQL> 换成整批发送(等价于图形工具按一次运行)
  完成
  SQL> SELECT * FROM t1
  id
  ---
  1
  2
  (2 行)

  关键字不分大小写,结果一模一样
  SELECT 大写给 2,select 小写也给 2
  **本书统一用大写写关键字、小写写表名字段名**,纯粹为了好读,引擎一点都不在乎。
  **但字符串里的值在乎**:`'张伟'` 和 `'张伟 '` 是两个值。

  本书的示例库:六张表,都是真表
  classes、goods、order_detail、orders、scores、students
  **一共 6 张:班级、学生、成绩、商品、订单、订单明细。**
  **书上用的是它自己的案例库,表名数据都不一样;本课按同样的思路自造了一套,好处是每一章都能接着上一章的数往下算。**

  最后一句:这套教程怎么用
  **一章一章顺着敲,别跳。** 前面的表后面还要用,跳过去就得重新造数据。
  **每一节的 Demo 都要自己跑一遍。** 看别人跑出来的数,和自己敲出来的数,掌握程度差得远。
  **报错不要紧,把报错读一遍。** 数据库的报错信息是全栈里最老实的一类,
  它基本都告诉你「哪个词不认识」。

第一段 -- 注释。 通过,这是标准写法。 第二段 # 注释。 报 unrecognized token: "#",这就是「换库就报错」的现场。 第三段块注释。 通过,跨行也行。 第四段一次送两句。 execute 报 You can only execute one statement at a time; 换 executescript 之后两条都进去了,表里两行。 第五段大小写。 大写小写都给 2,引擎确实不在乎。 第六段示例库。 六张表列出来——后面 18 章都在这六张表上折腾。

30 秒实验

  1. -- 和 -- 在 MySQL 里有区别吗?在本沙箱里呢?
  2. (先想再跑)把 executescript 换成 execute 送三条语句,报的是同一个错吗?
  3. 在 Linux 上建一张 Students 表,再 select * from students,能查到吗?

常见误区

  1. 注释写成 #。 MySQL 命令行里能用,SQLite/PostgreSQL 直接语法错,脚本不可移植。
  2. -- 后面不加空格。 标准 SQL 要求有空格,--注释 在 MySQL 里不算注释。
  3. 靠大小写区分表名。 Windows 上能跑,Linux 上找不到表,这类 bug 只在部署时爆。
自测三问(点开对答案) 1. 脚本里应该用哪两种注释? —— `-- `(两个减号加空格)和 `/* */`;`#` 只有 MySQL 客户端认,不可移植。 2. 为什么 `execute` 报「一次只能一条语句」? —— Python 的 sqlite3 驱动不允许一次执行多条;要整批发得用 executescript。 3. 哪两处真的区分大小写? —— 字符串里的值('张伟' 与 '张伟 ' 不同);Linux 上默认表名区分大小写。

工具装好了、规矩也定了,下一章正式进 SQL:语法、数据类型、注释,把「一句话怎么写」讲透。

相关笔记