一、Foreign Key
外键(Foreign Key) 是用来维护两个表之间关系的字段或字段组合。它引用了另一个表的主键(Primary Key),从而确保数据的一致性和完整性。
功能:
1. 确保数据引用的完整性:
• 外键中的值必须在被引用表(父表)中存在,或为空(NULL,视具体约束而定)。
2. 实现表之间的关系:
• 一对一(One-to-One):一个表的外键引用另一个表的主键。
• 一对多(One-to-Many):一个表的外键允许多个值引用另一个表的主键。
• 多对多(Many-to-Many):通过中间表建立关系,两个外键分别引用两个表的主键。
3. 级联操作(Cascade):
• 当父表数据更新或删除时,外键可以自动更新或删除。
创建外键语法:
1. 在 表创建时 定义外键:
CREATE TABLE ChildTable (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES ParentTable(id)
);
2. 在 表已存在时 添加外键:
ALTER TABLE ChildTable
ADD CONSTRAINT fk_parent
FOREIGN KEY (parent_id) REFERENCES ParentTable(id);
3. 添加带有 级联操作 的外键:
CREATE TABLE ChildTable (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES ParentTable(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
级联规则:
• ON DELETE CASCADE:
如果父表记录被删除,外键对应的子表记录也会被删除。
• ON DELETE SET NULL:
如果父表记录被删除,外键对应的子表字段将设置为 NULL(需要子表列支持 NULL)。
• ON DELETE NO ACTION 或 RESTRICT:
禁止删除父表记录,如果有子表引用。
• ON UPDATE CASCADE:
如果父表记录的主键被更新,外键对应的子表记录会同步更新。
实例:
父表:Authors
CREATE TABLE Authors (
id INT PRIMARY KEY,
name VARCHAR(100)
);
子表:Books
CREATE TABLE Books (
id INT PRIMARY KEY,
title VARCHAR(100),
author_id INT,
FOREIGN KEY (author_id) REFERENCES Authors(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
使用场景:
1. 插入数据:
INSERT INTO Authors (id, name) VALUES (1, 'Author A');
INSERT INTO Books (id, title, author_id) VALUES (101, 'Book 1', 1); -- 引用作者 1
2. 删除父表记录时的级联操作:
DELETE FROM Authors WHERE id = 1; -- 会删除 Books 中所有 author_id = 1 的记录
3. 更新父表主键时的级联操作:
UPDATE Authors SET id = 2 WHERE id = 1; -- Books 表中 author_id 也会更新为 2
查询与验证:
SELECT Books.title, Authors.name
FROM Books
JOIN Authors ON Books.author_id = Authors.id;
注意事项:
1. 外键列的数据类型必须与引用的主键列相同。
2. 如果外键列允许 NULL,可以不强制关联父表。
二、ALL
在 SQL 中,ALL 是一个关键字,通常与 子查询 或 比较操作符 一起使用。它用于指定一个条件或操作需要与子查询结果中的 所有值 进行比较。
常见用法场景
1. 与比较操作符(>、<、>=、<= 等)配合使用:
• 语法:
column_name operator ALL (subquery)
• 意义:只有当 column_name 满足与子查询返回的 所有值 的条件时,记录才会被选中。
• 示例:
SELECT *
FROM employees
WHERE salary > ALL (
SELECT salary
FROM employees
WHERE department = 'HR'
);
解释:
• 返回薪资高于 HR 部门所有员工薪资 的员工。
• 如果 ALL 后的子查询返回值为 [3000, 4000, 5000],salary > ALL 等价于 salary > 5000。
2. 与 SELECT 配合使用:
• 语法:
SELECT ALL column_name
FROM table_name;
• 意义:显式选择表中的 所有行,但实际中效果与直接 SELECT 无差别,因为默认情况下 SQL 会返回所有行。
• 示例:
SELECT ALL name
FROM students;
结果:
• 返回表中所有学生的 name,与 SELECT name FROM students; 等价。
3. 与 NOT 和子查询配合使用:
• 语法:
column_name NOT operator ALL (subquery)
• 意义:表示 column_name 不满足与子查询返回的 所有值 的条件。
• 示例:
SELECT *
FROM products
WHERE price NOT < ALL (
SELECT price
FROM products
WHERE category = 'Electronics'
);
解释:
• 返回价格不小于 电子产品类别中所有价格 的产品。
• 如果 ALL 子查询返回 [100, 200, 300],price NOT < ALL 等价于 price >= 100。
4. 与 UNION 操作配合(仅限 ALL 关键字):
• 语法:
SELECT column_name
FROM table1
UNION ALL
SELECT column_name
FROM table2;
• 意义:合并两个查询的结果集,并保留重复值。
• 示例:
SELECT name
FROM students
UNION ALL
SELECT name
FROM teachers;
解释:
• 返回学生和教师的名字(包括重复名字)。
• 如果不加 ALL,则默认使用 UNION 去重。
ALL 的作用总结:
• 比较操作符 + 子查询:
• 强调 对子查询返回的所有值 执行比较条件。
• UNION ALL:
• 合并两个结果集,并保留所有重复值。
• SELECT ALL:
• 选择表中所有行(实际效果等价于默认 SELECT)。
例子:ALL 与 ANY 的区别
使用 ALL
SELECT *
FROM employees
WHERE salary > ALL (
SELECT salary
FROM employees
WHERE department = 'IT'
);
• 返回薪资高于 IT 部门 所有员工薪资 的员工。
使用 ANY
SELECT *
FROM employees
WHERE salary > ANY (
SELECT salary
FROM employees
WHERE department = 'IT'
);
• 返回薪资高于 IT 部门 任意一个员工薪资 的员工。
三、DISTINCT
在 SQL 中,DISTINCT 是一个关键字,用于从查询结果中去除重复的行,仅返回 唯一的记录。
用法与语法
基本语法
SELECT DISTINCT column1, column2, ...
FROM table_name;
• DISTINCT 关键字紧跟在 SELECT 后面,作用于指定的列。
• 如果多个列组合使用 DISTINCT,那么返回的每一行数据必须在所有这些列上都是唯一的。
示例用法
1. 去除单列的重复值
SELECT DISTINCT department
FROM employees;
• 作用:返回 employees 表中所有唯一的部门名。
2. 去除多列的重复值
SELECT DISTINCT department, job_title
FROM employees;
• 作用:返回每个唯一的部门和职位组合。
• 注意:DISTINCT 是基于 所有指定列的组合 判断唯一性,而不是单独对每一列去重。
3. 结合 COUNT 使用
SELECT COUNT(DISTINCT department)
FROM employees;
• 作用:统计 employees 表中唯一部门的数量。
结果:
如果部门有 IT, HR, Sales,结果会是 3。
4. 与其他函数结合
SELECT DISTINCT department, AVG(salary)
FROM employees
GROUP BY department;
• 作用:返回每个唯一部门及其平均薪资。
四、GROUP BY
GROUP BY 是 SQL 中用于将查询结果按指定列分组的语句。分组后,可以对每组数据进行聚合操作,例如计算总和、平均值、计数等。
语法
SELECT column1, column2, AGGREGATE_FUNCTION(column3)
FROM table_name
GROUP BY column1, column2;
• column1, column2:分组依据的列,查询结果按这些列的值分组。
• AGGREGATE_FUNCTION(column3):对分组后的每组数据应用的聚合函数,例如 SUM、COUNT、AVG、MAX、MIN。
示例 1:按部门统计员工数量
假设有一个 employees 表,包含以下数据:
employee_id name department salary
1 Alice IT 5000
2 Bob IT 6000
3 Charlie HR 7000
4 David HR 8000
5 Eve Sales 9000
查询每个部门的员工数量:
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department;
结果:
department employee_count
IT 2
HR 2
Sales 1
解析:
• 按 department 分组。
• 每组计算员工数量(COUNT(*))。
示例 2:按部门计算薪资总和
SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department;
结果:
department total_salary
IT 11000
HR 15000
Sales 9000
解析:
• 按 department 分组。
• 每组计算薪资总和(SUM(salary))。
示例 3:按部门统计最高薪资
SELECT department, MAX(salary) AS max_salary
FROM employees
GROUP BY department;
结果:
department max_salary
IT 6000
HR 8000
Sales 9000
解析:
• 按 department 分组。
• 每组计算最高薪资(MAX(salary))。
示例 4:按部门和职位分组
如果表中有职位列,查询每个部门和职位的员工数量:
employee_id name department job_title salary
1 Alice IT Developer 5000
2 Bob IT Developer 6000
3 Charlie HR Manager 7000
4 David HR Recruiter 8000
5 Eve Sales Sales Manager 9000
查询每个部门和职位的员工数量:
SELECT department, job_title, COUNT(*) AS employee_count
FROM employees
GROUP BY department, job_title;
结果:
department job_title employee_count
IT Developer 2
HR Manager 1
HR Recruiter 1
Sales Sales Manager 1
解析:
• 按 department 和 job_title 同时分组。
• 每组计算员工数量。
示例 5:结合 HAVING 过滤分组结果
HAVING 用于对分组后的数据进行过滤。
查询员工数量大于 1 的部门:
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 1;
结果:
department employee_count
IT 2
HR 2
解析:
• 使用 GROUP BY 按部门分组。
• 过滤掉员工数量小于等于 1 的部门(HAVING COUNT(*) > 1)。
GROUP BY 与 ORDER BY 结合
按部门分组,统计员工数量,并按员工数量降序排列:
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
ORDER BY employee_count DESC;
结果:
department employee_count
IT 2
HR 2
Sales 1
注意事项
1. 必须在 GROUP BY 后分组:
• 如果没有分组列,则会报错。
2. GROUP BY 中的列必须出现在 SELECT 中,除非是聚合函数:
• 例如:
SELECT department, MAX(salary)
FROM employees
GROUP BY department; -- 正确
五、<> 符号
在 SQL 中,<> 是一种 不等于(NOT EQUAL TO) 的比较运算符,用于判断两个值是否不相等。
• 有些数据库更倾向于使用 <>(ANSI SQL 标准)。
• 有些数据库(如 MySQL)同时支持 <> 和 !=,使用任何一种都可以。
六、单引号 (')
是否需要在字段名称(列名)周围加反引号(``)取决于 数据库的类型 和 字段名称的命名规则。
七、加反引号(``)
1.1 字段名称为关键字或保留字时
• 如果字段名称与数据库的关键字或保留字冲突(如 SELECT、TABLE、GROUP 等),需要用反引号将字段名包裹起来。
• 示例(MySQL):
CREATE TABLE orders (
`order` INT, -- "order" 是保留字,因此需要加反引号
`date` DATE
);
1.2 字段名称包含特殊字符或空格时
• 字段名称中含有特殊字符(如 -、@)或空格时,需要用反引号包裹。
• 示例:
CREATE TABLE employees (
`employee-id` INT, -- 包含特殊字符 "-"
`first name` VARCHAR(50) -- 包含空格
);
1.3 确保区分大小写(MySQL 默认)
• 在 MySQL 中,字段名称的大小写敏感性与操作系统有关(Windows 不敏感,Linux 敏感)。如果需要强制区分大小写,可以用反引号包裹。
• 示例:
SELECT `FirstName` FROM employees; -- 区分大小写
在 SQL 中,USING 和 ON 是两种用于指定连接条件的方式,常见于连接(JOIN)操作中。二者功能类似,但有一些适用场景的差异。
八、USING
1. 语法简洁:
• 如果两个表中有同名的列作为连接条件,可以直接使用 USING(column_name),简化书写。
• 示例:
SELECT *
FROM books
INNER JOIN authors_of_books USING (book_id);
• 含义:将 books 和 authors_of_books 两个表中 同名列 book_id 的值相等的行连接在一起。
2. 自动消除重复列:
• USING 会自动去掉查询结果中重复的同名列,只保留一列。
• 示例:
SELECT *
FROM books
INNER JOIN authors_of_books USING (book_id);
如果两个表都包含 book_id 列,结果中只会显示一个 book_id。
九、ON
1. 灵活性更强:
• ON 允许指定任意连接条件,包括不同列的比较、复杂表达式等。
• 示例:
SELECT *
FROM books
INNER JOIN authors_of_books ON books.book_id = authors_of_books.book_id;
• 含义:将 books 表的 book_id 与 authors_of_books 表的 book_id 的值相等的行连接在一起。
2. 允许使用不同名称的列:
• 如果两个表中用于连接的列名称不同,必须使用 ON。
• 示例:
SELECT *
FROM books
INNER JOIN orders ON books.id = orders.book_id;
3. 不会消除重复列:
• 使用 ON 时,查询结果会保留所有列,包括重复的列。
• 示例:
SELECT *
FROM books
INNER JOIN authors_of_books ON books.book_id = authors_of_books.book_id;
结果中会同时包含 books.book_id 和 authors_of_books.book_id 两列。
十、三值逻辑表达式
我们用 SQL 中的 NULL 替代题目中的 Unknown,并基于三值逻辑规则得出结果。
1. True AND (15 > 1)
• 表达式:True AND True
• 结果:True
2. Unknown + 12
• 表达式:NULL + 12
• 规则:任何值与 NULL 运算结果均为 NULL。
• 结果:NULL
3. (True OR Unknown) AND (3 IN (2, 3, 4, 5))
• 拆解:
• (True OR Unknown) = True OR NULL → True
• (3 IN (2, 3, 4, 5)) = True
• True AND True → True
• 结果:True
4. 'Bent' LIKE '%t' OR Unknown <> 5
• 拆解:
• 'Bent' LIKE '%t' → True
• Unknown <> 5 → NULL <> 5 → NULL
• True OR NULL → True
• 结果:True
5. True + False + 25
• 表达式:在 SQL 中布尔值可能会转为数值:
• True → 1
• False → 0
• 计算:1 + 0 + 25 → 26
• 结果:26
6. (Unknown <> Unknown) OR (Unknown = Unknown)
• 拆解:
• (Unknown <> Unknown) → (NULL <> NULL) → NULL
• (Unknown = Unknown) → (NULL = NULL) → NULL
• NULL OR NULL → NULL
• 结果:NULL
7. (Unknown OR 1) + 12
• 拆解:
• Unknown OR 1 → NULL OR 1 → 1(1 表示 True)
• 1 + 12 → 13
• 结果:13
8. NOT (Unknown AND (12 / 3 - 4))
• 拆解:
• (12 / 3 - 4) → 0
• Unknown AND 0 → NULL AND 0 → False(NULL 与 False 逻辑运算为 False)
• NOT False → True
• 结果:True
9. (NOT Unknown) AND (NOT 12)
• 拆解:
• NOT Unknown → NOT NULL → NULL
• NOT 12 → False(非零值取反为 False)
• NULL AND False → False
• 结果:False
可以使用 SQL 查询来验证,例如:
SELECT TRUE AND (15 > 1);
SELECT NULL + 12;
SELECT (TRUE OR NULL) AND (3 IN (2, 3, 4, 5));
是的,在 SQL 中,像 TRUE AND (15 > 1) 这样的表达式是完全可以放在 SELECT 语句里的。这种用法可以用于测试逻辑表达式,尤其是在调试或学习时有帮助。
解释
• 逻辑表达式:
• SQL 支持布尔逻辑,例如 AND、OR、NOT,这些可以用于表达式中。
• 15 > 1 是一个布尔表达式,返回 TRUE。
• TRUE AND TRUE 最终返回 TRUE。
• SELECT 中的用法:
• SELECT 不仅可以用于检索表中的字段,还可以直接用于计算表达式。
• 例子:
SELECT TRUE AND (15 > 1) AS Result;
输出:
Result
------
TRUE
常见应用场景
1. 验证表达式的正确性:
• 在调试复杂查询时,使用类似语句检查逻辑是否正确。
SELECT 15 > 1 AS GreaterCheck;
2. 结合字段使用:
• 在查询结果中添加逻辑条件:
SELECT name, salary, salary > 5000 AS IsHighSalary
FROM Employee;
输出:
Name Salary IsHighSalary
---- ------ ------------
John 6000 TRUE
Mary 4000 FALSE
1. 直接返回逻辑值:
• 并非所有数据库都会返回布尔值(TRUE 或 FALSE)。某些数据库(如 MySQL)会将布尔值转换为整数形式:
• TRUE → 1
• FALSE → 0
• 例如:
SELECT TRUE AND FALSE; -- MySQL 会返回 0
SQL 中的 SELECT 语句不仅可以用于查询字段,也可以直接执行表达式。逻辑表达式(如 TRUE AND (15 > 1))在 SELECT 中是合法的,且非常有用。
十一、关系模型(Relational Model)
是数据库的核心理论之一,由 E.F. Codd 于 1970 年提出。它将数据表示为表格的形式(即关系),并提供了一种基于数学理论的系统化数据存储和操作方式。
关系模型的核心组成
1. 基本概念
• 关系(Relation):
• 表格形式的结构,用来存储数据。
• 每一行表示一个实体(记录或元组,Tuple)。
• 每一列表示一个属性(Attribute)。
• 属性(Attribute):
• 表中字段的名称。
• 每个属性有固定的数据类型(如 INT、VARCHAR)。
• 元组(Tuple):
• 表中的一行,表示一个具体的数据实例。
• 域(Domain):
• 每个属性的数据取值范围。
• 关系模式(Schema):
• 描述关系的结构,包括关系名、属性集、主键等信息。
关系模型的实际应用
• SQL数据库:
• 关系模型是许多数据库(如 MySQL、PostgreSQL、Oracle)的理论基础。
十二、Question
1. postCode 字段SW1 4EH,其长度为 7(包括空格)。
2. 如果将 street 设置为 VARCHAR(200),其实际存储时仍然只占用实际字符长度的内存空间(加上额外的长度标记)。
十三、Question 2
1. DBeaver
• 这是一个数据库客户端工具,用于连接和管理数据库,但它本身不是 DBMS。
• 不是 DBMS。
2. MariaDB
• 这是一个开源的关系型数据库管理系统(RDBMS),MySQL 的一个分支。
• 是 DBMS。
3. PhpMyAdmin
• 这是一个基于 Web 的 MySQL 管理工具,主要用于管理和操作 MySQL 数据库,但它本身不是 DBMS。
• 不是 DBMS。
4. MySQL
• 这是一个流行的开源关系型数据库管理系统(RDBMS)。
• 是 DBMS。
5. Microsoft Access
• 这是一个轻量级的关系型数据库管理系统,集成了图形界面和数据库引擎。
• 是 DBMS。
6. Counter-Strike
• 这是一个电子游戏,与数据库完全无关。
• 不是 DBMS。
十四、数据类型规范
1. DECIMAL(5,7)
❌ 错误。精度(5)必须大于或等于标度(7)。这个定义无效。
2. NUMERIC(7,6)
✅ 正确。精度(7)大于标度(6),这是有效的。
3. DATE
✅ 正确。DATE 是有效的数据类型。
4. DATE(5)
❌ 错误。DATE 不接受精度值。
5. CHAR
❌ 错误。CHAR 必须指定长度。
6. CHAR(1)
✅ 正确。这是一个有效的单字符定义。
7. VARCHAR
❌ 错误。VARCHAR 必须指定长度。
8. VARCHAR(250)
✅ 正确。这是一个有效的定义。
9. TINYINT
✅ 正确。TINYINT 是有效的数值数据类型。
10. STRING
❌ 错误。STRING 不是 MySQL 中的有效数据类型。
11. ZONE
❌ 错误。ZONE 不是 MySQL 中的有效数据类型。
12. UNSIGNED
❌ 错误。UNSIGNED 必须与数值类型一起使用,不能单独存在。
13. FLOAT
✅ 正确。FLOAT 是有效的数值数据类型。
十五、Question 3
Question 关于外键约束
示例 1:引用表和被引用表的列数量必须一致
CREATE TABLE Department (
DeptID INT PRIMARY KEY,
DeptName VARCHAR(50)
);
CREATE TABLE Employee (
EmpID INT PRIMARY KEY,
EmpName VARCHAR(50),
DeptID INT,
FOREIGN KEY (DeptID) REFERENCES Department(DeptID) -- 列数量一致
);
这里,Employee 表的 DeptID 列引用了 Department 表的 DeptID 列,列数量一致,所以没有错误。
示例 2:外键可以引用自身(自引用)
CREATE TABLE Employee (
EmpID INT PRIMARY KEY,
EmpName VARCHAR(50),
ManagerID INT,
FOREIGN KEY (ManagerID) REFERENCES Employee(EmpID) -- 自引用外键
);
这里,ManagerID 列是 Employee 表的一部分,它引用了自身表中的 EmpID 列,表示员工和经理的关系。
示例 3:允许外键列为空值
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
CustomerID INT,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) -- 外键列允许空值
);
在 Orders 表中,如果某个订单没有客户信息,可以将 CustomerID 列设置为 NULL。
关于外键约束
1. 引用表中外键涉及的属性数量必须与被引用表中属性的数量相同。
✅ 正确。外键的列数必须与引用的主键或唯一键的列数完全匹配,这是外键约束的基本规则。
2. 引用表中涉及外键的列必须是主键或唯一键。
❌ 错误。在被引用的表中,这些列必须是主键或唯一键,而不是引用表中的列。
3. 被引用表中涉及外键的属性可以是主键的一部分子集。
❌ 错误。外键必须与整个被引用的主键或唯一键匹配,而不能只是其中的子集。
4. 当现有数据违反该外键的参照完整性时,仍然可以应用外键。
❌ 错误。如果存在参照完整性冲突,无法添加外键约束。
5. 一个表可以有外键引用自身。
✅ 正确。这是允许的,用于建模层级关系,例如员工表中引用经理。
6. 一个表可以有多个外键。
✅ 正确。一个表可以引用多个其他表,甚至在不同外键下多次引用同一表。
7. 引用其他列的外键列可以包含空值。
✅ 正确。默认情况下,外键列可以包含空值,除非被显式限制。
十六、Question 4
示例:关于主键和唯一键
示例 1:一个表有多个唯一键
CREATE TABLE Products (
ProductID INT PRIMARY KEY,
ProductName VARCHAR(50) UNIQUE, -- 唯一键
SKU VARCHAR(20) UNIQUE -- 另一个唯一键
);
这里,ProductName 和 SKU 都是唯一键,而 ProductID 是主键。
示例 2:主键不能为 NULL,唯一键允许 NULL
CREATE TABLE Users (
UserID INT PRIMARY KEY,
Email VARCHAR(50) UNIQUE -- 唯一键允许空值
);
INSERT INTO Users (UserID, Email) VALUES (1, NULL); -- 允许
INSERT INTO Users (UserID, Email) VALUES (2, NULL); -- 允许(两个 NULL 视为不同)
主键 UserID 不允许为空值,但 Email 是唯一键,可以包含多个空值。
示例 3:主键定义中不能设置默认值为 NULL
CREATE TABLE Students (
StudentID INT PRIMARY KEY DEFAULT NULL, -- 错误:主键不能为 NULL
Name VARCHAR(50)
);
这段代码会导致错误,因为主键列不能有默认值为 NULL。
示例 4:主键是最小超键
CREATE TABLE Orders (
OrderID INT,
ProductID INT,
Quantity INT,
PRIMARY KEY (OrderID, ProductID) -- 联合主键
);
这里,(OrderID, ProductID) 是主键,也是最小超键。你不能只用 OrderID 或 ProductID 单独作为主键,因为它们不能唯一标识一行。
关于主键和唯一键
1. 一个表可以有多个唯一键。
✅ 正确。一个表可以有多个唯一约束,但只能有一个主键。
2. 当两个关系的主键相同时,才能应用UNION操作。
❌ 错误。UNION操作只需要列的数量和数据类型匹配,与主键无关。
3. 受主键约束的列可以包含空值。
❌ 错误。主键列不能包含空值。
4. 受唯一键约束的列可以包含空值。
✅ 正确。唯一约束允许空值,但每个空值被视为唯一的。
5. 列定义studentID INT PRIMARY KEY DEFAULT NULL不会导致错误。
❌ 错误。主键列不能有默认值为NULL。
6. 具有主键约束的列可以是超键。
✅ 正确。主键本质上是最小超键。
十七、Question 5
在 MySQL 中,要更改现有列的数据类型,以下两种语法是有效的:
1. ALTER TABLE … MODIFY COLUMN
ALTER TABLE table_name MODIFY COLUMN column_name new_data_type;
• 用法:用于更改列的数据类型,但列名保持不变。
• 示例:
ALTER TABLE Employees MODIFY COLUMN Salary DECIMAL(10, 2);
将 Salary 列的数据类型更改为 DECIMAL,并指定精度和范围。
2. ALTER TABLE … CHANGE COLUMN
ALTER TABLE table_name CHANGE COLUMN old_column_name new_column_name new_data_type;
• 用法:不仅可以更改列的数据类型,还可以同时更改列的名称。
• 示例:
ALTER TABLE Employees CHANGE COLUMN Salary AnnualSalary DECIMAL(10, 2);
将 Salary 列更名为 AnnualSalary,同时更改数据类型为 DECIMAL。
不正确的语法:
1. ALTER TABLE ... ALTER COLUMN:无效,MySQL 不支持此语法。
2. ALTER TABLE ... UPDATE COLUMN:无效,UPDATE 语法是用来更新数据,而非结构。
3. UPDATE TABLE ... MODIFY COLUMN:无效,UPDATE 无法用于更改列结构。
4. UPDATE TABLE ... CHANGE COLUMN:无效,与上述相同。
十八、Question
十九、 UNION 和 JOIN 的区别
• UNION 操作将两个表的所有行合并,并去掉重复的行。
UNION 的确需要两个查询的 列数相同 且 每列的数据类型兼容,但是不要求列名相同。当列名不同的时候,UNION 的行为是基于第一个查询的列名作为结果集的列名。