3.2 Ubuntu Linux 安装配置 MySQL

修改密码: mysqladmin -u root password

在 Ubuntu 上安装 MySQL,最简单的方式是在线安装。只需要几行简单的命令( # 号后面是注释):

1
2
3
4
5
#安装 MySQL 服务端、核心程序
sudo apt-get install mysql-server

#安装 MySQL 客户端
sudo apt-get install mysql-client

在安装过程中会提示确认输入 YES,设置 root 用户密码(之后也可以修改)等,稍等片刻便可安装成功。

安装结束后,用命令验证是否安装并启动成功:

1
sudo netstat -tap | grep mysql

如果出现如下提示,则安装成功:

1-02

此时,可以根据自己的需求,用 gedit 修改 MySQL 的配置文件(my.cnf),使用以下命令:

1
sudo gedit /etc/mysql/my.cnf

至此,MySQL 已经安装、配置完成,可以正常使用了。

3.3 尝试 MySQL

1). 打开 MySQL

使用如下两条命令,打开 MySQL 服务并使用 root 用户登录:

1
2
3
4
5
# 启动 MySQL 服务
sudo service mysql start

# 使用 root 用户登录,实验楼环境的密码为空,直接回车就可以登录
mysql -u root

执行成功会出现如下提示:

1-03

2). 查看数据库

使用命令 show databases;,查看有哪些数据库(注意不要漏掉分号 ;):

1-04

可见已有三个数据库,分别是 “information-schema”、“mysql”、“performance-schema”。

3). 连接数据库

选择连接其中一个数据库,语句格式为 use <数据库名>,这里可以不用加分号,这里我们选择 information_schema 数据库:

1
use information_schema

1-05

4). 查看表

使用命令 show tables; 查看数据库中有哪些表(注意不要漏掉“;”):

1-06

5). 退出

