大话数据库MySQL项目实战的那几个点

1、MySQL简介

MySQL通常特制完整的MySQLRDBMS,是一个开源的关系型数据库管理系统(Relational Database Management System),如今属于Oracle公司。随着MySQL功能的不断完善,性能不断提升,又有开源免费的优点,愈来愈多的企业选择使用MySQL,而放弃商用收费的Oracle。php

2、MySQL结构

一、逻辑结构mysql

clipboard.png

MySQL采用的是客户/服务器体系结构,所以实际使用时,有两个程序:程序员

  1. 一个是MySQL服务器程序,指的是mysqlId程序,运行在数据库服务器上,负责在网络上监听并处理来自客户端的服务请求根据这些请求去访问数据库的内容,再把有关信息回传给客户;
  2. 另外一个程序是MySQL客户端程序,负责链接到数据库服务器,并经过发出命令来告知服务器它想要的操做。

从下面简单的逻辑图中能够看出,MySQL内部大体分为三层:sql

  1. 最上层是大部分基于网络的C/S服务都有的部分,好比链接处理、受权认证、安全等;
  2. 第二层包括MySQL的不少核心服务功能,包括查询解析、分析、优化、缓存以及全部的内置函数(例如,日期、时间、数学和加密函数),全部的跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。
  3. 第三层包含了存储引擎,存储引擎负责MySQL中欧数据的存储和提取,是数据库中很是重要很是核心的部分,也是MySQL区别与其余数据库的一个重要特性。

不一样的存储引擎有个字的特色,MySQL支持插入式的存储引擎,能够根据实际状况选择最合适的存储引擎。不过目前对于绝大部分应用来讲,MySQL默认的存储引擎InnoDB应该就是其最佳选择。我以为刚开始学习的时候介绍不少不经常使用甚至不会用到的存储引擎虽然可能会横向比较,让开发人员更了解每一个存储引擎的特性,可是这样对开发人员形成的困扰更大,还不如专心学习一种用途最普遍的存储引擎,屏蔽其余干扰,学到必定深度后再了解其余存储引擎的不一样点。数据库

二、体系结构缓存

clipboard.png

具体查看MySQL在物理上的体系结构,从上到下依次是:安全

  1. 链接池组件
  2. 管理服务和工具组件、SQL接口组件、查询分析器组件、优化器组件、缓冲组件
  3. 插件式存储引擎
  4. 物理文件

3、 数据库和实例

区分两个词性能优化

clipboard.png

数据库指物理上的存储文件,实例是用来操做数据库文件的。在MySQL数据库中,实例与数据库一般是一一对应的,这时两个词能够互换,但在集群状况下,可能存在一个数据库被对个数据实例使用的状况.
MySQL是单进程多线程架构的数据库,实例在系统上的表现就是一个进程。服务器

4、MySQL不得不说的八个陷阱

Mysql安装简单,速度较快,功能丰富。另外它仍是开源运动的标杆,它的伟大成就向咱们展现了一个成功的公司是能够创建在开源代码之上的。网络

然而用过mysql的人都曾对着显示器挥舞过拳头。但你不可能发明一种每秒能保存成千上万行互联网数据,而且一点错误都没有的技术吧。

如下列举了8个开源关系型数据库的缺陷,其中不只限于MySQL,还有是针对关系型数据库的。只有明白了关系型数据库和MySQL,才能更好地避免在使用MySQL中尽可能少地遇到一些意外。

一、根深蒂固的bugs

任何大的软件包都有 bug。但稍微深刻了解一下,就会发现和 Mysql 相关的 bugs 自成体系。忽然你就须要留心,由于 NULL 并非以一样的方式出现,外键约束也没有像你想像的那样执行,连主键自动增加也会出错。

小问题大量存在,并且并不老是能够修复,这就是为何一些人保持一个列表。还好 MySQL 维护着一个很是好的 bug 报告系统,让咱们能够知道我些咱们没法想像的事情,知道其余人也在经受一样的磨难。

二、关系表的不灵活性

关系表具备条理性,条理性是好的——可是,它使得程序员不得不编造或硬塞一些数据到已经定义好模式的列中。NoSQL开始愈来愈受到欢迎的缘由之一,就是它为程序员提供了足够的灵活性,来加速数据库的使用。若是一个街道地址须要增长一行,那么,你能够将它很容易地插入到一个NoSQL文档中。若是你想添加一个完整的新的数据块,不管它包含什么内容,文档模型也能够原封不动地接受你的数据,而没必要改成它要求的数据格式。

