week 8 - Lab

week 8 - Lab

一、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 的行为是基于第一个查询的列名作为结果集的列名。