认识数据库
文章主要分为以下两个部分:
- 数据库分类
- MySQL 基础
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,每个数据库都有一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据。相对于文件存储数据,数据库中存储数据效率更高。
结构化查询语言(Structured Query Language)简称 SQL,是上世纪 70 年代由 IBM 公司开发,用于对数据库进行操作的语言。用于存取数据以及查询、更新和管理数据库系统,同时也是数据库脚本文件的扩展名。
数据库分类
目前数据库主要分为传统的关系型数据库(SQL)和非关系型数据库(NoSQL),还有最近几年出现的 NewSQL 新型数据库、分布式数据库等。
关系型数据库
关系型数据库把数据以表的形式进行存储,然后在各个表之间建立联系,通过表之间的关系来操作不同表之间的数据。
关系型数据库依据关系模型来创建数据库,关系模型是指“一对一,一对多,多对多”,通过关系模型来构建二维表格。
- 一对一:身份证号,校园卡
- 一对多:班级-学生,部门-职员
- 多对多:课程-学生,书籍-作者
常见的关系型数据库有 MySQL,Oracle,MariaDB,SqlServer,Access,PostgreSQL 等。
优点:
- 数据安全,数据一致性
- 二维表结构直观,易理解
- 使用 SQL 语句操作非常方便,可用于比较复杂的查询
缺点:
- 读写性能较差
- 不擅长处理较复杂的关系
非关系型数据库
传统的关系型数据库因为无法支持大规模数据和访问量而成为整个系统的瓶颈,非关系型数据库的关键在于放弃了传统关系型数据库的强事务保证和关系模型,通过所谓最终一致性和非关系数据模型(例如键值对,图,文档)来提高 Web 应用所注重的高可用性和可扩展性。
NoSQL 没有固定的表结构,其数据之间不存在表与表之间的关系,数据之间可以是独立的,因此 NoSQL 可以用于分布式系统上。
NoSQL 大致可以分为四种:
分类 | 数据模型 | 优势 | 举例 |
---|---|---|---|
键值数据库(key-value) | 哈希表 | 查询快,易部署,高并发 | Redis,Memcached |
列存储数据库 | 列式数据存储 | 查询快,数据压缩率高,不需要额外建立索引 | HBase,Cassandra |
文档型数据库 | 键值对扩展 | 将数据以文档的形式存储,数据结构不定 | MongoDB,CouchDB |
图数据库 | 节点和关系组成的图 | 利用图结构的相关算法 | Neo4j,JanusGraph |
键值数据库
键值数据库类似于传统语言中使用的哈希表,通过 key 来添加、删除、查询数据。因为使用 key 主键来访问,所以键值数据库具有很高的性能及拓展性。
例如 Redis,由于其数据是存储于内存,读写速度非常快。Redis 在一秒内读写可以超过十万个键值。它虽然是作为数据库来开发的,现在更广泛的应用于缓存、消息队列。
列存储数据库
列存储数据库将数据存储在列族中,一个列族存储经常被查询的相关数据。
列存储数据库主要用于海量数据分析。在进行数据分析时,通常只会查询表中的一列或几列,这时只需要把这几列拿出来就可以了,不需要查询的不关心,大大提高了检索效率。列存储数据库每一列存储的数据类型相同,压缩率较高。
文档型数据库
文档型数据库与键值数据库是类似的,只不过将数据用文档的形式存储,数据存储可以是 XML, JSON 等多种形式。
图数据库
图数据库将数据以图的方式存储。实体作为顶点,实体之间的关系作为边。图模型比较灵活,可以拓展到多个服务器上,图数据库没有标准的查询语言。
图数据库一般用于推荐系统,处理社交网络等等。
MySQL 基础
MySQL 是流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS (Relational Database Management System:关系数据库管理系统)应用软件之一。MySQL 使用 SQL 语言进行操作。
前置知识
配置文件 /etc/my.cnf
该文件默认配置如下:
登录
mysql -uroot -p
******** # 输入密码
# 退出
mysql>exit/quit
管理数据库
# 查看数据库
SHOW DATABASES;
# 使用数据库
USE 数据库名;
# 查看数据库中表名
SHOW TABLES;
# 查看表中列名
SHOW COLUMNS FROM 数据表名;
数据类型
MySQL 支持多种类型,大致可以分为三类:数值,日期/时间和字符串类型。
数值类型
数据类型 | 大小(字节) | 用途 |
---|---|---|
INT | 4 | 整数 |
FLOAT | 4 | 单精度浮点数 |
DOUBLE | 8 | 双精度浮点数 |
日期时间类型
类型 | 大小(字节) | 用途 | 格式 |
---|---|---|---|
DATE | 3 | 日期 | YYYY-MM-DD |
TIME | 3 | 时间至或持续时间 | HH:MM:SS |
YEAR | 1 | 年份值 | YYYY |
DATETIME | 8 | 混合日期和时间值 | YYYY-MM-DD HH:MM:SS |
字符串类型
类型 | 大小(字节) | 用途 | 格式 |
---|---|---|---|
CHAR | 0-255 | 定长字符串 | |
VARCHAR | 0-65535 | 变长字符串 | |
BLOB | 0-65535 | 二进制行形式的长文本数据 | |
TEXT | 0-65535 | 长文本数据 | |
ENUM | -- | 单选,比如性别 | ENUM('a','b','c') |
SET | -- | 多选 | SET('1','2','3') |
CHAR 和 VARCHAR 的区别:CHAR 的长度是固定的,而 VARCHAR 的长度是可以变化的。比如,存储字符串 “abc”,对于 CHAR(10),表示存储的字符将占 10 个字节(包括 7 个空字符),而同样的 VARCHAR(12) 则只占用 4 个字节的长度,增加一个额外字节来存储字符串本身的长度,12 只是最大值,当存储字符小于 12 时,按实际长度。
EMUN 和 SET 的区别:EMUN 类型的数据的值,必须是定义时枚举的值的其中之一,即单选,而 SET 类型的值可以多选。
约束
约束是一种限制,通过对表的行或列的数据做出限制,来确保表的数据完整性、唯一性。
比如规定一个用户的用户名不能为空值且没有重复的记录,这就是一种约束
在 MySQL 中,通常有这几种约束:
约束类型 | 主键 | 默认值 | 唯一 | 外键 | 非空 |
---|---|---|---|---|---|
关键字 | PRIMARY KEY | DEFAULT | UNIQUE | FOREIGN KEY | NOT NULL |
- 主键:数据表中的一行数据的唯一标识符,不能重复记录且不能为空
- 默认值:当有 DEFAULT 约束的列,插入数据为空时,将使用默认值
- 唯一:规定一张表中指定的一列的值必须不能有重复值
- 外键:确保数据完整性,每个外键必须参考另一个表的主键,被外键约束的列,取值必须在它参考的列中有对应值
- 非空:在插入值时必须非空
基本操作
创建数据库
CREATE DATABASE 数据库名;
创建数据表
CREATE TABLE 数据表名(
字段1 数据类型(数据长度)
字段2 数据类型(数据长度)
);
增加
往数据表中插入数据
INSERT INTO 数据表名(字段1,字段2) VALUES(值1,值2);
演示:创建一个 test 库,含有一个 students 数据表,往表中插入 id, name, gender, birth等信息,结果如下。
如果在插入中文时出错,可以在创建数据表时将编码方式设置为 utf8
。
CREATE TABLE student(
id int(10),
name char(20),
gender enum('男','女'),
birth date,
age int(5),
city varchar(20)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
查询
SELECT 语句的基本格式为:
SELECT 列名 FROM 表名 WHERE 限制条件
限制条件
- 比较条件:=, <, >, <=, >=
- 逻辑条件:AND, OR
- 范围:IN, NOT IN
- 通配符:LIKE 用于实现模糊查询,常见于搜索功能。
_
代表一个未指定字符,%
代表不定个未指定字符。 - 排序:ORDER BY 字段 (ASC/DESC) 升序或降序,默认为升序
内置计算函数
5 个内置函数:
函数名 | COUNT | SUM | AVG | MAX | MIN |
---|---|---|---|---|---|
作用 | 计数 | 求和 | 求平均 | 最大值 | 最小值 |
其中 COUNT 函数可用于任何数据类型,而 SUM, AVG 函数都只能对数字类型数据做计算,MAX 和 MIN 可用于数值,字符串或是日期时间数据类型
select MAX(salary) AS max_salary,MIN(salary) FROM employee;
修改和删除
MySQL 没有提供修改数据库名称的方法,因为这曾导致一系列安全问题。比较安全的做法是重新建一个新库,然后将旧库中的数据转移到新库中,并且暂时不要删除旧的数据库,以防数据遗失。
删除数据库
DROP DATABASE 数据库名;
重命名表名
RENAME TABLE 原名 TO 新名字;
ALTER TABLE 原名 RENAME 新名;
ALTER TABLE 原名 RENAME TO 新名;
删除表
DROP TABLE 表名字;
表结构修改
增加一列——ALTER ... ADD
ALTER TABLE 表名字 ADD COLUMN 列名字 数据类型 约束;
ALTER TABLE 表名字 ADD 列名字 数据类型 约束;
ALTER TABLE emplouyee add height int(10) default 170;
结果如下
新增加的列,被默认放置在表的最右边,如果要指定插入的位置,可以使用 AFTER 关键字;如果想放在第一列的位置,则使用 FIRST 关键字,如语句
ALTER TABLE employee ADD weight INT(4) DEFAULT 120 AFTER age;
ALTER TABLE employee ADD test INT(4) DEFAULT 11 FIRST;
删除一列——ALTER ... DROP
ALTER TABLE 表名字 DROP COLUMN 列名字;
ALTER TABLE 表名字 DROP 列名字;
重命名一列——ALTER ... CHANGE
ALTER TABLE 表名 CHANGE 原列名 新列名 数据类型 约束;
原列名和新列名相同时可以用于修改数据类型,修改数据类型可能会导致数据丢失,所以要慎重使用。
ALTER TABLE employee CHANGE height shengao INT(4) DEFAULT 170;
修改数据类型——ALTER ... MODIFY
ALTER TABLE 表名字 MODIFY 列名字 新数据类型;
修改表中某个值——UPDATE ... SET ... WHERE
UPDATE 表名字 SET 列1=值1,列2=值2 WHERE 条件;
例:
UPDATE employee SET age=21,salary=3000 WHERE name='Tom';
注意:一定要有 WHERE 条件,否则会出现你不想看到的结果
删除一行记录——DELETE ... WHERE
DELETE FROM 表名 WHERE 条件;
例:
DELETE FROM emplyee WHERE name='Tom';
其他
索引
在表中建立索引,在在、索引中找到符合查询条件的索引值,通过索引值可以快速找到表中的数据,可以大大加快查询速度。
建立索引格式
ALTER TABLE 表名字 ADD INDEX 索引名 (列名)
CREATE INDEX 索引名 ON 表名 (列名)
例:
ALTER TABLE employee ADD INDEX idx_id (id);
CREATE INDEX idx_name ON employee (name);
使用 SHOW INDEX FROM 表名
查看新建的索引。
视图
视图是从一个或多个表中导出来的表,是一种虚拟存在的表。
- 数据库中只存放了视图的定义,没有存放视图中的数据,这些数据存放在原来的表中
- 使用视图查询数据时,数据库系统会从原来的表中去除对应是数据
- 视图中的数据依赖于原来表中的数据,一旦表中的数据发生改变,显示在视图中的数据也会发生改变
- 在使用视图时,可以把它当做一张表
格式:
CREATE VIEW 视图名(列1,列2) AS SELECT 列1,列2 FROM 表名;
例子
CREATE VIEW v_emp (v_name,v_age,v_phone) AS SELECT name,age,phone FROM employee;
SELECT * FROM v_emp;
导入
导入 .sql
文件,在 MySQL 交互界面执行如下命令
source 文件路径/test.sql;
导入纯数据文件,把文件中得到数据保存到表中
LOAD DATA INFILE '文件路径和文件名' INTO TABLE 表名;
导入导出属于敏感操作,根据 MySQL 的安全策略,导入导出文件都必须在指定的路径下进行,在 MySQL 中查看路径变量
show variables like '%secure%'
指定安全路径为 /var/lib/mysql-files
,将要导入的数据文件移动到安全路径下。
查看 in.txt
文件内容
sudo vim /var/lib/mysql_files/SQL6/in.txt
在 MySQL 中查看没导入数据之前 employee 表的内容
执行导入语句,结果如下
LOAD DATA INFILE '/var/lib/mysql-files/SQL6/in.txt' INTO TABLE employee;
导出
导出与导入是相反的过程,是把数据库某个表中的数据保存到一个文件之中。
格式
SELECT 列1,列2 INTO OUTFILE '文件路径和文件名' FROM 表名;
注意文件路径之下不能有同名文件。
SELECT * INTO OUTFILE '/var/lib/mysql-files/out.txt' FROM employee;
备份
备份与导出的区别:导出的文件只是保存数据库中的数据;备份则是把数据库的结构,包括数据,约束,索引,视图等全部另存为一个文件。
mysqldump
是用于备份数据库的使用程序,主要产生一个 sql 脚本。
# 在终端中执行,不是 mysql 环境下
mysqldump -u root 数据库名>备份文件名; # 备份整个数据库
mysqldump -u root 数据库名 表名>备份文件名; # 备份整个表
备份整个数据库 mysql_shiyan
,将备份文件命名为 bak.sql
mysqldump -u root mysql_shiyan > bak.sql
成功创建备份文件。
恢复
新建一个新的空数据库 test
mysql> CREATE DATABASE test;
退出交互界面
mysql -u root test < bak.sql
总结
之前对数据库的分类不了解,不清楚关系型数据库与非关系型数据库的区别,这次练习,因为是主动学习的过程,主动去了解关系型数据库的特点,非关系型数据库的分类,所以还是有很大的收获。
对数据库的操作练习,也加强了自己对数据库的理解,但感觉自己还是不够熟练,还需继续加油!