试想一下,你用整数格式创建了一个所有是邮编的表格。这个表是十分高效的,它执行的规则也很好。忽然一次,有人上传了一个使用了连字符的九位数邮编。或者还有可能,你获得了一位来自加拿大客户的信件,上面写有邮政编码。

这时,一切都乱了。老板要求网站要在几小时内恢复正常工做。然而,如今已经没有时间来重建数据库。程序员能够作什么?也许,能够使用黑客手段把加拿大邮政编码由base64的数字格式改成base 10格式?或者设置一个使用转义编码的辅助表格,用来讲明真正的邮政编码或者其余?谁知道呢?处处都有黑客,他们都是危险的。但你没有时间来搞定它。

MySQL的关联规则让每一个人都诚实和谨慎,但它能强制咱们避开易受攻击和欺骗的麻烦。

三、存储引擎混乱

整体来讲,Mysql的存储引擎接口定义还算良好的。MySQL不是实际上的同一的数据库。它是由几个数据库组成,它们的大多数细节都被统一的表面掩盖了。开始时有一个MyISAM引擎,它很快但在先后一致上不能作到完备。有时你须要速度而且能够接受不一致的结果时是很好的。

当人们须要更多时,具有完整事务支持的Inno DB出现了。但这还不够。如今,它可能有20种存储引擎的选择——这足以使一个数据库管理员疯狂。固然,有时在不一样的存储引擎之间切换而没必要重写你的SQL是很好的,可是切换后总会带来混乱。这个表格我选择的引擎是MyISAM仍是innoDB呢?或者,我决定输出的数据是CSV格式的吗?

四、JOIN联合查询

曾经,将数据分表保存是计算机科学史上的伟大创新。分开后的表不只结构简单,使用上也简化了许多。但它却须要使用join语句来进行查询。

sql经过一系列join构建的复杂查询将开发者推入了困惑与绝望的深渊。并且存储引擎也须要以最优的方式来高效地解析join语句。开发者须要绞尽脑汁编写查询语句,而后数据库对其进行解析。

这就是不少注重运行速度的开发者放弃数据分表转而使用不规范数据表的缘由。不区分数据实体,将全部数据保存到一个大表中——以免复杂的查询。这样确实很快,而且服务器也不会耗尽内存。

如今的磁盘空间很廉价。8TB的磁盘已经在售,更大容量的也将上市。咱们再也不须要为使用join而绞尽脑汁了。

五、分支的混乱

毋庸置疑,一个可靠的、获得良好支持的MySQL分支,能够带来竞争和选择,可是它也引发困惑和混乱。更糟糕的是,一个称为MariaDB的MySQL分支,由Monty Widenius维护着。他一样也在参与编写MySQL。那么,Maria DB是真正独立的值得咱们拥护的吗?或者它是MySQL?咱们是否应该坚持使用由建立原始mysql数据库的组织运营的核心代码?或者咱们应该加入那些被认为更聪明的,每每很酷的背叛者?

如何获取关于兼容性的信息?虽然Maria DB和MySQL十分类似,但它们之间也有差别。这就是你们一直都在争论它的缘由。在性能方面,在咱们查询的范围内,在两个阵营中,也许它们的工做方式相同,但也许不一样,也许未来会不一样。

六、开发MySQL的动机

虽然MySQL是一款成功的开源产品,但它仍属于商业中的一款产品,专业开发者须要靠它来得到利益,固然,最直接的利益就是薪资。当大多数用户在持续地享受开源许可证带来的最佳体验时,毫无疑问这家公司还在为赚取足够的钱来维持运营而努力。这致使自由代码在“社区版”和出售给企业的完整产品之间产生了奇怪的分岐。

咱们应该对这款产品付钱吗?这种在社区版开展经营的行为是否公平?企业版中额外的功能是否是一个噱头,以引诱咱们不断付费的呢?这至少说明一点,它是另外一些须要回答的问题:选用哪一个版本?遵守哪一种许可证?选用它的哪一个功能集?

七、原生JSON支持的缺少

