欢迎各位兄弟 发布技术文章
这里的技术是共享的
500G排序,排序不能在磁盘上,只能在进程所在的地址空间中进行
如果没有索引,仅仅靠操作系统文件来进行的话,必须要把500G的数据全部载入内存排序,
才能取得排序结果的
更重要的是32位系统上,任何一个进程所能使用的内存空间不会超出4G,(当然windows 32位 可能是另外一码事)
除了保留给内存系统的1G之外,事实上也只有3G,
无论如何,对于数据的高效管理,在文件上是无法实现的,这就是为什么对于数据的管理必须要基于DBMS的原因,
DBMS根据规模不同分为
轻量级的应用
企业级的应用
有了DBMS后,我们的数据管理变得非常简化了
有了DBMS后,我们的数据管理的优势:
1,数据管理独立性 我们能够实现把数据表达和存储抽象给它分开
2,有效的完成数据存取 而不用每次操作都要涉及到对整个数据的做扫描
3,能够保证数据的完整性(尤其是RDBMS上施加一定的约束,这个数据在满足什么样的前提下才可以插入,这个数据在满足什么样的前提下才可以删除,它们彼此之间是有一定的关联关系的,它们的关联关系称之为约束,后面讲常见的约束类型,及实现什么样的约束)和安全性
4,数据集中管理 当多个用户共享数据的时候,我们实现集中管理有着极大的优势,可以将多个不同的需求的数据降低冗余,以节约存储空间,并且也能够实现集中对用户的权限进行指派等等,能够大大降低数据管理的难度
5,能够实现并发存储和故障恢复 一般而言,一个DBMS都应该提供类似的功能的 (两个转账,一减一增,数据文件崩溃或损坏,如何将损失降为最低)
6,减少应用程序开发时间(数据存储和应用程序的逻辑相分开)(当然这是在数据的逻辑层面上来完成的,跟程序开发本身没有关系)
一个DBMS应该具有的基本结构
用户对数据的管理,绝大多数都是通过sql命令来完成的,
sql(结构化查询语言 Structured query language) 这是早期的 IBM 公司的一个管理员为他们公司内部一个叫做systemr的关系型数据库管理系统所设计的一种云接口 叫sql
事实上接口刚出来不久,众多商业公司都采用SQL这种技术手段,并且在他们的商业关系型数据库产品当中都提供了自己的实现(像 Oracle egreSQL等等)
但是SQL本身只是一种类似于Shell的一种数据库管理接口(使用接口)
shell(bash shell, c shell,k shell )每一种 shell的使用方法和使用风格各有不同,
所以不同公司的像Oracle或者sql server的,他们的商业产品,内部实现的sql的格式可能也不尽相同,
所以为了避免这种乱象丛生的局面,美国国家标准委员会ANSI出面来规范SQL应该具有的功能,
所以现在SQL这种语言在ANSI是有标准的,从早期的86,89,92,99,03标准,它是用当年标准制定的年限来命名的
比较著名的 sql86 sql89 sql92 sql99 等,它们定义了一个数据库管理系统的接口应该实现哪些基本功能,而且应该具有什么样的使用特色
这样子,用户学了一款sql软件以后,那么操作同类的不属于同一个商业公司所提供的服务器软件,这种语法和命令的使用格式是兼容的,说白了,这就是一种工业标准
这就是我们所说的SQL
它们也称之为结构化查询语言,
绝大多数数据库管理软件,都提供了sql接口,以便用户能够使用sql查询语句的,
就算我们的access也能够接受sql语句的,它也有自己的sql接口
shell解释器要对shell作词法分析,语法分析,
关系型数据库管理系统的内部结构上应该具有的几个基本组件:
dbms (rdbms) (r就是relation)
前端用户对于sql使用,都是使用sql命令来发出的,
(发了sql命令的有可能是应用程序(比如php,php的前端驱动),有可能是用户,(应用前端,sql接口,web表格?各种应用程序))
sql命令送给我们的dbms以后,dbms必须要接收下来,并且做处理,(当然判断用户的权限等,现在先不说,只说它的基本组件)
分析器(词法分析,语法分析) 分析用户输入的命令倒底在语法上有没有问题,
计划执行器 分析器的下一步,分析的结果要生成执行计划 一个sql语法分析后可能会生成n个执行路径,也就是说一个sql语句可能有多个执行方法(比如执行一个select语句,要从某个表中查询出来一些数据,我们可以做全表扫描,对表中每一行逐个进行比较,这是一种查询方法;;;;也可以使用索引,假设有三个索引,其中两个索引都可以用,意味着我们为了完成这一条语句,有三种可执行的路径,三种方式,都能完成对应的任务) 计划执行器 就是分析我们倒底有多少种路径可以完成相应的任务的 分析执行以后,应该使用代价最小的,性能最好的,才是我们最终选择的
优化器 要对每一条路径?的语句做一个优化,使用优化器对结果进行优化, 直正选择了一条语句,它还不能直接执行,而是从中选择一个最优的执行方式,甚至不惜要对整个查询语句做改写的方式,只要执行结果一样,都成,,,那这就叫做优化器
文件的存取 语句要执行的话,意味着我们要操作数据了,数据在磁盘上放着,在磁盘上的文件中,所以我们必须要有一个系统完成文件的存取, 在这个地方,我们的dbms也必须得完成, 文件的存取方法有n种,我们要实现其中的至少一种
缓存器 进程不会在磁盘上直接操作数据,应该把数据载入到内存中进行操作,将文件读进来的时候,应该是在读入到内存中的一个缓存器中,将文件基于文件的存取方法存取的时候先把它读到缓存器中才能进行操作,它所能缓存的文件的量有是限的,一旦缓存满了,现在又需要载入新的数据,怎么办?置换,把缓存器中最近最少使用的内容给它替换出去,腾出空间,再读入新的内容,所以必须提供一种策略来管理缓存器当中的内容(这种策略是怎么提供的,不同的数据库服务器(不同的dbms)所提供的算法是不一样的) 缓存器所提供的任何内容最终我们要在这里面做了一些修改,它还要回存到磁盘上去,如何回去,存到哪个位置呢?我们还需要一个工具进行管理,这个工具就叫做磁盘空间管理器
磁盘空间管理器 它要实现对磁盘空间中的某个数据文件中的数据到底该怎么存储进行管理的,由此数据必须要由磁盘空间管理器转化以后存储到磁盘上
故障恢复管理器 一个dbms还要能够提供故障恢复的功能,所以它还要提供一个故障恢复管理器,万一我们的服务器正在运行过程中突然崩溃了,下一次启动以后,应该让我们的服务器某些数据本来正在存储过程中的数据,存取了一半的数据,将它恢复为正常状态
事务管理器 除此之外,我们一般还应该有并发事务管理器
锁管理器 还有一个并发的功能管理器的一个辅助工具,我们称为锁管理器
这是一个dbms所应该具备的几个基本功能,对我们而言,刚开始的时候,我们最关心的是前端执行引擎, (分析器 计划执行器 优化器) sql引擎给我们提供了众多的命令
命令分为
DDL DML DCL
数据定义语言 数据操作语言 数据控制语言
它有很多的命令,这些命令其实都要提交给我们的sql引擎来(分析器 计划执行器 优化器)进行执行的
不同的关系型数据库管理系统,它们所实现的内在逻辑和所实现的功能模块可能是不尽相同的,这就是几个最基本应该具备的基本功能 一个rdbms应该具备的几个核心组件
mysql 该怎么使用?
发行版有两类:
商业版(企业版) Enterprise Editon 比社区版提供了一部分的增强性的功能 比如企业级的性能监视器,也提供了其它的一些商业组件,比如备份工具,性能分析工具,以及增强的连接池功能等等
社区版 Community Edtion 在某些功能上不如企业版强 免费下载直接使用 而且是开源的
对我们而言 ,其实社区版的绝大部分功能都已经足够了
php 要访问mysql 可以通过api直接访问,也可以通过php的驱动,驱动就叫做连接器
MySQL native driver for PHP - mysqlnd 这里提供了mysql 的连接器
其实php也提供了连接mysql的连接器
我们可以自己选择使用哪个连接器
GA (General Ablity 公共可用版本)
https://dev.mysql.com/downloads/mysql/
mysql的 Community Server是遵循GPL协定的,而且目前最新版本是 8.0
如果要下载所需要的我们所期望对应的那个版本的话
我们选择对应的平台
我们想安装mysql服务器的话,它给我们提供的对应的软件包 有三种格式
1)软件包管理器特有的格式
比如 rpm 包 (deb包等) 包括 windows 上的msi,exe等
2)通用二进制格式 相当于绿色软件,(直接解压,做一些简单配置,就能够使用,不用安装)
3)源程序
我们应该用到的是 glibc 编译的包
rpm 有两类:
一类是特有平台的 (红帽 susi 都是使用rpm包的)
另一类是通用平台的
我们使用的 rhel 5.8的 平台 (32位)
1)特有的rpm包 为刚才的rhel5 使用的
2)通用二进制格式也行
3)源程序也成 源代码编译安装也成
几种方式都能安装mysql,最简单的方式,就是红帽官方提供给我们的rpm包
事实上安装完红帽的操作系统之后,只要制作好yum源,红帽官方制作好的就有mysql相关的包
[root@www ~]# yum list all | grep mysql
This system is not registered to Red Hat Subscription Management. You can use su bscription-manager to register.
file:///media/cdrom/Server/repodata/repomd.xml: [Errno 5] OSError: [Errno 2] 没 有那个文件或目录: '/media/cdrom/Server/repodata/repomd.xml'
Trying other mirror.
apr-util-mysql.i386 1.2.7-11.el5_5.2 development
freeradius-mysql.i386 1.1.3-1.6.el5 development
freeradius2-mysql.i386 2.1.12-5.el5 development
libdbi-dbd-mysql.i386 0.8.1a-1.2.2 development
mod_auth_mysql.i386 1:3.0.0-3.2.el5_3 development
mysql.i386 5.0.95-5.el5_9 development #mysql的客户端 (mysql是c/s架构的,有服务器端和客户端)
mysql-bench.i386 5.0.95-5.el5_9 development #性能分析组件 压力测试组件
mysql-connector-odbc.i386 3.51.26r1127-2.el5 development #mysql专用的odbc的连接器
mysql-connector-odbc64.i386 5.1.8-1.el5 development #mysql专用的odbc的连接器
mysql-devel.i386 5.0.95-5.el5_9 development
mysql-server.i386 5.0.95-5.el5_9 development #mysql的服务器端
mysql-test.i386 5.0.95-5.el5_9 development #mysql的 测试组件
mysql51.i386 1-9.el5 development
mysql51-build.i386 1-9.el5 development
mysql51-mysql.i386 5.1.70-1.el5 development
mysql51-mysql-bench.i386 5.1.70-1.el5 development
mysql51-mysql-libs.i386 5.1.70-1.el5 development
mysql51-mysql-server.i386 5.1.70-1.el5 development
mysql51-mysql-test.i386 5.1.70-1.el5 development
mysql51-runtime.i386 1-9.el5 development
mysql55.i386 1-12.el5 development
mysql55-build.i386 1-12.el5 development
mysql55-mysql.i386 5.5.32-3.el5 development
mysql55-mysql-bench.i386 5.5.32-3.el5 development
mysql55-mysql-devel.i386 5.5.32-3.el5 development
mysql55-mysql-libs.i386 5.5.32-3.el5 development
mysql55-mysql-server.i386 5.5.32-3.el5 development
mysql55-mysql-test.i386 5.5.32-3.el5 development
mysql55-runtime.i386 1-12.el5 development
php-mysql.i386 5.1.6-40.el5_9 development
php53-mysql.i386 5.3.3-21.el5 development
qt4-mysql.i386 4.2.1-1.el5_7.1 development
rsyslog-mysql.i386 3.22.1-7.el5 development
rsyslog5-mysql.i386 5.8.12-4.el5 development
[root@www ~]#
我们要提供mysql服务器的话,只要安装mysql-server.i386即可
有了服务器之后,还要做一些测试,做一些查看,还要装mysql.i386
所以对于红帽官方提供给我们的内容来讲 rpm包对我们而言,最重要的有两个mysql,mysql-server
如果用到php的话,会看到php-mysql.i386 php53-mysql(这是驱动) (不装php,php-mysql.i386 php53-mysql这是没有必要的)
这是官方提供给我们的包,版本是5.0,版本很老,,现在已经是5.6.10的版本
因此,要使用最新的包,要使用mysql官方所提供的rpm包(这些包版本可能更新,但是要注意的是
红帽官方上rhel上其它应用程序将依赖于这个系统本身所提供的rpm包,所以要使用mysql官方所提供的rpm包的话,
可能红帽系统上的一些软件还会自动给你安装红帽官方所提供的rpm包,这是让人崩溃的地方,由此在红帽上,我们要使用
很多依赖于mysql服务器的应用程序的话,我们不建议使用mysql官方所提供的rpm包,建议使用红帽自有的,因为这样,
依赖关系所必须要强制你提供的功能;而且很多应用程序彼此之间的版本有依赖性的,你提供太新的版本,它未必适用...
除非我们把这台主机专门就做mysql服务器,不装其它额外应用程序,也没有人依赖mysql的话,这个时候,你可以使用mysql官方的rpm包)
如果我们编译(全部手动编译)安装一个平台 比如 LAMP ,这个时候就可以使用mysql的源码包(使用源码包定制安装mysql,或者使用它的通用二进制格式也成)
mysql 源码有2,3十M,编译起来,恐怕没有半个小时,不大容易实现
因此,除非我们特别需要定制mysql中的某些特性,否则简单的测试环境中,我们完全可以使用通用二进制格式来安装mysql
我们的通用二进制格式 将近300M,解压出来 应该有6,7百M了吧(因为它的压缩比比较大)
点 no thanks,just start my download 就可以下载对应的版本了
我们这里先不使用二进制格式来安装
mysql是C/S架构的组件
事实上在红帽系列的系统上,给我们提供的组件就已经把它们分割开来了
mysql 客户端
mysql-server 服务器端
而安装完成之后,它们各自有二进制程序
mysql
mysql 命令 选项大多都有默认值
mysql
-u USERNAME (-u 表示username)指明以哪个用户的身份去连接 不指,默认是root
-p (-p 表示 password)(可以 后面跟单引号('')里面是密码,不建议,因为别人会看到密码) (-p直接敲回车,它让我们输密码的),表示给这个用户提供密码的 不指,默认是空密码
-h MYSQL_SERVER (-h 表示host)指定mysql主机服务器是谁 不指,默认就是localhost
mysqld-safe (干脆叫mysqld) 至于safe是什么,我们后面再说
mysqld安装完之后,直接启动,mysql服务器就可以运行起来了
监听在 tcp/3306 端口,一般情况下,默认使用一个普通用户去运行,这样子服务器故障或服务器被劫持,不致于影响全局
一般以 mysql:mysql (mysql用户 mysql 组)的身份去执行
mysql是一个 RDBMS
这个RDBMS在我们生成数据库以后,这些数据是要保存在我们的数据库服务器某个目录当中(或者某个磁盘的某个文件系统上)
默认情况下,在红帽系列的系统上 保存在 /var/lib/mysql 这个位置不理想,因为假如500G的文件,可能放不下吧 而且mysql文件的预期增长大小的速度与实际的增长大小的速度绝对是两码事
所以我们修改它倒底安装在什么位置 (或者说数据文件目录应该在什么位置) (此时不修改位置吧,这里我们主要是简单看看mysql倒底是怎么安装和使用的)
只要装mysql-server 一般它会自动解决依赖关系的
装mysql-server 客户端mysql也会装上的
[root@localhost ~]# yum -y install mysql-server
安装完成之后,mysql服务器会有一个初始化的动作
对于mysql服务器来讲,它是一个服务器程序,它可以帮我们管理很多的数据库,
每一个数据库的数据库名来引用数据库,
每一个数据库里面有多少张表,每一个表的表名,每一个表里面的字段,字段的属性等存到哪里,就好像我们存文件一样,一个文件名本身不属于文件数据,文件的大小不属于文件数据,文件名,文件大小称为文件的元数据,这些元数据存放在哪里?
对于文件系统来讲,文件元数据存放在 元数据区
对于mysql来讲,也有很多的元数据,数据库的服务器的名字,表的名称,字段名称,字段属性信息,这些跟数据本身是没有关系的,这些数据放在哪里?也需要一个位置来存放,所以mysql创建完成以后,有个独特的数据库,就叫mysql
mysql首先是一个服务器软件,而在这个服务器软件内部自己也有一个数据库就叫mysql
这个数据库里面放的就叫元数据, 当前的数据库上有多少个数据库,每个名字叫什么,每个库里面的表,每个表的名字叫什么,每个表里面的字段,字段的属性定义等等,都在这个mysql数据库里面,很显然,刚开始安装好数据库的时候,mysql库是不存在的
初始化的过程就是让我们建立这个mysql库的.
启动mysql 直接就是 service mysqld start
第一次启动的时候,它会自动完成初始化的
[root@localhost ~]# service mysqld start
[root@localhost ~]# service mysqld start
初始化 MySQL 数据库: Installing MySQL system tables...
OK
Filling help tables...
OK
To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h localhost.localdomain password 'new-password'
Alternatively you can run:
/usr/bin/mysql_secure_installation
which will also give you the option of removing the test
databases and anonymous user created by default. This is
strongly recommended for production servers.
See the manual for more instructions.
You can start the MySQL daemon with:
cd /usr ; /usr/bin/mysqld_safe &
You can test the MySQL daemon with mysql-test-run.pl
cd mysql-test ; perl mysql-test-run.pl
Please report any problems with the /usr/bin/mysqlbug script!
The latest information about MySQL is available on the web at
Support MySQL by buying support/licenses at http://shop.mysql.com
[确定]
启动 mysqld: [确定]
[root@localhost ~]#
马哥的 mysql 第一次启动
初始化mysql 数据库,正在安装mysql的系统表
警告 max_join_size 不要管它,
正在复制mysqld 当中的某些数据 提示已经好了
mysqld有一个root用户,这个mysql的root 与 操作系统的root是两码事 这是mysql服务器的root
mysql的数据应该被哪些用户访问,我们是应该定义权限的,一个用户能够访问哪些数据库对象,都是靠用户标识来实现的,这个mysql的root用户的默认密码是空的 为了安全性,应该设定为一个特定的密码,这个mysql的root用户是具有最高权限的,所以不设密码非常危险
看下mysql监听的3306端口有没有打开
[root@localhost ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 3961/./hpiod
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 16044/mysqld
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 3567/portmap
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3984/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 3998/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 4039/sendmail
tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN 3966/python
tcp 0 0 0.0.0.0:831 0.0.0.0:* LISTEN 3617/rpc.statd
tcp 0 0 :::80 :::* LISTEN 13765/httpd
tcp 0 0 :::22 :::* LISTEN 3984/sshd
tcp 0 0 :::443 :::* LISTEN 13765/httpd
[root@localhost ~]#
客户端连mysql服务器吧 命令叫 mysql
这个客户端命令会自动的连接到mysql服务器上去
[root@localhost ~]# mysql
\q (反斜杠q)(或者 exit 或者 quit)退出mysql
选项和它的参数之间可以没有空格 (比如 -uroot)
[root@localhost ~]# mysql -uroot -p -h 127.0.0.1
Enter password: #没有密码 直接敲回车
使用自己的ip地址 192.168.1.45 ,它告诉你连不上去
为什么使用不同的地址连不上去?
这是因为mysql的用户比较独特
mysql用户: USENAME@HOST (包括用户名及允许它能够登录的主机 ,这个主机指的是客户端主机 允许你使用USERNAME在哪些客户端主机上来登录我们mysql服务器的)
所以我们连接mysql服务器的时候,指定服务器的ip地址是使用-h来指定的 (-h 应该指的是客户端的ip吧?),但是我们创建用户的时候,也是在mysql服务器上来创建这个用户,必须指定用户名,密码,以及能够通过哪些客户端主机来登录
我们允许root通过本机来进行密码登录,不允许你通过192.168.1.45来登录,因为使用192.168.1.45的话,就相当于使用远程主机来登录了
mysql 客户端与服务器是怎么连接的?
http是基于tcp协议的
dhcp是基于udp协议的
dns既有tcp,又有udp的
mysql是基于tcp协议的,长时间处于连接状态的协议,但是如果服务器与客户端在同一台主机上,它是另外一码事 (比如 -h 127.0.0.1或 localhost的时候 如果是linux,使用的是socket的方式进行连接的;;;;;如果是windows 使用 memory 共享内存的方式来进行连接的)
(如果 -h 192.168.1.45,哪怕仍然是同一台主机,但是它也不是使用socket这种方式来连接,而是使用tcp/ip协议来连接)
socket是一个套接字文件(文件的类型,有一种文件叫套接字文件)
linux上的mysql的套接字文件叫 /var/lib/mysql/mysql.sock
这样子就意味着实现的是本机进程间通信,这样子性能就意味着不需要使用网络驱动来连接,这样子的话,速度会快得多
如果客户端和服务端不在同一台主机上(如果指定的不是localhost 或 127.0.0.1 即使是同一台主机,也是tcp/ip协议来连接),那就必须要使用tcp/ip协议来连接了
[root@localhost ~]# ls /var/lib/mysql/
ibdata1 ib_logfile0 ib_logfile1 mysql mysql.sock test
[root@localhost ~]#
mysql客户端工具 交互式客户端
连接到服务器上以后,可以在里面输很多命令
有两种工作模式
交互式模式:输入一个命令,程序就执行一个命令
批处理模式:可以写一堆脚本,执行一堆脚本,类似于我们的bash shell,执行mysql脚本的,一次执行n条命令
连接到交互式模式以后,交互式模式中的命令类别:
客户端命令:在客户端本身执行的命令
\q 是客户端命令
\h 或 help 可以获取客户端命令的帮助的
客户端命令 都有两种格式 直接使用命令或者反斜线加一个字符来表示这个命令的简写
\? 获取帮助 \q 退出客户端
所有的客户端命令都可以加上命令直接执行
服务器端命令:这个命令要发送到服务器端,由服务器执行,并返回到客户端的命令
select 查询等太多的命令
所有的服务端命令都必须使用语句结束符 默认是分号 ;
为什么要使用语句结束符?不然的话(这条命令要送到服务器端执行,一条完整的语句写到哪里算结束呢?所以必须要明白这个语句到哪里算结束了,才能进行执行的)
SQL接口
任何一个关系型数据库管理系统都应该提供自己的sql接口,sql接口实现sql的时候,它应该遵循sql的ANSI规范 (从道理上讲,大家都应该遵循规范,这样子兼容性更好,但事实上,每一个关系型数据库管理系统在遵循某一种规范的同时,都对它进行了扩展 比如Oracle除了兼容基本的sql接口之外,还扩展了sql语句,被称为叫PL/SQL (可以理解成叫过程语言SQL,它支持强大的编程功能,它支持条件选择,循环,这样一来,它的编程能力大大增强了,默认的ANSI规范定义的时候,是没有这些功能的) (SQL Server ,T-SQL ( Transact-SQL 事务SQL) )) (MySQL也做了扩展,只不过自己没说叫什么SQL,MySQL也有很多自己独有的东西,其它数据库上未必能够使用的,比如这里有个命令,可以放到服务器上执行的 ( SHOW DATABASES ); 显示有几个数据库,,,,安装了MySQL后,默认给我们创建了三个数据库)
(最重要是mysql数据库
information_schema数据库 为了保证兼容的 为了保证如果其它服务器上不支持show这样的命令的话,我们也能够查找有多少个数据库,所以information_schema当中所保留的就是类似于将我们这些数据库当中所产生的执行中的信息保存在一个数据库的格式,并且提供了一个查询接口的,说白了,information_schema是mysql运行当中位于内存中的信息,(我们知道 proc目录吧,磁盘上没有任何东西,但是linux启动起来以后,proc目录里面有一堆文件,但是它又不是文件,它是内核中的参数,这里information_schema也是的,关机后information_schema里面是空的,里面没有任何信息,但是打开数据库后发现里面有一堆信息,就是一样的道理,,,它是mysql运行当中所产生的一些运行时数据所储存的位置)
test数据库是空的,只有测试的时候才用到它
而这每一个数据库其实对应于相当于我们文件系统中的一个目录
)
mysql默认情况下,数据库放在/var/lib/mysql 下面
[root@www cdrom]# ls /var/lib/mysql/
ibdata1 ib_logfile0 ib_logfile1 mysql mysql.sock test
没有看到 information_schema 因为information_schema 是位于内存中的,是内存映射
在 /var/lib/mysql/ 里面 建一目录,就相当于建立一个数据库
[root@www cdrom]# cd /var/lib/mysql/
[root@www mysql]# mkdir mydb
[root@www mysql]#
此时看到多了一个数据库 mydb
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| test |
+--------------------+
4 rows in set (0.01 sec)
mysql>
数据库其实简单映射一下,就是目录, 就是在它的数据目录下的一个子目录,而且名称都是相同的
数据库名称区分不区分大小写,取决于你的文件系统
linux ext2 ext3 区分大小写的
windows 是不区分大小写的
各个关系型数据库都有自己的扩展吧(show databases;应该就是mysql的自己的扩展命令),
可能有些扩展并不是完全兼容的
show databases; 是一条执行语句,是一个服务器端命令吧
关系数据库对象
库
表:
索引:
视图: (虚表)
约束: (键,其实也是索引)
存储过程:
存储函数:
触发器: (对主动数据库的)
游标: (C语言编程时经常涉及到的一个概念)
用户:
上面的都是可以创建的对象,数据库定义语言就是定义这些对象的
权限:
事务:
关系型数据库最核心的组件就是表
表是由 行, 列 组成
一个表没有一行是可以的,是空表,没有任何一列数据是不行的,没有列的话(没有属性定义),数据无法存储
一个表称为一个实体 (通常一个表称为一个实体集,某一类实体的集合)
表中的每一行表示的数据的意义是一样 (通常每一行称为一个实体) row
列来表示各种不同的属性, 字段 field (column) (一个表至少得有一个列)
我们要往表中插入数据,要事先定义好表的格式,就意味着要定义表的字段
1,字段名称, 要是一个能够描述实体属性的某一个类别,最好能够做到见名知义,跟命名变量的时候是一样的,一般来讲只能使用字符数字下划线,但是一般来讲我们只使用字符,,,,像变量一样,我们的字段是用来存数据的,整形变量和字符型变量存储10的时候,存储方法不一样,
INT A=10 4位就够了,一个字节足矣
CHAR A=10 这个是两个字符,至少要16位
2,数据类型, 对于关系型数据库来讲,除了要有字段名称,还要有字段类型(数据类型) mysql是强类型的,必须要给对应的字段定义数据类型 字符型,数值型,日期型,布尔型(逻辑型,是真还是假)
字符型:
CHAR(n), CHAR(10)表示里面最多能存10个字符,若没存到10个,它占据10个空间,无论你占不占用,它都是10个字符的空间,所以有可能会浪费 最多只能存储256个字符? 默认情况下是不区分大小写的,固定长度
VARCHAR(n),var ( variable )表示可变化的,可变长度的char, VARCHAR(10),如果存了2个字符,它只占据了2个字符的空间(其实不是2个,而是2+1个),既然不知道有多长,后面的几个空倒底是不是我们的字符组成部分呢?所以它必须要有一个结束符(结束修饰符) 最多只能存储65536个字符 默认情况下是不区分大小写的, 可变长度
BINARY(n) ,以二进制格式来进行存储,它是区分大小写的,也是字符型,它叫二进制,但它可不是二进制数据,它的意思是区分大小写的字符,它也只存储固定长度的
VARBINARY(n) ,实现变长的BINARY
TEXT(n),存储大量字符的时候,文本大对象,明确说明我们用多少个字节来存储,我们要存储多大长度的TEXT文本, 这是文本格式 text有多种变化(smalltext mediumtext text longtext)
BLOB(n),(binary large object )二进制的大对象
上面的字符支持NOT NULL,不允许为空,
数值型
精确数值型:
整形 INTEGER INTEGER有n种变化
(TINYINT 一个字节的 微整形 -128至+127 或 0至255)
(SMALLINT 两个字节的 小整形)
(MEDIUMINT 三个字节的中等整形)
(INT 四个字节的整形)
(BIGINT 八个字节的大整形)
以上这些是不同长度的字节来存储整数,它们所能够表示的整数范围不一样,适合的才是最好的,存储人的年龄应该使用TINYINT, 而且不可能有负数 整形有个修饰符 UNSIGNED 无符号,正数和0
还支持修饰符NOT NULL,不允许为空,
十进制数值型(decimal),也是浮点的,但是里面的数值是精确的,尤其适用于财务计算当中
近似数值型:浮点型
FLOAT 单精度浮点型
DOUBLE 双精度浮点型
日期时间型
DATE 日期型
TIME 时间型
DATETIME 日期时间型
STAMP 时间戳
布尔型: 其实mysql 不止是bool型 真假使用 1 0 来表示 (使用很小的整形来表示 1 0)
内置类型: ENUM 枚举类型 可以定义最多只接受哪几个字符(单个字符?),其它字符都不接受
SET 集合类型 具体怎么用,到时候再说
每一种类型有什么修饰符,有多少个字节,下次再说
内置(是这个数据库独有,其实不能算数据类型了?)
3,类型修饰符 比如定义一个类型是整形,我们要求你必须要在这里面存一个整数,如果用户什么数都没有存,或者存了一个浮点数行不行?不行 类型修饰就是实施的数据约束,限制的功能
4,索引 , 还可以定义索引,索引本身是建在字段上的,跟表本身是没有关系的
DDL 定义数据对象的语言
CREATE
ALTER
DROP
DML 定义数据操纵语言
INSERT
UPDATE
DELETE
DCL 定义数据控制语言
GRANT
REVOKE
这些关键字 命令 不区分大小写,但是我们应该统一使用一种风格,不要一会儿大写,一会儿小写,这很不好,为什么不好?将来会讲到
创建数据库
CREATE DATABASE db_name; (服务器端命令要用分号结尾)
CREATE DATABASE [ IF NOT EXISTS ] db_name; 假如不存在数据库db_name,就创建它
数据库也没有什么需要特别更改的地方,更细节的用法,比如怎么去定义数据库的字符集,排序规则,这些比较麻烦,后面再说
删除数据库
DROP DATABASE [ IF EXISTS ] db_name; 删除数据库db_name, mysql没有回收站的功能,删了后是无法恢复的 [ IF EXISTS ] 表示存在
mysql> create database testdb ;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| test |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
mysql> mysql客户端也有记忆功能的,有命令历史的,用上下箭头可翻出历史命令
mysql> create database testdb; 再执行创建数据库testdb 的命令, 报错(数据库已存在)
ERROR 1007 (HY000): Can't create database 'testdb'; database exists
mysql>
mysql> create database if not exists testdb; 如果不存在数据库testdb,就创建它
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql>
mysql> drop database testdb; 删除数据库,敲回车时,一定要想一想,有没有危险
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql>
创建表
CREATE TABLE tb_name(col1,col2,...);
查看一个数据库中的表
SHOW TABLES from db_name ; (如果不使用from db_name,表示显示默认数据库中的表)
查看某个表的结构 (看表中有几个字段什么的,每个字段的类型限定)
DESC tb_name; DESC可以写成 DESCRIPTION吧
删除表 DROP TABLE tb_name; 记住不可逆,没有回收站,
如果表不存在,直接删除的话,它会报错的
所以 DROP TABLE IF EXISTS tb_name; 如果存在表,才删除
修改表 ALTER TABLE tb_name
MODIFY 修改某个字段的 (字段名不改,改字段的属性类型定义)
CHANGE 改变某个字段的 (字段名称都会改掉的,也同时改字段的属性类型定义,哪怕字段的属性类型定义一样,也要写上去)
ADD 添加一个字段
DROP 删除一个字段
怎么创建键,创建索引,下次再说
DML
INSERT INTO tb_name (col1,col2,......) values|value ('STRING',NUM,...) 插入数据 (关键词 values或value) 插入字符串,一定要用引号引起来 如果表中每一个字段都给它一个值,那么 (col1,col2,......) 可以省略掉
还支持批量插入
INSERT INTO tb_name (col1,col2,......) values|value ('STRING',NUM,...), ('STRING',NUM,...), ('STRING',NUM,...), ('STRING',NUM,...), ('STRING',NUM,...), ('STRING',NUM,...), ('STRING',NUM,...); 批量插入时, 用逗号( , )隔开各个字段集合,最后用分号结束
UPDATE tb_name set column=value WHERE CONDITION 要指定 where条件,不指定条件的话,所有的行都改了 (不使用where 非常危险) where 就是指定过滤条件,指定选择条件的
DELETE FROM tb_name WHERE CONDITION 要指定 where条件,不指定条件的话,所有的行都删除了 (不使用 where 非常危险) where 就是指定过滤条件,指定选择条件的
选择:
SELECT 字段 FROM tb_name WHERE CONDITION 事实上它还有很多其它用法,比如做聚合函数,做having,做group by ,做having再做过滤,有很多的用法
*:所有字段
where: 没有where条件表示显示所有行
选择和投影
选择:指定以某字段做为搜索码,作逻辑比较,筛选符合条件的行,只显示部分行,而不是显示所有行 选择是选择行的
投影: 把一部分字段遮住,只留住了一部分(如果有4个字段,只想显示2个), 投影是选择列的
REPLACE INTO 替换数据 马哥不讲了
创建用户:
CREATE USER 'USERNAME'@'HOST' [ IDENTIFIED BY 'PASSWORD' ]; 创建用户的时候还指定密码 这个用户只能连到mysql上来,其它操作,像做一些查看,像创建数据库等什么权限都没有 (当然创建用户的时候,可以不用加密码的)
DROP USER 'USERNAME'@'HOST'
HOST: 主机表示方法
IP:
HOSTNAME:
NETWORK:
通配符:
_: 下划线表示匹配任意单个字符 172.16.1.__ (两个下划线 表示 10到99都包含进来了? 两位嘛 一般是10到99 ) 172.16.1._(一个下划线,表示1到9)
%: 百分号表示匹配任意长度的任意字符
jerry@'%'表示可以从任意主机上登录;;;;;;;;;;; 当我们使用匹配字符的时候(使用通配符的时候),一定要用引号引起来
jerry@localhost 与 jerry@192.168.1.45 不是同一个用户
DCL
GRANT pri1,pri2,...... ON DB_NAME.TB_NAME TO 'USERNAME'@'HOST' [IDENTIFIED BY 'PASSWORD']; 授权用户权限 (授权给用户的时候,是可以同时改密码的(所以 CREATE USER 命令 是可以不指定密码的))(这里如果用户不存在,会自动调用 CREATE USER 命令创建用户的 )
REVOKE pri1,pri2,...... ON DB_NAME.TB_NAME FROM 'USERNAME'@'HOST' 取消对用户的授权
pri1 权限 比如 (select update delete )
查看用户的授权: SHOW GRANTS FOR 'USERNAME'@'HOST'
ALL PRIVILEGES 表示所有权限
mysql> create table mydb.表名 要用库名.表名,不然程序不知道创建在哪个数据库里面
mysql> use mydb (这是一个客户端命令,可以不用分号;结尾)或者 use mydb 表示设置默认数据库为mydb
Database changed
mysql> (现在就可以不用写mydb了)
mysql> create table students(Name char(20) not null, Age tinyint unsigned,Gender char(1) not null);
ERROR 1005 (HY000): Can't create table 'students' (errno: 13)
(这个错误是因为 我们自己直接创建的一个目录数据库(mkdir mydb),其属主属组是root:root
运行mysql服务器的属主属组是mysql:mysql,所以说是没有权限 ,用create database mydb属主属组就是mysql:mysql了
就有权限了
[root@www mysql]# pwd
/var/lib/mysql
[root@www mysql]# ls -la
总计 20576
drwxr-xr-x 5 mysql mysql 4096 05-21 21:58 .
drwxr-xr-x 29 root root 4096 05-19 21:50 ..
-rw-rw---- 1 mysql mysql 10485760 05-19 21:52 ibdata1
-rw-rw---- 1 mysql mysql 5242880 05-19 21:52 ib_logfile0
-rw-rw---- 1 mysql mysql 5242880 05-19 21:52 ib_logfile1
drwxr-xr-x 2 root root 4096 05-19 22:08 mydb
drwx------ 2 mysql mysql 4096 05-19 21:52 mysql
srwxrwxrwx 1 mysql mysql 0 05-19 21:52 mysql.sock
drwx------ 2 mysql mysql 4096 05-19 21:52 test
[root@www mysql]#
)
mysql>
mysql> select database(); 得到当前的数据库
+------------+
| database() |
+------------+
| mydb |
+------------+
1 row in set (0.00 sec)
mysql>
( 先删掉 mydb这个目录吧
[root@www mysql]# pwd
/var/lib/mysql
[root@www mysql]# rm -rf mydb/
[root@www mysql]#
)
mysql> create database mydb; 再通过命令创建mysql数据库
Query OK, 1 row affected (0.00 sec)
(
[root@www ~]# cd /var/lib/mysql/
[root@www mysql]# pwd
/var/lib/mysql
[root@www mysql]# ls -la
总计 20576
drwxr-xr-x 5 mysql mysql 4096 05-21 22:33 .
drwxr-xr-x 29 root root 4096 05-19 21:50 ..
-rw-rw---- 1 mysql mysql 10485760 05-19 21:52 ibdata1
-rw-rw---- 1 mysql mysql 5242880 05-19 21:52 ib_logfile0
-rw-rw---- 1 mysql mysql 5242880 05-19 21:52 ib_logfile1
drwx------ 2 mysql mysql 4096 05-21 22:33 mydb 可以看到属主属组 mysql:mysql
drwx------ 2 mysql mysql 4096 05-19 21:52 mysql
srwxrwxrwx 1 mysql mysql 0 05-19 21:52 mysql.sock
drwx------ 2 mysql mysql 4096 05-19 21:52 test
[root@www mysql]#
)
mysql>
mysql> use mydb
Database changed
mysql> create table students(Name char(20) not null, Age tinyint unsigned,Gender char(1) not null);
Query OK, 0 rows affected (0.00 sec)
现在成功创建了表
mysql>
mysql> show tables; 现在可以查看表了
+----------------+
| Tables_in_mydb |
+----------------+
| students |
+----------------+
1 row in set (0.00 sec)
mysql>
mysql> desc students; 表名是要区分大小写的,因为表本身要对应单个文件放在数据库目录里面的
+--------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------------+------+-----+---------+-------+
| Name | char(20) | NO | | NULL | |
| Age | tinyint(3) unsigned | YES | | NULL | |
| Gender | char(1) | NO | | NULL | |
+--------+---------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> help create table ( 客户端命令 ) 获取帮助
mysql> help alter table 它比 create table 还要复杂
alter_specification:
table_options
| ADD [COLUMN] col_name column_definition
[FIRST | AFTER col_name ] # FIRST 表示字段放在第一个, AFTER col_name表示放到某个列后面 FIRST, AFTER col_name 是修正字段的位置的 如果不使用 FIRST或 AFTER col_name 就表示这个新添加的列放到表的最后了,作为表的最后一列了
一竖 | 表示或者
CHANGE [COLUMN] old_col_name new_col_name column_definition 改变字段
[FIRST|AFTER col_name]
DROP [COLUMN] col_name 删除字段 删除列名
mysql> alter table students add course varchar(100);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql>
mysql> desc students;
+--------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------------+------+-----+---------+-------+
| Name | char(20) | NO | | NULL | |
| Age | tinyint(3) unsigned | YES | | NULL | |
| Gender | char(1) | NO | | NULL | |
| course | varchar(100) | YES | | NULL | |
+--------+---------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> alter table students change course Course varchar(100) after name; #这里字段定义(字段的属性类型信息),即使不改变,这里照样要写一遍
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql>
mysql> desc students;
+--------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------------+------+-----+---------+-------+
| Name | char(20) | NO | | NULL | |
| Course | varchar(100) | YES | | NULL | |
| Age | tinyint(3) unsigned | YES | | NULL | |
| Gender | char(1) | NO | | NULL | |
+--------+---------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
可以为空的时候,就可以不给数据了,不能为空的时候,就必须给数据
mysql> insert into students (Name,Gender) values ('LingHuchong','M'),('XiaoLongnv','F');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql>
mysql> select * from students;
+-------------+--------+------+--------+
| Name | Course | Age | Gender |
+-------------+--------+------+--------+
| LingHuchong | NULL | NULL | M |
| XiaoLongnv | NULL | NULL | F |
+-------------+--------+------+--------+
2 rows in set (0.00 sec)
mysql>
mysql> insert into students values ('XiaoXiangzi','HaMogong',57,'M');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from students;
+-------------+----------+------+--------+
| Name | Course | Age | Gender |
+-------------+----------+------+--------+
| LingHuchong | NULL | NULL | M |
| XiaoLongnv | NULL | NULL | F |
| XiaoXiangzi | HaMogong | 57 | M |
+-------------+----------+------+--------+
3 rows in set (0.00 sec)
mysql>
mysql> update students set Course='Pixiejianfa' ;
Query OK, 3 rows affected (0.01 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from students;
+-------------+-------------+------+--------+
| Name | Course | Age | Gender |
+-------------+-------------+------+--------+
| LingHuchong | Pixiejianfa | NULL | M |
| XiaoLongnv | Pixiejianfa | NULL | F |
| XiaoXiangzi | Pixiejianfa | 57 | M |
+-------------+-------------+------+--------+
3 rows in set (0.00 sec)
mysql>
mysql> update students set Course='Hamogong' where Name='XiaoXiangzi';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql>
mysql> select * from students;
+-------------+-------------+------+--------+
| Name | Course | Age | Gender |
+-------------+-------------+------+--------+
| LingHuchong | Pixiejianfa | NULL | M |
| XiaoLongnv | Pixiejianfa | NULL | F |
| XiaoXiangzi | Hamogong | 57 | M |
+-------------+-------------+------+--------+
3 rows in set (0.00 sec)
mysql>
mysql> select Name,Course from students;
+-------------+-------------+
| Name | Course |
+-------------+-------------+
| LingHuchong | Pixiejianfa |
| XiaoLongnv | Pixiejianfa |
| XiaoXiangzi | Hamogong |
+-------------+-------------+
3 rows in set (0.00 sec)
mysql>
显示一个表的子集: 下面的查询 既有投影,又有选择
mysql> select Name,Course from students where Gender='M';
+-------------+-------------+
| Name | Course |
+-------------+-------------+
| LingHuchong | Pixiejianfa |
| XiaoXiangzi | Hamogong |
+-------------+-------------+
2 rows in set (0.00 sec)
mysql>
mysql> select * from students;
+-------------+-------------+------+--------+
| Name | Course | Age | Gender |
+-------------+-------------+------+--------+
| LingHuchong | Pixiejianfa | NULL | M |
| XiaoLongnv | Pixiejianfa | NULL | F |
| XiaoXiangzi | Hamogong | 57 | M |
+-------------+-------------+------+--------+
3 rows in set (0.00 sec)
mysql> delete from students where Course='Pixiejianfa';
Query OK, 2 rows affected (0.00 sec)
mysql>
此时看到已经删了两行
mysql> select * from students;
+-------------+----------+------+--------+
| Name | Course | Age | Gender |
+-------------+----------+------+--------+
| XiaoXiangzi | Hamogong | 57 | M |
+-------------+----------+------+--------+
1 row in set (0.00 sec)
mysql>
mysql> create user 'jerry'@'%' identified by 'jerry';
Query OK, 0 rows affected (0.01 sec)
mysql> show grants for 'jerry'@'%'; 看看这个用户有哪些权限
+-----------------------------------------------------------------------------+
| Grants for jerry@% |
+-----------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'jerry'@'%' IDENTIFIED BY PASSWORD '7e82afb618ffeb73' |
+-----------------------------------------------------------------------------+
1 row in set (0.00 sec)
#USAGE 表示只能连到服务器上,别的什么权限也没有
mysql>
mysql> grant all privileges on mydb.* To 'jerry'@'%'; #mydb.* 这里用星号 表示mydb数据库上的所有表 (这里因为 'jerry'@'%'原来已经有密码了,所以 没有 使用 IDENTIFIED BY 来改密码 )
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> show grants for 'jerry'@'%';
+-----------------------------------------------------------------------------+
| Grants for jerry@% |
+-----------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'jerry'@'%' IDENTIFIED BY PASSWORD '7e82afb618ffeb73' |
| GRANT ALL PRIVILEGES ON `mydb`.* TO 'jerry'@'%' |
+-----------------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql>
马哥直接在另外一台新电脑上装上mysql 客户端 (我的另一台电脑装的是服务器端(里面包含客户端))
# yum install mysql
另一台电脑上
我为什么登不上远程的mysql 可是马哥是能够登上的 (把mysql客户端主机的防火墙和myql服务端主机的防火墙全都关掉吧,然后 再看 /node-admin/13658 ) 可以看到 是没有权限看 mysql 这个数据库的(为什么没有授于 test information_schema 权限,却能够看到它们呢?)