数据库入门 (摘自廖雪峰的官方网站)
数据库作为一种专门管理数据的软件就出现了。应用程序不需要自己管理数据,而是通过数据库软件提供的接口来读写数据。至于数据本身如何存储到文件,那是数据库软件的事情,应用程序自己并不关心:
随着时间的推移和市场竞争,最终,基于关系模型的关系数据库获得了绝对市场份额。
数据模型
数据库按照数据结构来组织、存储和管理数据,实际上,数据库一共有三种模型:
- 层次模型:上下级”的层次关系来组织数据的一种方式,看起来就像一颗树
- 网状模型:把数据节点和很多节点都连接起来,看起来就像很多城市之间的路网
- 关系模型:把数据看作是一个二维表格,任何数据都可以通过行号+列号来唯一确定,它的数据模型看起来就是一个Excel表
数据类型
对于一个关系表,除了定义每一列的名称外,还需要定义每一列的数据类型。关系数据库支持的标准数据类型包括数值、字符串、时间等:
主流关系数据库
目前,主流的关系数据库主要分为以下几类:
1.商用数据库,例如:Oracle,SQL Server,DB2等;
2.开源数据库,例如:MySQL,PostgreSQL等;
3.桌面数据库,以微软Access为代表,适合桌面应用程序使用;
4.嵌入式数据库,以Sqlite为代表,适合手机应用和桌面程序。
什么是SQL?
SQL是结构化查询语言的缩写,用来访问和操作数据库系统。SQL语句既可以查询数据库中的数据,也可以添加、更新和删除数据库中的数据,还可以对数据库进行管理和维护操作。不同的数据库,都支持SQL,这样,我们通过学习SQL这一种语言,就可以操作各种不同的数据库。
安装MySQL
MySQL是目前应用最广泛的开源关系数据库,和其他关系数据库有所不同的是,MySQL本身实际上只是一个SQL接口,它的内部还包含了多种数据引擎.
在Linux上安装MySQL:
可以使用发行版的包管理器。例如,Debian和Ubuntu用户可以简单地通过命令apt-get install mysql-server安装最新的MySQL版本。
运行MySQL
MySQL安装后会自动在后台运行。为了验证MySQL安装是否正确,我们需要通过mysql这个命令行程序来连接MySQL服务器。
在命令提示符下输入mysql -u root -p
,然后输入口令,如果一切正确,就会连接到MySQL服务器,同时提示符变为mysql>
。
输入exit
退出MySQL命令行。注意,MySQL服务器仍在后台运行。
关系模型
关系模型本质上就是若干个存储数据的二维表,可以把它们看作很多Excel表。
表的每一行称为记录(Record),记录是一个逻辑意义上的数据。
表的每一列称为字段(Column),同一个表的每一行记录都拥有相同的若干字段。
主键
对于关系表,有个很重要的约束,就是任意两条记录不能重复。不能重复不是指两条记录不完全相同,而是指能够通过某个字段唯一区分出不同的记录,这个字段被称为主键。对主键的要求,最关键的一点是:记录一旦插入到表中,主键最好不要再修改,因为主键是用来唯一定位记录的,修改了主键,会造成一系列的影响。
选取主键的一个基本原则是:不使用任何业务相关的字段作为主键。
常见的可作为id字段(主键)的类型有:
- 自增整数类型:数据库会在插入数据时自动为每一条记录分配一个自增整数,这样我们就完全不用担心主键重复,也不用自己预先生成主键;
- 全局唯一GUID类型:使用一种全局唯一的字符串作为主键,类似8f55d96b-8acc-4636-8cb8-76bf8abc2f57。GUID算法通过网卡MAC地址、时间戳和随机数保证任意计算机在任意时间生成的字符串都是不同的,大部分编程语言都内置了GUID算法,可以自己预算出主键。
联合主键:关系数据库实际上还允许通过多个字段唯一标识记录
外键
关系数据库通过外键可以实现一对多、多对多和一对一的关系。外键既可以通过数据库来约束,也可以不设置约束,仅依靠应用程序的逻辑来保证。
//外键并不是通过列名实现的,而是通过定义外键约束实现的
ALTER TABLE students
ADD CONSTRAINT fk_class_id
FOREIGN KEY (class_id)
REFERENCES classes (id);
索引
索引是关系数据库中对某一列或多个列的值进行预排序的数据结构。通过使用索引,可以让数据库系统不必扫描整个表,而是直接定位到符合条件的记录,这样就大大加快了查询速度。
ALTER TABLE students
ADD INDEX idx_score (score)
查询数据
- 基本查询
使用SELECT
查询的基本语句SELECT * FROM <表名>
可以查询一个表的所有行和所有列的数据。SELECT
查询的结果是一个二维表
例:SELECT * FROM students;
- 条件查询
SELECT语句可以通过WHERE
条件来设定查询条件,查询结果是满足查询条件的记录。SELECT * FROM <表名> WHERE <条件表达式>
score >= 80 AND gender = 'M'
使用<>判断不相等 score <> 80 name <> 'abc'
使用LIKE判断相似 name LIKE 'ab%' name LIKE '%bc%' %表示任意字符
例如'ab%'将匹配'ab','abc','abcd'
- 投影查询
返回某些列的数据,而不是所有列的数据
SELECT 列1, 列2, 列3 FROM ...使用LIMIT <M> OFFSET <N>可以对结果集进行分页,每次查询返回结果集的一部分;
分页查询需要先确定每页的数量和当前页数,然后确定LIMIT和OFFSET的值。
SELECT id, score, name FROM students;
使用投影查询,并将列名重命名:
SELECT id, score points, name FROM students;
使用投影查询+WHERE条件:
SELECT id, score points, name FROM students WHERE gender = 'M';
- 排序
根据其他条件排序怎么办?可以加上ORDER BY
子句,如果score列有相同的数据,要进一步排序,可以继续添加列名。
例:使用ORDER BY score DESC, gender表示先按score列倒序,如果有相同分数的,再按gender列排序:
-- 按score, gender排序:
SELECT id, name, gender, score FROM students ORDER BY score DESC, gender;
- 分页查询
使用LIMIT OFFSET 可以对结果集进行分页,每次查询返回结果集的一部分;
分页查询需要先确定每页的数量和当前页数,然后确定LIMIT和OFFSET的值。 - 聚合查询
统计一张表的数据量,以查询students表一共有多少条记录为例,我们可以使用SQL内置的COUNT()
函数查询,SELECT COUNT(*) FROM students;
GROUP BY子句指定了按class_id分组-- 使用聚合查询并设置WHERE条件:
SELECT COUNT(*) boys FROM students WHERE gender = 'M';
如果聚合查询的WHERE
条件没有匹配到任何行,COUNT()
会返回0,而SUM()、AVG()、MAX()和MIN()
会返回NULL:
- 多表查询
SELECT查询不但可以从一张表查询数据,还可以从多张表同时查询数据。查询多张表的语法是:SELECT * FROM <表1> <表2>
- 链接查询
连接查询是另一种类型的多表查询。连接查询对多个表进行JOIN运算,简单地说,就是先确定一个主表作为结果集,然后,把其他表的行有选择性地“连接”在主表结果集上。
选出所有学生,同时返回班级名称 SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score FROM students s INNER JOIN classes c ON s.class_id = c.id;
修改数据
INSERT语句的基本语法
INSERT INTO <表名> (字段1, 字段2, ...) VALUES (值1, 值2, ...);
UPDATE语句的基本语法
UPDATE <表名> SET 字段1=值1, 字段2=值2, ... WHERE ...;
DELETE
DELETE FROM <表名> WHERE ...;
管理MySQL
MySQL Client命令行都是客户端,和MySQL交互,唯一的接口就是SQL。
数据库
在一个运行MySQL的服务器上,实际上可以创建多个数据库(Database)。
- 要列出所有数据库,使用命令:
SHOW DATABASES;
- 要创建一个新数据库,使用命令:
CREATE DATABASE test;
- 删除一个数据库,使用命令:
DROP DATABASE test;
表
- 列出当前数据库的所有表,使用命令:
SHOW TABLES;