经过安装MySQL查看其年龄,而后你就知道须要添加哪些驱动程序使它变得可用。MySQL一般在3306端口上通讯,通常输出的是它自己难以理解的格式化数据。若是要让你的代码和它通讯,你必须添加另外一层代码,将MySQL的语言转换成有用的东西。这些层的代码,以库的形式分发,常常须要人们购买一个商业许可证。

现代数据存储层一般直接以JSON通讯。虽然MySQL和Maria DB如今有能力解析SQL中的JSON部分,但这还远远不够,原生的JSON接口已经被普遍使用于CouchDB、MongoDB,或任何最新的工具中。

八、封闭源和专有模块的兴起

虽然MySQL是开源的,但除了一些在”开源核心“周边开发的一些较新的、非开源的代码和专有模块。程序员也须要赚钱、须要生活,Oracle须要拿它的辛苦成果来换钱,这是一种现实,也是商业的性质。使用MySQL你也不能够免费获得任何东西。

要求MySQL始终坚持在一个很高的标准上,这有点不公平,由于开源的成功多是一个圈套。它开始能够免费,但并不意味着它能够始终免费。若是企业须要更多新的功能,他们就要经过各类方式付费来获取。有时向Oracle付费,比本身来编写代码要便宜得多。有时商业的、不开源的代码是有意义的。

MySQL虽然做为一个成功的开源系统,但以上这些问题也总不可避免地出现,这就须要咱们在它们发生以前有个深入的认识,才能在从此的应用中避免没必要要的麻烦。

在此我向你们推荐一个架构学习交流群。交流学习群号:575745314 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

5、MySQL分布式集群搭建

1 准备集群搭建环境

使用6台虚拟机来搭建MYSQL集群,相应的实验环境与对应的MYSQL节点之间的对应关系以下图所示:

clipboard.png

管理节点(MGM):这类节点的做用是管理MySQLCluster内的其余节点,如提供配置数据,并中止节点,运行备份等。因为这类节点负责管理其余节点的配置,应该在启动其余节点以前启动这类节点。MGM节点是用命令“ndb_mgmd”启动的;

数据节点(NDB):这类节点用于保存Cluster的数据,数据节点的数目与副本的数目相关,是片断的倍数。例如,对于两个副本,每一个副本有两个片断,那么就有4个数据节点,没有必要设定过多的副本,在NDB中数据会尽可能的保存在内存中。数据节点使用命令“ndb”启动的;

SQL节点:这是用来访问Cluster数据的节点,对于MySQL Cluster,客户端节点是使用NDB Cluster存储引擎的传统MySQL服务器。一般,SQL节点使用命令“mysqld-ndbcluster”启动的;

二、准备安装包

在官网上下载mysql的安装包: mysql-cluster-gpl-7.4.11-Linux-glibc2.5-x86_64.tar.gz,并进行解压。

三、集群搭建流程

1]将上述安装包解压出来的文件都移到/usr/local/mysql下;

2]运行script目录下的mysql-install-db.sh脚本,运行命令为./mysql-install-db.sh --user=root--basedir =/usr/local/mysql --datadir=/usr/local/mysql;注意其中用户为root的名称须要跟配置文件my.cnf中的相同;

在管理节点,数据节点,SQL节点上都执行上述安装命令,从而完成对mysql的安装;

四、集群配置与启动

1]在管理节点上须要完成对于集群总体的配置配置:在/var/lib/mysql-cluster/config.ini中实现以下的配置信息:

clipboard.png

2]在数据节点中须要在my.cnf中完成对于数据节点的相关配置信息,以下:

clipboard.png

须要指明配置的数据节点的根目录,数据目录,socket链接配置,用户配置,以及对应的管理节点的ip地址配置;将配置完成的配置文件移动到/etc/my.cnf,完成;

3]在SQL节点上完成对于SQL节点的配置信息,一样的是在my.cnf中完成相应配置信息,并将配置文件移动到/etc/my.cnf中,相应的配置信息的设定以下所示:

clipboard.png

完成以上配置后,就能够启动集群中的各个节点了。

五、集群启动

在启动mysql集群的时候,注意首先要启动管理节点,并依次启动其余等若干个节点,相应的启动步骤以下:

1]在管理节点上,切换到/usr/local/mysql/bin目录下,执行ndb_mgmd -f /var/lib/mysql-cluster/config.ini命令,完成管理节点的启动;