使用命令 quit 或者 exit 退出 MySQL。it或者exit` 退出 MySQL。

本节实验会创建几个表,然后对其中的各个字段添加约束,学习添加和测试约束的方法。

2.1 约束分类

听名字就知道,约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性。

比如,规定一个用户的用户名不能为空值且没有重复的记录,这就是一种约束规则。

在MySQL中,通常有这几种约束:

约束类型: 主键 默认值 唯一 外键 非空
关键字: PRIMARY KEY DEFAULT UNIQUE FOREIGN KEY NOT NULL

2.2 建立含约束的表

为了方便介绍这几种约束,我们先建立一个数据库。

注:如果你是从上一节直接进入本节进行学习的,请先删除上一节建立的数据库mysql_shiyan,删除语句为DROP DATABASE mysql_shiyan; 关于数据库的删除操作我们会具体讲解,这里先继续实验。

当然不用你一行一行地输入命令搭建这个数据库,实验楼已经为你准备好了。首先打开 Xfce 终端,输入命令进入 /home/shiyanlou/Desktop 目录:

1
cd Desktop

使用 git 命令将需要的数据文件下载到本地文件夹:

1
git clone https://github.com/shiyanlou/SQL3.git

下载完成后,输入命令开启 MySQL 服务并使用 root 用户登录:

1
2
3
4
5
#打开 MySQL 服务
sudo service mysql start

#使用 root 用户登录
mysql -u root

刚才下载的 SQL3 目录下,有个文件 MySQL-03-01.sql,其中包含的代码可以新建一个数据库 mysql_shiyan,然后在其中创建三张表 departmentemployeeproject,它们包含了各种约束。

(SQL3 目录在桌面上,你可以用Gedit查看里面的 MySQL-03-01.sql 文件。)

如果你是接着上一个实验开始操作的话,记得先使用如下命令删掉 mysql_shiyan 数据库:

1
drop database mysql_shiyan;

加载文件中的数据,需要在 MySQL 控制台中输入命令:

1
source /home/shiyanlou/Desktop/SQL3/MySQL-03-01.sql;

查看一下这个数据库,输入命令 show tables;,可见:

00

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
CREATE DATABASE mysql_shiyan;

use mysql_shiyan;

CREATE TABLE department
(
dpt_name CHAR(20) NOT NULL,
people_num INT(10) DEFAULT '10',
CONSTRAINT dpt_pk PRIMARY KEY (dpt_name)
);

CREATE TABLE employee
(
id INT(10) PRIMARY KEY,
name CHAR(20),
age INT(10),
salary INT(10) NOT NULL,
phone INT(12) NOT NULL,
in_dpt CHAR(20) NOT NULL,
UNIQUE (phone),
CONSTRAINT emp_fk FOREIGN KEY (in_dpt) REFERENCES department(dpt_name)
);

CREATE TABLE project
(
proj_num INT(10) NOT NULL,
proj_name CHAR(20) NOT NULL,
start_date DATE NOT NULL,
end_date DATE DEFAULT '2015-04-01',
of_dpt CHAR(20) REFERENCES department(dpt_name),
CONSTRAINT proj_pk PRIMARY KEY (proj_num,proj_name)
);

2.3 主键

在数据库中,如果有两行记录数据完全一样,那么如何来区分呢? 答案是无法区分,如果有两行记录完全相同,那么对于 Mysql 就会认定它们是同一个实体,这于现实生活是存在差别的。

假如我们要存储一个学生的信息,信息包含姓名,身高,性别,年龄。

不幸的是有两个女孩都叫小梦,且她们的身高和年龄相同,数据库将无法区分这两个实体,这时就需要用到主键了。

主键 (PRIMARY KEY)是用于约束表中的一行,作为这一行的唯一标识符,在一张表中通过主键就能准确定位到一行,因此主键十分重要,主键不能有重复记录且不能为空。

MySQL-03-01.sql 中,这里有主键:

07

也可以这样定义主键:

08-

还有一种特殊的主键——复合主键。主键不仅可以是表中的一列,也可以由表中的两列或多列来共同标识,比如:

09-

2.4 默认值约束

默认值约束 (DEFAULT) 规定,当有 DEFAULT 约束的列,插入数据为空时,将使用默认值。

默认值常用于一些可有可无的字段,比如用户的个性签名,如果用户没有设置,系统给他应该设定一个默认的文本,比如空文本或 ‘这个人太懒了,没有留下任何信息’

MySQL-03-01.sql 中,这段代码包含了 DEFAULT 约束:

10

DEFAULT 约束只会在使用 INSERT 语句(上一实验介绍过)时体现出来, INSERT 语句中,如果被 DEFAULT 约束的位置没有值,那么这个位置将会被 DEFAULT 的值填充,如语句:

1
2
3
4
5
# 正常插入数据
INSERT INTO department(dpt_name,people_num) VALUES('dpt1',11);

#插入新的数据,people_num 为空,使用默认值
INSERT INTO department(dpt_name) VALUES('dpt2');

输入命令 SELECT * FROM department;,可见表中第二行的people_num 被 DEFAULT 的值 (10) 填充:

01

2.5 唯一约束

唯一约束 (UNIQUE) 比较简单,它规定一张表中指定的一列的值必须不能有重复值,即这一列每个值都是唯一的。

MySQL-03-01.sql 中,也有 UNIQUE 约束:

11

当 INSERT 语句新插入的数据和已有数据重复的时候,如果有 UNIQUE 约束,则 INSERT 失败,比如:

1
2
INSERT INTO employee VALUES(01,'Tom',25,3000,110110,'dpt1');
INSERT INTO employee VALUES(02,'Jack',30,3500,110110,'dpt2');

结果如图:

02

2.6 外键约束

外键 (FOREIGN KEY) 既能确保数据完整性,也能表现表之间的关系。

比如,现在有用户表和文章表,给文章表中添加一个指向用户 id 的外键,表示这篇文章所属的用户 id,外键将确保这个外键指向的记录是存在的,如果你尝试删除一个用户,而这个用户还有文章存在于数据库中,那么操作将无法完成并报错。因为你删除了该用户过后,他发布的文章都没有所属用户了,而这样的情况是不被允许的。同理,你在创建一篇文章的时候也不能为它指定一个不存在的用户 id。

一个表可以有多个外键,每个外键必须 REFERENCES (参考) 另一个表的主键,被外键约束的列,取值必须在它参考的列中有对应值。

12-

在 INSERT 时,如果被外键约束的值没有在参考列中有对应,比如以下命令,参考列 (department 表的 dpt_name) 中没有 dpt3,则 INSERT 失败:

1
INSERT INTO employee VALUES(02,'Jack',30,3500,114114,'dpt3');

可见之后将 dpt3 改为 dpt2(department 表中有 dpt2),则插入成功:

03

2.6 外键约束

外键 (FOREIGN KEY) 既能确保数据完整性,也能表现表之间的关系。

比如,现在有用户表和文章表,给文章表中添加一个指向用户 id 的外键,表示这篇文章所属的用户 id,外键将确保这个外键指向的记录是存在的,如果你尝试删除一个用户,而这个用户还有文章存在于数据库中,那么操作将无法完成并报错。因为你删除了该用户过后,他发布的文章都没有所属用户了,而这样的情况是不被允许的。同理,你在创建一篇文章的时候也不能为它指定一个不存在的用户 id。

一个表可以有多个外键,每个外键必须 REFERENCES (参考) 另一个表的主键,被外键约束的列,取值必须在它参考的列中有对应值。

12-

在 INSERT 时,如果被外键约束的值没有在参考列中有对应,比如以下命令,参考列 (department 表的 dpt_name) 中没有 dpt3,则 INSERT 失败:

1
INSERT INTO employee VALUES(02,'Jack',30,3500,114114,'dpt3');

可见之后将 dpt3 改为 dpt2(department 表中有 dpt2),则插入成功:

03

2.6 外键约束

外键 (FOREIGN KEY) 既能确保数据完整性,也能表现表之间的关系。

比如,现在有用户表和文章表,给文章表中添加一个指向用户 id 的外键,表示这篇文章所属的用户 id,外键将确保这个外键指向的记录是存在的,如果你尝试删除一个用户,而这个用户还有文章存在于数据库中,那么操作将无法完成并报错。因为你删除了该用户过后,他发布的文章都没有所属用户了,而这样的情况是不被允许的。同理,你在创建一篇文章的时候也不能为它指定一个不存在的用户 id。

一个表可以有多个外键,每个外键必须 REFERENCES (参考) 另一个表的主键,被外键约束的列,取值必须在它参考的列中有对应值。

12-

在 INSERT 时,如果被外键约束的值没有在参考列中有对应,比如以下命令,参考列 (department 表的 dpt_name) 中没有 dpt3,则 INSERT 失败:

1
INSERT INTO employee VALUES(02,'Jack',30,3500,114114,'dpt3');

可见之后将 dpt3 改为 dpt2(department 表中有 dpt2),则插入成功:

03

搭建一个简易的成绩管理系统的数据库

介绍

现需要构建一个简易的成绩管理系统的数据库,来记录几门课程的学生成绩。数据库中有三张表分别用于记录学生信息、课程信息和成绩信息。

数据表结构如下:

学生表(student):学生 id 、学生姓名和性别

此处输入图片的描述

课程表:课程 id 和课程名

此处输入图片的描述

成绩表:成绩 id 、学生 id 、课程 id 和分数

此处输入图片的描述

服务器中的 MySQL 还没有启动,请注意 MySQL 的 root 账户默认密码为空。

目标

1.MySQL 服务处于运行状态

2.新建数据库的名称为 gradesystem

3.gradesystem 包含三个表:student、course、mark;

  • student 表包含3列:sid(主键)、sname、gender;
  • course 表包含2列:cid(主键)、cname;
  • mark 表包含4列:mid(主键)、sid、cid、score ,注意与其他两个表主键之间的关系。

4.将上述表中的数据分别插入到各个表中

提示

  • 建立表时注意 id 自增和键约束
  • 每个表插入语句可通过一条语句完成

挑战参考代码

以下内容仅供参考,为了能有更好的学习效果,请尽量按自己的想法来完成练习题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ sudo service mysql start

$ mysql -u root

mysql> CREATE DATABASE gradesystem;

mysql> use gradesystem

mysql> CREATE TABLE student(
-> sid int NOT NULL AUTO_INCREMENT,
-> sname varchar(20) NOT NULL,
-> gender varchar(10) NOT NULL,
-> PRIMARY KEY(sid)
-> );

mysql> CREATE TABLE course(
-> cid int NOT NULL AUTO_INCREMENT,
-> cname varchar(20) NOT NULL,
-> PRIMARY KEY(cid)
-> );

mysql> CREATE TABLE mark(
-> mid int NOT NULL AUTO_INCREMENT,
-> sid int NOT NULL,
-> cid int NOT NULL,
-> score int NOT NULL,
-> PRIMARY KEY(mid),
-> FOREIGN KEY(sid) REFERENCES student(sid),
-> FOREIGN KEY(cid) REFERENCES course(cid)
-> );

mysql> INSERT INTO student VALUES(1,'Tom','male'),(2,'Jack','male'),(3,'Rose','female');

mysql> INSERT INTO course VALUES(1,'math'),(2,'physics'),(3,'chemistry');

mysql> INSERT INTO mark VALUES(1,1,1,80),(2,2,1,85

SELECT语句详解

3.1 基本的SELECT语句

SELECT 语句的基本格式为:

1
SELECT 要查询的列名 FROM 表名字 WHERE 限制条件;

如果要查询表的所有内容,则把 要查询的列名 用一个星号 * 号表示(实验2、3中都已经使用过),代表要查询表中所有的列。 而大多数情况,我们只需要查看某个表的指定的列,比如要查看 employee 表的 name 和 age:

1
SELECT name,age FROM employee;

01

3.2 数学符号条件

SELECT 语句常常会有 WHERE 限制条件,用于达到更加精确的查询。WHERE限制条件可以有数学符号 (=,<,>,>=,<=) ,刚才我们查询了 name 和 age,现在稍作修改:

1
SELECT name,age FROM employee WHERE age>25;

筛选出 age 大于 25 的结果:

02

或者查找一个名字为 Mary 的员工的 name,age 和 phone:

1
SELECT name,age,phone FROM employee WHERE name='Mary';

结果当然是:

03

3.3 “AND”与“OR”

从这两个单词就能够理解它们的作用。WHERE 后面可以有不止一条限制,而根据条件之间的逻辑关系,可以用 [条件一 OR 条件二]] 和 [条件一 AND 条件二] 连接:

例如,筛选出 age 小于 25,或 age 大于 30

1
SELECT name,age FROM employee WHERE age<25 OR age>30;

04

1
2
#筛选出 age 大于 25,且 age 小于 30
SELECT name,age FROM employee WHERE age>25 AND age<30;

05

而刚才的限制条件 age>25 AND age<30 ,如果需要包含25和30这两个数字的话,可以替换为 age BETWEEN 25 AND 30

06

3.4 IN 和 NOT IN

关键词 INNOT IN 的作用和它们的名字一样明显,用于筛选“在”“不在”某个范围内的结果,比如说我们要查询在 dpt3dpt4 的人:

1
SELECT name,age,phone,in_dpt FROM employee WHERE in_dpt IN ('dpt3','dpt4');

07

NOT IN 的效果则是,如下面这条命令,查询出了不在 dpt1 也不在 dpt3 的人:

1
SELECT name,age,phone,in_dpt FROM employee WHERE in_dpt NOT IN ('dpt1','dpt3');

08