数据库基础概述
大部分互联网公司都选择MySQL作为业务数据存储数据库,除了MySQL目前还有很多公司使用Oracle(甲骨文)、SQLserver(微软)、MongoDB等。
从使用成本来区分可以将数据库分为企业版数据库(商业化)及社区版开源数据库:企业版数据库属于收费型软件,需要购买License或者Key,否则会在使用中受限于用户或数据大小的控制;开源数据库属于免费公开的类型,使用者不用花钱购买许可就可以使用。
像Oracle(甲骨文)企业版、SQL server(微软)、MySQL(甲骨文)企业版、DB2(IBM)属于企业版,MySQL社区版为开源版本。通常商业版本拥有更多的功能,同时拥有软件供应商的技术支持(但是通常技术支持很昂贵),所以银行以及垄断行业国企(电信行业)一般使用企业版数据库。互联网行业兴起后,对于数据的使用量需求增大,同时由于很多社区版数据库功能逐步丰富和性能的提高,互联网公司逐步从优先选择企业版数据库的思路转换尝试免费的社区版本,这样能够降低可观的使用成本(像一般中大型互联网公司的数据需求量,如果使用企业版本数据库则需要花费千万甚至上亿的资金购买企业正版认证和服务),相比较一个数据库工程师或者一个数据库工程师团队的人力成本要低很多。
前面大部分说的都是传统关系型数据库,关系型数据库的官方定义为:“建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据”。其中重点在于“建立在关系模型基础上的数据库”,后面会形象解释区别;针对关系型数据库还有非关系型数据库,非关系型数据库被人们统称NoSQL,像常用的Redis、MongoDB、Memcached等。关系型和非关系型数据库在数据存储是都是遵循Key-Value对应的,例如“用户名=张三,性别=男,年龄=20”,其中用户名、性别、年龄就是Key,对应的张三、男和20就是Value,这样就可以利用对应条件例如“用户名”是“张三”找到对应的“张三”的属性“性别=男,年龄=20”。
通常可以把关系型数据库中的Table(表)想象成一个标准的Excel文件中的sheet(页下签),在页面的第一行中是各个列的属性(列属性实际是表结构定义好的,列属性不单有列名,还包含其他属性,且在真正使用中列属性通常是隐式的),例如上面说的用户名、性别、年龄,列属性下面的所有内容就是所有数据,每一行的内容都是按照列属性定义好的,例如第一行是“张三,男,20”,第二行是“李四,男,21”。
非关系型数据库其实也是遵循Key-Value的,利用MongoDB举例(MongoDB是文档型数据库,其中的文档可以理解为数据行,数据表叫作集合),在MongoDB的集合中不规定你必须存储什么样的数据,既可以存储文档为“用户名=张三,性别=男,年龄=20”,也可以存储文档为“国家=中国,城市=北京”,列属性和列数量没有关系型数据库的表结构定义限制。关系型数据库与非关系型数据库没有好与坏的区分,他们需要根据不同业务场景和业务功能需要来使用。(简单了解即可)
MySQL的社区版又有很多分支,例如官方MySQL社区版、Percona社区版、MariaDB版本等,虽然他们软件提供方不一样,但实际都是在MySQL主要代码基础上封装了一些特有功能特点,例如MySQL 5.5版本、Percona 5.5版本和MariaDB 5.5版本基本功能是一样的。在实际工作中需要每个公司出的小版本都有哪些特性和新功能。
如果我们只需要维护一个简单的数据关系且数据量很小,那么可能一个Excel表格就能满足需求,但是如果数据量达到千万,数据文件几个G,那么就无法通过一个简单文本进行维护了。数据库的性能来自于数据结构和内存的使用,因为内存随机读速度比传统机械硬盘随机读速度高很多倍(暂时不引入固态硬盘讨论),所以如果能将数据库数据全部加载到内存中查询数据会很快,这也就是为什么数据库服务器的内存通常都很大,当然数据库内存大只是提供一个优良的平台,如果不进行合理的设计以及性能的调优,那么数据库使用的效率也会降低,后面会逐步说明。
数据库工程师英文全称是Database Administator,简称DBA,根据不同的数据库可以分为Oracle DBA、SQL Server DBA、MySQL DBA等。
MySQL 5.5官网功能说明索引:http://dev.mysql.com/doc/refman/5.5/en/
目前MySQL官方大版本为5.7。
搭建环境
互联网公司的服务器通常使用Linux系统作为服务端和数据库的操作系统平台,所以我们学习MySQL也需要先学会搭建一个自己实验的Linux平台环境。
在搭建实验环境之前应该先了解实体机和虚拟机的区别。像一般家用台式机、笔记本,公司机房的服务器(机架服务器、刀片服务器或中大型服务器等)都属于实体机,实体机可以理解为现实存在的实体主机;反之虚拟机是虚构出来的没有实物存在的主机,虚拟机运行在实体主机内通过软件层面实现的虚构主机。一台实体主机可以虚拟多个虚拟机,也可以通过多台实体主机的群集虚拟更多的虚拟机实现虚拟化和云的概念。
在Windows系统中我们使用VMware Workstation软件搭建Linux虚拟机,根据我们台式机或者笔记本硬件配置作为指标,实验项目为需求来构建虚拟机。
下载VMware Workstation和Linux系统镜像(iso文件),然后进行安装,我使用的是VMware Workstation 9和Centos6.3(互联网公司一般使用Redhat或者Centos发布的Linux系统,具体区别可自行查询)。
“文件”->“新建虚拟机”
“新建虚拟机”向导第一步: 选择“标准”方式安装即可
“新建虚拟机”向导第二步:“安装盘镜像文件”中选择电脑中已经下好的Linux镜像文件,例如我电脑中的是一个Centos6.3 64位的镜像文件
“新建虚拟机”向导第三步:“Easy安装信息”这一步骤是设置主机名(和虚拟机内部的主机名没有关系)、默认用户和最高权限用户密码,注意这里密码是最高权限用户即root用户的密码
“新建虚拟机”向导第四步:在“虚拟机名称”中输入的是在VMware Workstation中显示这台虚拟机的名称,可以看到第一个VMware Workstation截图中左侧“我的电脑”中已经有两个正在运行的虚拟机“Centos6.3.1”和“Centos6.3.2”。“位置”中选择这台虚拟机在Windows中保存的位置,因为虚拟机一般使用比较大的磁盘空间,所以都不会默认使用系统盘,我习惯在一个大磁盘中分配一个独立的空间给虚拟机使用
“新建虚拟机”向导第五步:在“最大磁盘空间”中设置这台虚拟机磁盘大小,这个磁盘就像实体机的硬盘一样,提供给虚拟机操作系统和数据存储使用
“新建虚拟机”向导第六步:完成第五步就基本完成了虚拟机的配置,在第六步的“虚拟机将按一下设置被创建”中是你设置好的虚拟机的基本信息包括虚拟的硬件部分,比如虚拟的“硬盘”、“内存”等
“新建虚拟机”向导第六步:可以再次“定制硬件”,比如搭建一个测试某个软件功能的实验环境实际不需要大内存,我们可以通过“定制硬件”将虚拟机分配的内存调小,一般512MB即可
“新建虚拟机”向导第七步:在第六步最下面点击“完成”后,虚拟机基本上都会自动进行安装,有的版本会在中间需要点击一次“OK”
“新建虚拟机”安装过程:Linux(不光Centos发布的,其他公司发行版本或社区版也是)实际是由很多功能块组成,在安装过程中我们可以看到安装的软件包
进入系统“登录”:注意这时需要选择“other”,然后用root用户和虚拟机安装时设置的root密码进入
进入系统“打开命令行”:因为Linux通常不使图形界面来进行操作(Ubuntu的图形界面还是很不错的),大部分工作都是通过命令行来完成的,所以我们要学会打开命令行,学会修改主机名和IP地址。进入系统后,在图形界面的桌面鼠标右键打开菜单选择“Open In Terminal”
进入系统“查看IP地址”:在虚拟机的命令行中输入“ifconfig”命令可以查看到目前虚拟机的网络连接状况
进入系统“查看IP地址”:如果使用“ifconfig”命令获取不到IP地址,例如没有出现上图中“inet addr:192.168.1.105”的信息,而是如下图的状态,可以调整虚拟机的连接设置
设置虚拟机的“网络连接”:将虚拟机的“网络连接”从“NAT”调整为“桥接”,过一会儿就会发现在虚拟机图形界面右上角时间左侧的电脑网络状态变为正常,红色叉子消失,然后在使用“ifconfig”命令获取虚拟机的IP地址
实验环境的使用
搭建实验环境可以测试软件功能,同时也可以模拟一些场景,例如公司在真实环境中的服务器结构(通常所说的生产环境架构)。
生产环境指的是互联网公司面向用户搭建的平台,就像工厂向用户提*品一样,生产环境要求高安全高可靠,一般不会轻易调整生产环境。在软件开发过程中需要模拟真实场景对软件进行测试,那么就有测试环境(有的公司还有功能环境,比测试环境更接近生产环境)。
我们搭建的虚拟机实验环境可以理解为一个测试环境,可以形象的认为VMware Workstation是一个虚拟的机房,而其中的虚拟机是虚拟机房机架上的服务器。
通常公司的服务器都在大型机房中,我们无法直接通过图形界面登录服务器,我们只能通过网络连接这些服务器,那么就需要SecureCRT或者Xshell这类远程ssh登录软件。
在上面搭建环境时我们已经查看到了虚拟机的IP地址,如果我们把VMware Workstation认为是虚拟机房,那么我们就可以通过机房的网络端口与机房中的虚拟服务器进行连接,如下图:
下载并打开SecureCRT,“文件”->“快速连接”在主机名中输入刚才Centos6.3.3图形界面的命令行中使用ifconfig命令获取到的IP地址,用户名root,点击“连接”
在初次连接时会有提示“新建主机密钥”,选择“接受并保存”(我使用了Centos6.3.2的连接,所以显示的IP是192.168.1.104)
输入root用户密码,并勾选“保存密码”后确定就模拟远程登录进入了虚拟机
在开始使用SecureCRT时会发现Linux自己的一些颜色方案无法显示(比如文件夹蓝色字体、可执行文件绿色、链接的文/件目录浅蓝色),在会话选项中的“终端”选择Linux,同时勾选“ANSI颜色”和“使用颜色方案”
1、安装
源码、分发包、rpm安装的区别和适用场景
源码包:
源码包就是程序源代码包,其中包含程序代码文件,这些代码文件是文本型,可以直接通过编辑器打开阅读内容,这里的程序还不能直接使用,因为操作系统和电脑无法直接调用文本代码,需要语言编译器将文本代码编译成二进制文件,编译完成的输出就是分发包。Windows系统安装软件时经常会出现一个自定义安装的选项,用户可以自主选择软件部分功能安装,取消安装不需要的组件,增加安装默认组件外的可选功能,在Linux系统上是通过编译参数控制软件自带功能的安装,稍后在编译安装MySQL时会举例说明。
分发包:
分发包是通过源码包编译完成的软件,可以直接使用。由于在公司生产环境中可能会出现Linux服务器版本不同、底层c和c++等语言库版本不同,可以根据系统环境版本及稳定性的需要选择源码包编译安装,或直接使用分发包。源码包编译安装可以根据自己需要选择开启或关闭一些功能,分发包由于是已经编译好的,无法再进行选择和调整,除非重新修改编译参数再编译。
rpm安装:
Linux系统提供yum命令的简单快捷软件安装方式,当Linux系统联网且yum源配置完成后,使用“yum install”加软件包名就可以安装该软件以及相关所需要的环境。
如果Linux系统主机未联网也可以在其他主机上登录软件官网下载rpm包,然后上传到该主机上使用rpm命令进行安装,但是系统会校验所需要的环境。
熟悉MySQL的三种安装方式:源码、分发包、rpm
MySQL官方下载地址:http://dev.mysql.com/downloads/mysql/
在下载页面中“Select Platform”的“Source Code”是源码包,“Linux - Generic”是官方分发包,“Red Hat EnterPrise Linux/Oracle Linux”中下载rpm包。
源码包安装:
#需要安装cmake,如果没有配置yum源可以编译安装
yum -y install cmake.x86_64
#解压源码包
tar -zxvf mysql-5.5..tar.gz
#进入源码包目录
cd mysql-5.5.
#cmake源码参数
#注意参数“-DCMAKE_INSTALL_PREFIX=”控制MySQL源码编译完软件放置的路径,通常情况用户自主安装的软件放置在“/usr/local/”下
#参数“-DWITH_INNOBASE_STORAGE_ENGINE=”说明开启InnoDB引擎
#参数“-DDEFAULT_CHARSET=utf8”说明默认使用的字符集为utf8(字符集后面解释)
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DWITH_MYISAM_STORAGE_ENGINE= -DWITH_INNOBASE_STORAGE_ENGINE= -DWITH_MEMORY_STORAGE_ENGINE= -DWITH_READLINE= -DENABLED_LOCAL_INFILE= -DMYSQL_USER=mysql -DWITH_INNOBASE_STORAGE_ENGINE= -DWITH_ARCHIVE_STORAGE_ENGINE= -DWITH_BLACKHOLE_STORAGE_ENGINE= -DWITH_PERFSCHEMA_STORAGE_ENGINE= -DWITH_PARTITION_STORAGE_ENGINE= -DWITH_FEDERATED_STORAGE_ENGINE= -DWITHOUT_EXAMPLE_STORAGE_ENGINE= -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all
#编译
make && make install
#编译完成后可以查看安装完成的软件
[root@test1 ~]# cd /usr/local/mysql
[root@test1 mysql]# ll
total
drwxr-xr-x root root Oct : bin
-rw-r--r-- root root Mar COPYING
drwxr-xr-x root root Sep : data
drwxr-xr-x root root Sep : docs
drwxr-xr-x root root Sep : include
-rw-r--r-- root root Mar INSTALL-BINARY
drwxr-xr-x root root Sep : lib
drwxr-xr-x root root Sep : man
drwxr-xr-x root root Sep : mysql-test
-rw-r--r-- root root Mar README
drwxr-xr-x root root Oct : scripts
drwxr-xr-x root root Sep : share
drwxr-xr-x root root Sep : sql-bench
drwxr-xr-x root root Sep : support-files
#bin路径下都是MySQL的命令,包含MySQL启动、停止、备份等命令
#include、lib等路径下都是MySQL底层编译完成的类库文件
#scripts下面有初始化MySQL的脚本,每个MySQL都需要初始化建立最基础的系统表及用户表(也可以使用相同版本的初始化文件在其他未初始化实例中使用,就可以省略执行初始化脚本)
分发包安装:
#解压分发包
tar -zxvf mysql-5.5.-linux-x86_64.tar.gz
#解压完成以后就会像上面编译安装完后的样子
yum/rpm包安装:
#如果系统可以联网且配置yum源可以直接yum安装
yum install -y mysql*
#如果未联网的系统可以下载好rpm包上传,然后使用rpm -ivh安装
安装完成后生成的文件
编译完成后生成的文件及文件夹如上面编译示例,分发包解压完成后也大致相同。但是编译安装后MySQL的路径是由编译前cmake参数控制的,编译完成MySQL文件会拷贝至该路径下。
分发包解压就可以使用。
yum和rpm安装会将MySQL命令安装到系统默认安装路径下。
2、启动
初始化
在第一次启动MySQL之前需要进行初始化,前面在介绍编译完的MySQL目录中提到了一个“scripts”目录,其中包含初始化脚本。因为MySQL数据库在启动时会使用一些系统表和用户表,这些表在初始状态下是没有的,都需要使用初始化脚本建立生成(也可以使用相同版本的初始化文件在其他未初始化实例中使用,就可以省略执行初始化脚本)
[root@test ~]# mkdir -p /data1/mysql/3306_mysql
[root@test ~]# /usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/data1/mysql/3306_mysql
Installing MySQL system tables...
OK
Filling help tables...
OK
...
#执行命令后出现两个OK表示初始化正常(“/data1/mysql/3306_mysql”路径需要先建立),可能不同版本的MySQL输出内容不完全相同
#在上面mysql_install_db命令的参数中,“--basedir=/usr/local/mysql”是MySQL安装目录参数以及安装目录路径,“--datadir=/data1/mysql/3306_mysql”是MySQL数据目录参数及数据目录路径
#执行上面的命令后会在“/data1/mysql/3306_mysql”目录中建立几个目录和文件
[root@test ~]# ll /data1/mysql/3306_mysql/
total
-rw-rw---- root root Feb : log-error.log
drwx------ root root Feb : mysql
-rw-rw---- root root Feb : mysql-bin.
-rw-rw---- root root Feb : mysql-bin.
-rw-rw---- root root Feb : mysql-bin.index
drwx------ root root Feb : performance_schema
drwx------ root root Feb : test
可以看到上面生成了3个目录分别是mysql、performance_schema、test,这3个目录是初始化脚本生成的3个库(数据库中的库,库是存放表的单位,MySQL会默认MySQL数据目录中的目录都是它是库),其中mysql目录最重要,其中包含上面提到的系统表和用户表,另外两个目录则默认为空。
mysql-bin为名的文件是MySQL的二进制日志,后面复制中会提到;log-error.log是MySQL的错误日志,其中会包含启动过程、运行中出现的错误以及一些其他信息。前面提到的两个文件可以通过修改配置文件调整文件命名规则,所以在一些人或公司使用MySQL时会出现其他的二进制文件名、错误日志名。
另外注意在初始化MySQL后要讲数据目录调整为mysql用户所属。
配置与配置文件
使用Windows软件时通常会有软件设置,在Linux系统中的软件通常在启动和使用时利用软件参数调整软件的自带功能。因为通常软件的启动参数较多,也有软件(例如MySQL)不支持直接使用内置参数加载,所以需要配置文件,配置文件是汇总一个软件配置信息的独立文件,软件通过直接读取配置文件获取所有的配置信息,不用在软件启动时后面跟很多参数。
MySQL启动时有启动参数(在Linux系统上的命令参数都可以使用“命令 --help”的方式获得说明,例如“mysqld_safe --help”),MySQL在使用中有动态和静态参数两种。
启动参数
MySQL在启动时一般使用“--defaults-file=配置文件”让MySQL实例启动时加载配置文件。
内置参数(配置文件中的)
由于数据库性能依靠内存,所以配置文件中会有很多针对MySQL实例内存的设置,用几个参数举例:
key_buffer_size = 64M #MyISAM引擎表内存预分配大小,实例级别参数
innodb_buffer_pool_size = 1G #InnoDB引擎表内存预分配大小(MySQL 5.7以前版本无法动态修改),实例级别参数
sort_buffer_size = 4M #MySQL服务在处理排列时可以使用的内存,线程级别
数据库一般会对请求进行限制,比如只能同时对200个不同请求源进行处理,在这之外的请求需要等待直到200个请求中有已经完成且断开连接的。可以把管理这些连接的东西看做一个池“连接池”,当连接池满了就无法在承载,除连接池外还有个处理等待请求的连接池。相关参数有:
max_connections=200 #最大连接数限制,就是上面说的200个请求,在MySQL中我们称之为thread“线程”
max_user_connections=150 #用户的最大连接数限制,也就是说同一个用户可以从不同的地方访问数据库,但是受限于这个值
connect_timeout = 20 #连接等待超时时间。当等待的请求超过这个时间就被断开
wait_timeout=30 #连接请求处理完成后,如果空闲时间超过30秒会被MySQL主动断开
interactive_timeout=30 #与wait_timeout设置相同即可,参数具体差异可以参考官网说明
动态参数与静态参数
动态参数就是在MySQL在使用中可以直接调整并且生效的参数。相反有些参数无法直接修改生效,需要修改配置文件并重启MySQL实例才可以。
MySQL不同版本的参数也完全相同,有的低版本参数在高版本中取消了,有的低版本参数无法动态修改然后高版本可以。
单、多实例启动
单实例启动 mysqld_safe
[root@test ~]# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &
#上面命令中“/usr/local/mysql/bin”是MySQL编译安装完的命令目录,“--defaults-file=/etc/my.cnf”是配置文件参数以及配置文件位置,“&”是Linux的修饰符,表示这个命令在后台运行
在互联网公司中通常一台数据库服务器不只运行一个MySQL实例(一个运行的MySQL就叫作一个MySQL实例),就像一台电脑可以运行多个QQ一样。
同时启动多个实例 mysqld_multi
[root@test ~]# /usr/local/mysql/bin/mysqld_multi --defaults-file=/etc/my.cnf start
#由于这种方式不常用,不多做解释,如果需要自己参考官网说明
启动后生成的文件
熟悉日志
3、使用
连接的概念
建库建表
添加、查询、删除、更改数据
SQL语法及简单函数
主从复制原理
用户管理及权限控制
备份
4、优化
存储引擎的特点
SQL优化方法
监控内存、磁盘的使用