2]在各个数据节点上,切换到/usr/local/mysql/bin目录下,执行ndbd --initial(第一次启动时,不然执行ndbd便可),完成对数据节点的启动;

3]在各个SQL节点上,一样切换到/usr/local/mysql/bin目录下,执行mysqld_safe --user=root完成启动;

4]在管理节点上运行ndb_mgm命令,进入数据库管理的客户端,输入show命令,查看与之相链接的各个节点的状态;

5]在SQL节点上分别进入系统的安全状态,并完成对root用户的密码修改,运行如下指令,进行密码修改:

A use mysql,切换到mysql数据库;

B UPDATE user SET Password = PASSWORD('123456')WHERE user = 'root';从而实现对root密码的修改;

C flush privilege,完成修改;

6]修改使得任意主机都能连得上mysql,进行以下修改,一样安装第5步进入安全模式,并完成相应的修改,以下:

grant all on‘.’to ‘root@'%' identified by '123456';

这样就能够使得任意一个主机均可以经过root用户来登陆mysql了;

六、集群测试

在集群上的一个SQL节点上执行建立数据库,并建立一张表,并完成相应的数据插入,以下:

A create database ctest; //建立数据库

B create table test(

id int primarykey; //建立一张表

);

C insert into test (id)values(1); //完成数据插入

登陆另一个SQL节点,并执行SQL查询操做,看数据库中是否已经有数据,以下:

select * from ctest;

若是有数据,表示数据插入成功;

七、关闭集群

1]首先关闭管理节点和数据节点,须要在管理节点上执行命令,以下:./ndb_mgm -e shutdown;

2]而后关闭SQL节点,在SQL节点上执行命令/usr/local/mysql/support-fies/mysql.server stop(其中/usr/local/mysql/是mysql的安装目录).从而关闭SQL节点

在此我向你们推荐一个架构学习交流群。交流学习群号:575745314 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

clipboard.png

6、MySQL 的最佳实践

数据库操做是当今 Web 应用程序中的主要瓶颈。 不只是 DBA(数据库管理员)须要为各类性能问题操心,程序员为作出准确的结构化表,优化查询性能和编写更优代码,也要费尽心思。 在本文中,我列出了一些针对程序员的 MySQL 优化技术。

在咱们开始学习以前,我补充一点:你能够在 Envato Market 上找到大量的 MySQL 脚本和实用程序。

clipboard.png

1.优化查询的查询缓存

大部分MySQL服务器都有查询缓存功能。这是提升性能的最有效的方法之一,这是由数据库引擎私下处理的。当同一个查询被屡次执行,结果会直接从缓存里提取,这样速度就很快。

主要的问题是,这对程序员来讲太简单了,不容易看到,咱们不少人都容易忽略。咱们其实是能够组织查询缓存执行任务的。

clipboard.png

查询缓存在第一行不执行的缘由在于CURDTE()功能的使用。这适用于全部的非肯定性功能,就像NOW()和RAND()等等。。。由于功能返回的结果是可变的。MySQL决定禁用查询器的查询缓存。咱们所须要作的是经过添加一额外一行PHP,在查询前阻止它发生。

2. EXPLAIN你的选择查询

使用EXPLAIN关键词能够帮助了解MySQL是怎样运行你的查询的。这有助于发现瓶颈和查询或表结构的其它问题。

EXPLAIN的查询结果会展现哪个索引被使用过,表示怎样扫描和储存的,等等。。。

选择一个SELECT查询(一个有链接的复杂查询会更好),在它的前面添加关键词EXPLAIN,这样就能够直接使用数据库了。结果会以一个漂亮的表来展现。例如,就比如我执行链接时忘了添加一栏的索引:

clipboard.png

如今它只会从表2里面扫描9和16行,而非扫描7883行。经验法则是乘以全部“行”那一栏的数字,你的查询性能会跟结果数字成比例的。

3. 获取惟一行时使用LIMIT 1

有时当你查表时,你已经知道你正在查找的结果只有一行。你可能正在获取惟一记录,或者你可能只是查询是否存在知足你的WHERE子句条件的记录。

在这种状况下,将LIMIT 1添加到查询条件中能够提升性能。这样,数据库引擎将在找到刚刚第一个记录以后中止扫描记录,而不是遍历整个表或索引。

