数据库的发展史
文件管理系统的缺点
数据库管理系统的优点
用户通过软件,将请求发送给专门的数据库管理系统(DBMS),通过它再去访问磁盘文件。
DBMS是专门针对特定的文件来管理的,比如说MySQY数据库文件,打开此文件就必须要用MySQY的数据管理系统,其他程序不能打开,相对安全
名词解释
数据库管理系统的基本功能
数据库系统的架构
关系型数据库用的由SQL语言(结构化查询语言)实现的,包括一些例如ACID的特性,可以保证数据库的安全和稳定,但是代价为性能瓶颈,当用户量达到一定数量时,这个瓶颈非常明显;基于这个原因出现了NoSQL数据库(redis等),其突出的特性就是高性能,高并发
关系型数据库简介
数据库排名:
https://db-engines.com/en/ranking
实体-联系模型E-R
联系的类型
表A:入学记录
编号 | 姓名 | 英语水平 |
---|---|---|
1 | 三峰 | 入门 |
表B:毕业记录
编号 | 学时 | 英语水平 |
---|---|---|
1 | 600课时 | 6级 |
一对多联系(1:n),一条信息对应多个对象,会用到外键(foreign key FK)
表A:主键表
ID(PK) | 姓名 | 英语水平 |
---|---|---|
1 | 三峰 | 入门 |
表B:外键表
ID(fk–>A.ID) | 学时 | 英语水平 |
---|---|---|
1 | 月考1 | 85 |
1 | 月考2 | 89 |
表A:学员表(主键表)
ID(PK) | 姓名 | 英语水平 |
---|---|---|
1 | 三峰 | 入门 |
2 | 无极 | 4级 |
表B:课程分类(主键表)
课程ID(PK) | class |
---|---|
1 | 6级包过班 |
2 | 托福加强班 |
3 | 旅游口语速成班 |
表C:报名表(外键表)
学员ID(fk–>A.ID) | classID(fk–>B.ID) |
---|---|
1 | 1 |
1 | 2 |
2 | 2 |
数据的操作
数据的约束条件:是一组完整性规则的集合,来保证数据的完整性
简易数据规划流程
数据库的正规化分析
范式
范式等级越高,可能带来的表关联越复杂,造成性能降低,很多时候会故意违反范式来提升性能
1NF
| 作者| 书名1 | 书名2 | <==不允许,即使用编号区分也不可以,因为数据内容相同
| a | linux | python|
|作者| 书名 |
| a | linux、python| <==不允许,同一列中不可有多值
|作者| 书名 | <==解决方法,将书名列为多行处理
| a| python|
| a| linux |
2NF
pk(name,city) <==复合主键
|name|cityid| sex| phone|citynumber
| a | bj | | 010 |
| a | sh | | 021 |
| b | bj | | 010 |
'回避违反格式的做法,将区号单独拿出来再建立一个表格'
|name|cityid| sex| phone|
| a | 1 |
| a | 2 |
| b | 1 |
|cityid | city | citynumber|
|1 | bj | 010 |
|2 | sh | 021 |
3NF
'这样就违反了第三范式,属性不依赖域其他非主属性,citynumber依赖于city'
ID|name|city| sex| phone|citynumber
1 | a | bj | | 010
2 | a | sh | | 021
3 | b | bj | | 010
'规避方法相同,将违反项独立出来制表'
|cityid | city | citynumber|
| 1 | bj | 010 |
| 2 | sh | 021 |
数据库对象命名
数据存储协议:应用层协议,C/S
约束
约束:constraint,表中的数据要遵守的限制
索引
将表中的一个或多个字段中的数据复制一份另存,并且按特定次序排序存储
关系运算:
数据模型
关系模型的分类:
概念
SQL: Structure Query Language
结构化查询语言,结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统, 可以使用相同的结构化查询语言作为数据输入与管理的接口。结构化查询语言语句可以嵌套,这使它具有极大的灵活性和强大的功能
SQL解释器:
与使用linux相同,SQL会有一个类似bash的解释器翻译给计算机
SQL语言规范
MariaDB [(none)]>SELECT user,host,possword FROM mysql.user;
MariaDB [(none)]> SELECT user,host FRO <==错误
-> M mysql.user
MariaDB [(none)]> SELECT user,host
-> FROM mysql.user
取消脚本中的某项命令,注释掉的格式
[root@localhost ~]$cat test.sql
/*show databases;
select user,host,password from mysql.user;*/ <==多行注释,成对出现的,中间可以包含多个命令
–注释内容单行注释,注意有空格[root@localhost ~]$cat test.sql
select ls ; -- from mysql.user; <===单行注释,'--'后内容都注释掉,只会执行ls
show databases;
SQL语句分类
SQL语句构成
源代码:编译安装
获得源代码https://mariadb.org/,选择Downland,进入下载界面选择想要的版本,推荐滞后一个版本,点击图示位置
创建用户:指定数据存放位置,指定家目录路径为/data/mysql
不自动创建,后期手动创建,自动创建会生成系统默认文件,其中的隐藏文件会显示在数据库内
'1. 创建账号'
[root@hai7-8 data]$useradd -r -s /sbin/nologin -d /data/mysql mysql
'2. 创建目录,权限为755'
[root@hai7-8 data]$mkdir /data/mysql
'3. 修改所属者所属组'
[root@hai7-8 data]$chown mysql.mysql /data/mysql/
安装编译需要工具
[root@hai7-8 data]$yum -y install bison bison-devel zlib-devel libcurl-devel libarchive-devel boost-devel gcc gcc-c++ cmake ncurses-devel gnutls-devel libxml2-devel openssl-devel libevent-devel libaio-devel
解压缩源码包
[root@hai7-8 data]$tar xvf mariadb-10.2.18.tar.gz
编译源码为可执行程序,这里比较特别的是使用cmake编译
cmake的重要特性之一是其独立于源码(out-of-source)的编译功能,即编译工作可以在另一个指定的目录中而非源码目录中进行,这可以保证源码目录不受任何一次编译的影响,因此在同一个源码树上可以进行多次不同的编译,如针对于不同平台编译
编译选项:https://dev.mysql.com/doc/refman/5.7/en/source-configuration-options.html
[root@hai7-8 mariadb-10.2.18]$cmake . \
-DCMAKE_INSTALL_PREFIX=/app/mysql \ <==安装路径
-DMYSQL_DATADIR=/data/mysql/ \ <==数据库路径
-DSYSCONFDIR=/etc \ <==配置文件路径
-DMYSQL_USER=mysql \ <==用户账号使用哪个
-DWITH_INNOBASE_STORAGE_ENGINE=1 \ <==启用那些存储引擎
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \ <==启用那些存储引擎
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ <==启用那些存储引擎
-DWITH_PARTITION_STORAGE_ENGINE=1 \ <==启用那些存储引擎
-DWITHOUT_MROONGA_STORAGE_ENGINE=1 \ <==启用那些存储引擎
-DWITH_DEBUG=0 \ <==是否启用debug
-DWITH_READLINE=1 \ <==设置权限
-DWITH_SSL=system \ <==设置权限
-DWITH_ZLIB=system \ <==设置权限
-DWITH_LIBWRAP=0 \ <==设置权限
-DENABLED_LOCAL_INFILE=1 \ <==设置权限
-DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock \ <==套接字,sock程序路径,确定要有写权限
-DDEFAULT_CHARSET=utf8 \ <==是否支持utf8
-DDEFAULT_COLLATION=utf8_general_ci
开始构建并安装
[root@hai7-8 mariadb-10.2.18]$make -j 8 && make install &&{ for i in {1..10};do echo -e '-a'; sleep 0.5;done; }
提示:如果出错,执行rm-f CMakeCache.txt
生成数据库文件
执行系统提供的生成脚本,来构建数据库的基本数据,此脚本必须在mysql程序bin所在目录下执行
'1. 进入程序安装目录'
[root@hai7-8 mysql]$cd /app/mysql/
'2. 执行脚本mysql_install_db,指定生成路径,生成所属'
[root@hai7-8 mysql]$scripts/mysql_install_db --datadir=/data/mysql --user=mysql
'3. 查看数据库生成的文件'
[root@hai7-8 mysql]$ls /data/mysql/
aria_log.00000001 aria_log_control ib_buffer_pool ibdata1 ib_logfile0 ib_logfile1 mysql performance_schema test
建立配置文件,编译时指定放在/etc下, 拿系统提供的模板文件作为参考
'1. 进入模板文件所在目录'
[root@hai7-8 mysql]$cd /app/mysql/support-files/
'2. 拷贝模板文件my-huge.cnf到编译时指定的路径,覆盖系统原文件'
[root@hai7-8 support-files]$cp my-huge.cnf /etc/my.cnf
'3. 修改配置文件,指定数据存放位置,sock文件路径'
[root@hai7-8 ~]$vim /etc/my.cnf
[mysqld]
datadir=/data/mysql <==数据存在路径
准备启动脚本
'1. 拷贝系统提供的模板到/etc/init.d/下,改名为mysqld'
[root@hai7-8 ~]$cp /app/mysql/support-files/mysql.server /etc/init.d/mysqld
'2. 将mysql服务加入服务列表'
[root@hai7-8 support-files]$chkconfig --add mysqld
'3. 启动服务'
[root@hai7-8 support-files]$service mysqld start
准备环境变量,启动服务
[root@hai7-8 ~]$echo 'PATH=/app/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
[root@hai7-8 ~]$. /etc/profile.d/mysql.sh
二进制程序安装
官方还提供了已经编译后的二进制程序,直接解压缩,稍微加以配置就可以使用
安装思路可以参考yum安装包里的安装脚本rpm -q --scripts mariadb-server
为了扩容方便,将数据目录放在逻辑卷中,先建一个逻辑卷分区(sda3)
'1. 将sda3定义为物理卷'
[root@localhost ~]$pvcreate /dev/sda3
'2. 创建卷组命名为vg_data,将sda3加入到卷组中'
[root@localhost ~]$vgcreate vg_data /dev/sda3
'3. 创建逻辑卷,将vg_data所有空间都加入到逻辑卷中'
[root@localhost ~]$lvcreate -n lv_musql -l 100%FREE vg_data
'4. 格式化文件系统'
[root@localhost ~]$mkfs.xfs /dev/vg_data/lv_musql
'5. 建一个挂载点'
[root@localhost ~]$mkdir /mysql
'6. 将挂载信息写入/etc/fstab中'
[root@localhost ~]$vim /etc/fstab
UUID=b231db56-e07f-419e-b7b7-d2b280d0580a /mysql xfs defaults 0 0
[root@localhost ~]$mount -a
准备用户,指定但不生成家目录,家目录下的隐藏文件,会显示在数据库中;手动创建目录/mysql/data,需要有写权限,这里需要注意的是权限问题
[root@localhost ~]$useradd -r -s /sbin/nologin -M -d /mysql/data mysql
解包下载的二进制程序,解压路径必须为/usr/local,是官方编译时候指定的路径,解压后目录是带版本号的,如果在主机的主机上编译目录是不带版本号的,所以需要创建一个软连接mysql,指向解压目录
[root@localhost data]$tar xf mariadb-10.2.18-linux-x86_64.tar.gz -C /usr/local <==文件的所属者、所属组有问题,需要修改
'创建软连接'
[root@localhost local]$ln -s mariadb-10.2.18-linux-x86_64/ mysql
'修改文件权限'
[root@localhost local]$chown -R root.mysql mysql/
准备配置文件,来指定数据库位置,解压后在/ mysql/support-files/目录下提供了几个模板文件,选my-huge.cnf。配置文件放置在/etc下自建目录/mysql/my.cnf,不去修改系统自带的/etc/my.cnf
'1. 创建mysql配置文件目录'
[root@localhost support-files]$mkdir /etc/mysql
'2. 拷贝模板文件到目录下,改名为my.cnf'
[root@localhost support-files]$cp my-huge.cnf /etc/mysql/my.cnf
'3. 修改模板,在[mysqld]块里,加入数据存放路径,关闭反向解析等'
[root@localhost support-files]$vim /etc/mysql/my.cnf
[mysqld]
datadir=/mysql/data <==指定数据存放路径
innodb_file_per_table= on <==数据库的每一个表都生成独立的文件10.2后版本,默认开启
skip_name_resolve= on <==禁止主机名解析(反向解析),可以提升访问速度,建议使用
创建数据库文件,基本的mysql数据库,二进制程序并不会生成,需要创建,使用解压缩后/mysql/scripts/下的脚本mysql_install_db
[root@localhost ~]$cd/usr/local/mysql/
'运行脚本创建数据库,所有者为mysql'
[root@localhost mysql]$scripts/mysql_install_db --datadir=/mysql/data --user=mysql
'此脚本的执行路径必须为程序bin所在目录,即mariadb-10.2.18-linux-x86_64或者软连接mysql目录,加上脚本路径'
要管理mysql就要将其当成服务,需要准备服务脚本,并启动服务,系统提供了模板脚本供参考 /mysql/ support-files/mysql.server
'1. 拷贝到 /etc/rc.d/init.d/并改名为mysqld,名字自定义,确保有执行权限'
[root@localhost support-files]$cp mysql.server /etc/rc.d/init.d/mysqld
'2. 将mysql服务脚本加入到服务列表中'
[root@localhost support-files]$chkconfig --add mysqld
'3. 启动服务'
[root@localhost support-files]$service mysqld start
将程序写入PATH变量中,并执行一次安全加强脚本
[root@localhost bin]$echo PATH=/usr/local/mysql/bin:$PATH > /etc/profile.d/mysql
[root@localhost profile.d]$mysql_secure_installation
官方提供的RPM包安装
下载仓库配置工具,通过配置YUM源通过互联网安装
CentOS安装光盘
[root@localhost ~]$yum -y install mariadb-server
启动服务
[root@localhost ~]$systemctl start mariadb
服务端相关文件
客户端相关文件
首次使用数据库必要说明
mysql
,默认会以mysql的本地root登录,界面如下[root@localhost ~]$mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.56-MariaDB MariaDB Server
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. <==输入help或者\h获取帮助
MariaDB [(none)]>
select user();
,查看当前用户账号;[root@localhost ~]$mysql
MariaDB [(none)]> select user() ; <==括号为系统函数
+----------------+
| user() |
+----------------+
| root@localhost | <==用户账号,两部分组成'USERNAME@HOST',
+----------------+
HOST:限制此用户可通过哪些远程主机连接mysql服务器,支持使用通配符x写法
1. % 匹配任意长度的任意字符
2. 172.16.0.0/255.255.0.0 或172.16.%.%
3. _ 匹配任意单个字符;
show databases;
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test | <==test为测试使用,其他3个为mysql使用,test可以删除
+--------------------+
select user,host,password from mysql.user;
MariaDB [(none)]> select user,host,password from mysql.user;
+------+-----------------------+----------+
| user | host | password |
+------+-----------------------+----------+
| root | localhost | | <==默认情况下数据库没有远程地址,只能本地访问
| root | localhost.localdomain | | <==目前密码为空,所以刚安装好,不需要密码就可以登录
| root | 127.0.0.1 | |
| root | ::1 | |
| | localhost | | <==账户名为空的行,表示匿名账号登录
| | localhost.localdomain | |
+------+-----------------------+----------+
mysql -u[用户] -p[密码] -h[目标IP]
;mysql -umoli
,并查看登录用户[root@localhost ~]$mysql -umoli
MariaDB [(none)]> select user();
+----------------+
| user() |
+----------------+
| moli@localhost | <==在可访问列表中没有moli账户,仍然可以登录,就是因为用户为空格的行
使用包里提供的脚本来完成优化mysql_secure_installation
[root@localhost ~]$mysql_secure_installation
Enter current password for root (enter for none): <==输入当前root的口令,初次登录没有,直接回车
Set root password? [Y/n] <==是否设置root的口令,y
New password: <==输入新口令
Re-enter new password: <==确认新口令
Remove anonymous users? [Y/n] <==是否删除匿名账户,y删除n跳过
Disallow root login remotely? [Y/n] <==是否禁用远程root登录,y禁用,禁用后只能在本机管理
Remove test database and access to it? [Y/n] y <==是否删除test数据库,y删除
Reload privilege tables now? [Y/n] <==是否将改动立即生效,y同意
优化成功后登录方法
[root@localhost ~]$mysql -uroot -pxxxxxx
[root@localhost ~]$mysql -uroot -p <==-p选项后不加密码,直接回车
Enter password: <==交互式提交密码
MariaDB [(none)]> select user,host,password from mysql.user;
+------+-----------+-------------------------------------------+
| user | host | password |
+------+-----------+-------------------------------------------+
| root | localhost | *3E4714923D8151785EF57A14E39AAFB1EA424707 |
| root | 127.0.0.1 | *3E4714923D8151785EF57A14E39AAFB1EA424707 |
| root | ::1 | *3E4714923D8151785EF57A14E39AAFB1EA424707 |
+------+-----------+-------------------------------------------+
客户端程序
mysql客户端程序其中常见的工具
MyISAM存储引擎的管理工具(已经逐渐淘汰,现在主流的是namoDB引擎)
服务器端程序
mysqld_multi--example
需要准备多个mysqld安装程序,将配置文件加以修改,让各自的端口号不同可以实现多示例,也就是跑多个数据库,各实例之间没有联系mysql客户端命令行可用选项
选项 | 描述 |
---|---|
-A, --no-auto-rehash | 禁止补全 |
-u, --user= | 用户名 ,默认为root |
-h, --host= | 服务器主机,默认为localhost |
-p, --passowrd= | 用户密码,建议使用-p,默认为空密码 |
-P, --port= | 服务器端口 |
-S, --socket= | 指定连接socket文件路径 |
-D, --database= | 指定默认数据库 |
-C, --compress | 启用压缩 |
-e | “SQL“执行SQL命令 |
-V, --version | 显示版本 |
-v --verbose | 显示详细信息 |
–print-defaults | 获取程序默认使用的配置 |
命令行可用选项示例
[root@hai7-8 ~]$mysql -e "show databases" <==-e选项可以在命令行直接执行sql命令
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
[root@hai7-8 ~]$mysql -D mysql
MariaDB [mysql]> <==中括号中设置为显示当前数据库,指定后进入会跳转到指定数据库
[root@hai7-8 ~]$mysql --print-defaults <==执行此参数时,前面不需要加用户和密码
mysql would have been started with the following arguments:
交互式命令有两类:
命令 | 描述 |
---|---|
\h, help | 获取帮助 |
\u,use | 选定当前数据库,可以理解为cd命令 |
!,system | |
\s,status | 显示当前状态信息 |
.,source | 执行文件中的命令 |
show help
脚本模式
将命令放到文件中,传给mysql
mysql –uUSERNAME -pPASSWORD< /path/somefile.sql
'1. 将show databases;和select...mysql.user;写入文件test.sql中'
[root@localhost ~]$cat test.sql
show databases;
select user,host,password from mysql.user;
'2. 将文件内容传给mysql,批量执行'
[root@localhost ~]$mysql -uroot -pxxxxxx < test.sql
Database
information_schema
mysql
performance_schema
user host password
root localhost *3E4714923D8151785EF57A14E39AAFB1EA424707
root 127.0.0.1 *3E4714923D8151785EF57A14E39AAFB1EA424707
root ::1 *3E4714923D8151785EF57A14E39AAFB1EA424707
调用文件来执行,也可以通过交互式达成,命令为
sourcemysql> source /path/from/somefile.sql
[root@localhost ~]$mysql -uroot -p
Enter password
MariaDB [(none)]> source test.sql
修改提示符
[root@localhost ~]$mysql -uroot -pfree7801336
MariaDB [(none)]> <==与bash命令行提示符类似,等待键入命令,可以修改
[root@hai7-8 /etc/yum.repos.d]$mysql --prompt="\u@\h \v [\y]"
root@localhost 10.2.18-MariaDB [18] <==修改后效果
[root@hai7-8 /etc/profile.d]$vim v9.sh
export MYSQL_PS1=" (\u@\h \v) [\d]> "
[root@hai7-8 ~]$. /etc/profile.d/v9.sh
[mysql]
语句块内,优先级高于系统配置文件[root@localhost ~]$vim /etc/my.cnf.d/mysql-clients.cnf
[mysql]
prompt="\\r:\\m:\\s [\y]>" <==格式与放在系统中的格式不同
参数 | 描述 |
---|---|
\c | 记录命令递增计数器 |
\D | 当前完整日期 |
\d | 默认数据库 |
\h | 服务器主机 |
\l | 当前分隔符 (new in 5.1.12) |
\m | 当前时间的分钟数 |
\n | 换行符 |
\O | 当前月份,以三个字母表示 (Jan, Feb, …) |
\o | 当前月份的数字格式 |
\P | am/pm |
\p | 当前TCP/IP接口或套接字文件 |
\R | 当前时间24小时制 |
\r | 当前时间12小时制 |
\S | 分号 |
\s | 当前时间的秒数 |
\t | 制表符 |
\U | 完整用户名称 user_name@host_name account |
\u | 用户名 |
\v | 数据库服务器版本 |
\w | 星期几,以三个字母表示 (Mon, Tue, …) |
\Y | 当前年份,以4个字符表示 |
\y | 当前年份,以2个符母表示 |
服务器监听的两种socket地址:
[root@localhost ~]$vim /etc/my.cnf
[mysqld]
skip-networking=1 <==值为1时关闭网络连接
服务端命令
通过mysql协议发往服务器执行并取回结果,每个命令都必须命令结束符号;默认为分号
例如:SELECT VERSION();
服务器端配置
工作特性有多种配置方式
配置文件
后面覆盖前面的配置文件,顺序如下:
数据库迁移
[root@hai7-8 ~]$mysql
MariaDB [(none)]> show variables like 'datadir' <==显示当前数据库路径
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
MariaDB [(none)]> show variables like 'basedir'; <==显示安装路径
+---------------+------------------+
| Variable_name | Value |
+---------------+------------------+
| basedir | /usr/local/mysql |
+---------------+------------------+
[root@localhost home]$service mysqld stop
迁移数据库
[root@localhost mysql]$cp /mysql/data /data/mysql -av
修改配置文件
[root@localhost mysql]$vim /etc/mysql/my.cnf
# The MySQL server
[mysqld]
datadir=/data/mysql <==迁移后的路径
[root@localhost mysql]$service mysqld start
MariaDB [(none)]> show variables like 'datadir' ;
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| datadir | /data/my/ | <==数据库路径确实已经修改
+---------------+-----------+