clipboard.png

4. 索引搜索字段

索引不只仅是为了主键或惟一键。若是你会在你的表中按照任何列搜索,你就都应该索引它们。

clipboard.png

正如你所看到的,这个规则也适用于如 “last_name LIKE ‘a%’”的部分字符串搜索。当从字符串的开头搜索时,MySQL就能够使用那一列的索引。

你也应该明白什么样搜索能够不使用有规律的索引。例如,当搜索一个单词时(例如,”WHERE post_content LIKE ‘%apple%’”),你将不会看到普通索引的好处。你最好使用 mysql 全文搜索或者构建你本身的索引解决方案。

5. 索引并对链接使用一样的字段类型

若是你的应用程序包含许多链接查询, 你须要确保链接的字段在两张表上都创建了索引。 这会影响MySQL如何内部优化链接操做。

此外,被链接的字段,须要使用一样类型。例如, 若是你使用一个DECIMAL字段, 链接另外一张表的INT字段, MySQL将没法使用至少一个索引。 即便字符编码也须要使用相同的字符类型。

clipboard.png

6. 不要ORDER BY RAND()

起初这是一个听起来挺酷的技巧, 让许多菜鸟程序员陷入了这个陷阱。但你可能不知道,一旦你开始在查询中使用它,你建立了很是可怕的查询瓶颈。

若是你真的须要对结果随机排序, 这有一个更好的方法。补充一些额外代码,你将能够防止当数据成指数级增加时形成的瓶颈。关键问题是,MySQL必须在排序以前对表中的每一行执行RAND()操做(这须要处理能力),而且仅仅给出一行。

clipboard.png

因此挑选一个小于结果数的随机数,并将其用做LIMIT子句中的偏移量。

7. 避免使用SELECT *

从数据表中读取的数据越多,查询操做速度就越慢。它增长了磁盘操做所需的时间。此外,当数据库服务器与Web服务器分开时,因为必须在服务器之间传输数据,将会有更长的网络延迟。

这是一个好习惯:当你使用SELECT语句时老是指定你须要的列。

clipboard.png

8. 几乎老是有一个id字段

在每一个以id列为PRIMARY KEY的数据表中,优先选择AUTO_INCREMENT或者INT。 也能够优选使用UNSIGNED,由于该值不能为负的。

即便你拥有一个具备惟一用户名字段的用户表,也不要将其做为主键。 VARCHAR字段做为主键(检索)速度较慢。经过内部ID引用全部的用户数据,你的代码中将更加结构化。

有些后台操做是由MySQL引擎自己完成的,它在内部使用主键字段。当数据库设置越复杂(集群,分区等…),这就变得更加剧要了。

这个规则的一个可能的例外是“关联表”,用于两个表之间的多对多类型的关联。例如,“posts_tags”表中包含两列:post_id,tag_id,用于保存表名为“post”和“tags”的两个表之间的关系。这些表能够具备包含两个id字段的PRIMARY键。

9. 相比VARCHAR优先使用ENUM

ENUM枚举类型是很是快速和紧凑的。在内部它们像TINYINT同样存储,但它们能够包含和显示字符串值。这使他们成为某些领域的完美候选。

若是有一个字段只包含几种不一样的值,请使用ENUM而不是VARCHAR。例如,它能够是名为“status”的列,而且只包含诸如“active”,“inactive”,“pending”,“expired”等的值…

关于如何重构你的数据表,甚至有一种方法是能够从MySQL自己获得“建议”。 当你有一个VARCHAR字段,它实际上建议你将该列类型更改成ENUM。这经过调用PROCEDURE ANALYZE()来完成。

在此我向你们推荐一个架构学习交流群。交流学习群号:575745314 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

10. 使用PROCEDURE ANALYSE()获取建议

PROCEDURE ANALYSE() 将使用MySQL分析列结构和表中的实际数据,为你提供一些建议。它只有在数据表中有实际数据时才有用,由于这在分析决策时很重要。

例如,若是你建立了一个INT类型的主键,但没有太多行,MySQL则可能建议您改用MEDIUMINT。或者若是你使用VARCHAR字段,若是表里只有不多的取值,你可能会获得一个建议是将其转换为ENUM。

你也能够在其中一个表视图中单击phpmyadmin中的“建议表结构”连接来执行此操做。

clipboard.png

请记住,这些只是建议。 若是你的数据表变得愈来愈大,他们甚至可能不是正确的建议。至于如何修改最终是你来决定。

11. 若是能够的话使用NOT NULL

除非你有很是重要的理由使用NULL值,不然你应该设置你的列为NOT NULL。

首先,问一下你本身在空字符串值和NULL值之间(对应INT字段:0 vs. NULL)是否有任何的不一样.若是没有理由一块儿使用这两个,那么你就不须要一个NULL字段(你知道在Oracle中NULL和空字符串是同样的吗?)。

NULL列须要额外的空间,他们增长了你的比较语句的复杂度。若是能够的话尽可能避免它们。固然,我理解一些人,他们也许有很是重要的理由使用NULL值,这不老是一件坏事。
摘自MySQL 文档:

“行空列须要额外的空间来记录它们的值是否为空。 对于MyISAM表,每一个NULL列须要一点额外的,围捕到最近的字节”。

12. 预处理语句

使用预处理语句有诸多好处,包括更高的性能和更好的安全性。

预处理语句默认状况下会过滤绑定到它的变量,这对于避免SQL注入攻击极为有效。固然你也能够指定要过滤的变量。但这些方法更容易出现人为错误,也更容易被程序员遗忘。这在使用框架或 ORM 的时候会出现一些问题。

既然咱们关注性能,那就应该说说这个方面的好处。当在应用中屡次使用同一个查询的时候,它的好处特别明显。既然向同一个预备好的语句中传入不一样的参数值,MySQL 对这个语句也只会进行一次解析。

同时,最新版本的 MySQL 在传输预备好的语句时会采用二进制形式,这样作的做用很是明显,并且对减小网络延迟颇有帮助。

曾经有一段时间,许多程序员为了一个重要的缘由则避免使用预处理语句。这个缘由就是,它们不会被MySQL 缓存。不过在 5.1 版本的某个时候,查询缓存也获得的支持。

想在 PHP 中使用预处理语句,你能够看看 mysqli 扩展 或使用数据抽象层,如 PDO。

clipboard.png

13. 无缓冲查询

一般当你从脚本执行一个查询,在它能够继续后面的任务以前将须要等待查询执行完成。你能够使用无缓冲的查询来改变这一状况。
在PHP 文档中对 mysql_unbuffered_query() f函数有一个很好的解释:

“mysql_unbuffered_query()发送SQL查询查询MySQL没有自动抓取和缓冲结果行mysql_query()。
这节省了大量的内存生产大型结果集的SQL查询,你能够在结果集后当即开始工做第一行被检索到的是你没必要等到完整的SQL查询已经完成。”

然而,它有必定的局限性。你必须在执行另外一个查询以前读取全部的行或调用mysql_free_result() 。另外你不能在结果集上使用mysql_num_rows() 或 mysql_data_seek() 。

14. 使用 UNSIGNED INT 存储IP地址

不少程序员没有意识到能够使用整数类型的字段来存储 IP 地址,因此一直使用 VARCHAR(15) 类型的字段。使用 INT 只须要 4 个字节的空间,并且字段长度固定。

必须确保列是 UNSINGED INT 类型,由于 IP 地址可能会用到 32 位无符号整型数据的每个位。

在查询中能够使用 INET_ATON() 来把一个IP转换为整数,用 INET_NTOA() 来进行相反的操做。在 PHP 也有相似的函数,ip2long() 和 long2ip()。

clipboard.png

15. 固定长度(静态)的表会更快

(译者注:这里提到的表的长度,实际是指表头的长度,即表中每条数据占用的空间大小,而不是指表的数据量)

若是表中全部列都是“固定长度”,那么这个表被认为是“静态”或“固定长度”的。不固定的列类型包括 VARCHAR、TEXT、BLOB等。即便表中只包含一个这些类型的列,这个表就再也不是固定长度的,MySQL 引擎会以不一样的方式来处理它。
固定长度的表会提升性能,由于 MySQL 引擎在记录中检索的时候速度会更快。若是想读取表中的某一地,它能够直接计算出这一行的位置。若是行的大小不固定,那就须要在主键中进行检索。

它们也易于缓存,崩溃后容易重建。不过它们也会占用更多空间。例如,若是你把一个 VARCHAR(20) 的字符改成 CHAR(20) 类型,它会老是占用 20 个字节,无论里面存的是什么内容。

你能够使用“垂直分区”技术,将长度变化的列拆分到另外一张表中。来看看:

16. 垂直分区

垂直分区是为了优化表结构而对其进行纵向拆分的行为。

示例 1: 你可能会有一张用户表,包含家庭住址,而这个不是一个经常使用数据。这时候你能够选择把表拆分开,将住址信息保存到另外一个表中。这样你的主用户表就会更小。如你所知,表越小越快。

示例 2: 表中有一个 “last_login” 字段,用户每次登陆网站都会更新这个字段,而每次更新都会致使这个表缓存的查询数据被清空。这种状况下你能够将那个字段放到另外一张表里,保持用户表更新量最小。

不过你也须要确保不会常常联合查询分开后的两张表,要否则你就得忍受由这带来的性能降低。

17. 拆分大型DELETE或INSERT语句

若是你须要在网站上执行大型DELETE或INSERT查询,则须要注意不要影响网络流量。当执行大型语句时,它会锁表并使你的Web应用程序中止。

Apache运行许多并行进程/线程。 所以它执行脚本效率很高。因此服务器不指望打开过多的链接和进程,这很消耗资源,特别是内存。

若是你锁表很长时间(如30秒或更长),在一个高流量的网站,会致使进程和查询堆积,处理这些进程和查询可能须要很长时间,最终甚至使你的网站崩溃。

若是你的维护脚本须要删除大量的行,只需使用LIMIT子句,以免阻塞。

clipboard.png

18.越少的列越快

对于数据库引擎,磁盘多是最重要的瓶颈。更小更紧凑的数据、减小磁盘传输量,一般有助于性能提升。

MySQL文档Storage Requirements 有全部数据类型清单。

若是已知表具备不多的行,则没有理由是主键类型为INT,能够用MEDIUMINT、SMALLINT代替,甚至在某些状况下使用TINYINT。 若是不须要完整时间记录,请使用DATE而不是DATETIME。

确保留下合理的扩展空间,否则你可能会像Slashdot这样。

19. 选择正确的存储引擎

MySQL有两个主要存储引擎,MyISAM和InnoDB。 每一个都有本身的优势和缺点。

MyISAM适用于读取繁重的应用程序,可是当有不少写入时它不能很好地扩展。 即便你正在更新一行的一个字段,整个表也被锁定,而且在语句执行完成以前,其余进程甚至没法读取该字段。 MyISAM在计算SELECT COUNT(*)的查询时很是快。

InnoDB是一个更复杂的存储引擎,对于大多数小的应用程序,它比MyISAM慢。 但它支持基于行的锁定,使其更好地扩展。 它还支持一些更高级的功能,好比事务。
● MyISAM存储引擎
● InnoDB存储引擎

20. 使用对象关系映射器(ORM, Object Relational Mapper)

经过使用ORM(对象关系映射器),你能够得到必定的性能提高。ORM能够完成的一切事情,手动编码也可完成。但这可能意味着须要太多额外的工做,而且须要高水平的专业知识。

ORM以“延迟加载”著称。这意味着它们仅在须要时获取实际值。可是你须要当心处理他们,不然你可能最终建立了许多微型查询,这会下降数据库性能。

ORM还能够将多个查询批处理到事务中,其操做速度比向数据库发送单个查询快得多。

目前我最喜欢的PHP-ORM是Doctrine。我写了一篇关于如何安装Doctrine与CodeIgniter的文章(install Doctrine with CodeIgniter)。

21. 当心使用持久链接

持久链接意味着减小重建链接到MySQL的成本。 当持久链接被建立时,它将保持打开状态直到脚本完成运行。 由于Apache重用它的子进程,下一次进程运行一个新的脚本时,它将重用相同的MySQL链接。

clipboard.png

理论上看起来不错。 但从我我的(和许多其余人)的经验看来,这个功能可能会致使更多麻烦。 你可能会出现链接数限制问题、内存问题等等。

Apache老是并行运行的,它建立许多子进程。 这是持久链接在这种环境中不能很好工做的主要缘由。 在你考虑使用mysql_pconnect()以前,请咨询你的系统管理员。

相关文章
相关标签/搜索