你的位置:首页 > 数据库

[数据库]MySQL存储引擎,优化,事务


1唯一约束unique和主键key的区别?

 

 

1、什么是数据的存储引擎?

      存储引擎就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。因为在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类型(即存储和操作该表的类型),在Oracle和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的。而MySQL数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据自己的需求编写自己的存储引擎。
MySql中有哪些存储引擎?
     1 MyISAM:这种引擎是mysql最早提供的。这种引擎又可以分为静态MyISAM、动态MyISAM 和压缩MyISAM三种:
    静态MyISAM:如果数据表中的各数据列的长度都是预先固定好的,服务器将自动选择这种表类型。因为数据表中每一条记录所占用的空间都是一样的,所以这种表存取和更新的效率非常高。当数据受损时,恢复工作也比较容易做。
    动态MyISAM:如果数据表中出现varchar、xxxtext或xxxBLOB字段时,服务器将自动选择这种表类型。相对于静态MyISAM,这种表存储空间比较小,但由于每条记录的长度不一,所以多次修改数据后,数据表中的数据就可能离散的存储在内存中,进而导致执行效率下降。同时,内存中也可能会出现很多碎片。因此,这种类型的表要经常用optimize table 命令或优化工具来进行碎片整理。
    压缩MyISAM:以上说到的两种类型的表都可以用myisamchk工具压缩。这种类型的表进一步减小了占用的存储,但是这种表压缩之后不能再被修改。另外,因为是压缩数据,所以这种表在读取的时候要先时行解压缩。
    但是,不管是何种MyISAM表,目前它都不支持事务,行级锁和外键约束的功能。
    2 MyISAM Merge引擎:这种类型是MyISAM类型的一种变种。合并表是将几个相同的MyISAM表合并为一个虚表。常应用于日志和数据仓库。
    3 InnoDB:InnoDB表类型可以看作是对MyISAM的进一步更新产品,它提供了事务、行级锁机制和外键约束的功能。
    4 memory(heap):这种类型的数据表只存在于内存中。它使用散列索引,所以数据的存取速度非常快。因为是存在于内存中,所以这种类型常应用于临时表中。
    5 archive:这种类型只支持select 和 insert语句,而且不支持索引。常应用于日志记录和聚合分析方面。
2、各种存储引擎特性比较:

在实际工作中,选择一个合适的存储引擎是一个很复杂的问题。每种存储引擎都有各自的优势,不能笼统的说谁比谁更好。下面将详解不同环境经常用到的存储引擎和针对各个存储引擎的特点进行对比,给出不同的选择建议。

  • InnoDB存储引擎

InnoDB是Mysql数据库的一种存储引擎。InnoDB给Mysql的表提供了 事务、回滚、崩溃修复能力、多版本并发控制的事务安全、间隙锁(可以有效的防止幻读的出现)、支持辅助索引、聚簇索引、自适应hash索引、支持热备、行级锁。还有InnoDB是Mysql上唯一一个提供了外键约束的引擎。

InnoDB存储引擎中,创建的表的表结构是单独存储的并且存储在.frm文件中。数据和索引存储在一起的并且存储在表空间中。但是默认情况下mysql会将数据库的所有InnoDB表存储在一个表空间中的。其实这种方式管理起来非常的不方便而且还不支持高级功能所以建议每个表存储为一个表空间实现方式为:使用服务器变量innodb_file_per_table = 1。

如果需要频繁的进行更新、删除操作的数据库也可选择InnoDB存储引擎。因为该存储引擎可以实现事务提交和回滚。

  • MyISAM存储引擎

MyISAM存储引擎是Mysql中常见的存储引擎,MyISAM存储引擎是基于ISAM存储引擎发展起来的。MyISAM支持全文索引、压缩存放、空间索引(空间函数)、表级锁、延迟更新索引键。但是MyISAM不支持事务、行级锁、更无法忍受的是崩溃后不能保证完全恢复(只能手动修复)。

MyISAM存储引擎的表存储成3个文件。文件的名字和表的名字相同。扩展名包含frm、MYD、MYI。其中frm为扩展名的文件存储表的结构;MYD为扩展名的文件存储数据,其是MYData的缩写;MYI为扩展名的文件存储索引,其为MYIndex的缩写。

MyISAM存储引擎的插入数据很快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM存储引擎能够实现处理的高效率。如果应用的完整性、并发性要求很低,也可以选择MyISAM存储引擎。

  • ARCHIVE

ARCHIVE,见名之意可看出是归档,所以归档之后很多的高级功能就不再支持了仅支持插入(insert)和查询(select)两种功能, ARCHIVE存储引擎之前还不支持索引(在Mysql5.5以后开始支持索引了),但是它拥有很好的压缩机制。通常用于做仓库使用。

ARCHIVE存储引擎适用于存储日志信息或其他按时间序列实现的数据采集类的应用场景中。

  • CSV

CSV是将数据文件保存为CSV格式的的文件的,可以方便的导入到其他数据库中去(例如:excel表格,SQLserver等等),由此需要在数据库间自由共享数据时才偶尔建议使用此存储引擎。并且它也不支持索引;个人认为仅适用于数据交换。

  • BLACKHOLE

BLACKHOLE叫做黑洞,也就是说没有存储机制,任何数据都会被丢弃,但是会记录二进制日志。一般在Mysql复制(中继服务器)中经常用到,这个在Mysql复制博客中将详细介绍,敬请关注。

  • FEDERATED

FEDERATED可以实现跨服务器整理表,简单说就是它可以访问远程服务器上数据的存储引擎,所以说它不再本地创建数据只会自动的建立一个连接到其他服务器上链接,有点类似于代理的功能,默认都是禁用的。

  • MEMORY存储引擎

MEMORY存储引擎是Mysql中的一类特殊的存储引擎。其使用存储在内存中的内存来创建表,而且所有数据保存在内存中。数据安全性很低,但是查找和插入速度很快。如果内存出现异常就会影响到数据的完整性,如果重启或关机,表中的所有数据就会丢失,因此基于MEMORY存储引擎的表的生命周期很短,一般都是一次性的。适用于某些特殊场景像查找和映射,缓存周期性的聚合数据等等。

  • MRG_MYISAM

MRG_MYISAM存储引擎是合并MyISAM表的,就是将多个MyISAM合并为一个(在用户看来是一个进行工作,其实是多个底层物理文件在运行工作)。


来源: http://blog.jobbole.com/94385/

锁定

  数据库引擎中的锁定功能决定了如何管理信息的访问和更新。当数据库中的一个对象为信息更新锁定了,在更新完成之前,其它处理不能修改这个数据(在某些情况下还不允许读这种数据)。

  锁定不仅影响许多不同的应用程序如何更新数据库中的信息,而且还影响对那个数据的查询。这是因为查询可能要访问正在被修改或者更新的数据。总的来说,这种延迟是很小的。大多数锁定机制主要是为了防止多个处理更新同一个数据。由于向数据中插入信息和更新信息这两种情况都需要锁定,你可以想象,多个应用程序使用同一个数据库可能会有很大的影响。

  不同的存储引擎在不同的对象级别支持锁定,而且这些级别将影响可以同时访问的信息。得到支持的级别有三种:表锁定、块锁定和行锁定。支持最多的是表锁定,这种锁定是在MyISAM中提供的。在数据更新时,它锁定了整个表。这就防止了许多应用程序同时更新一个具体的表。这对应用很多的多用户数据库有很大的影响,因为它延迟了更新的过程。

  页级锁定使用Berkeley DB引擎,并且根据上载的信息页(8KB)锁定数据。当在数据库的很多地方进行更新的时候,这种锁定不会出现什么问题。但是,由于增加几行信息就要锁定数据结构的最后8KB,当需要增加大量的行,也别是大量的小型数据,就会带来问题。

  行级锁定提供了最佳的并行访问功能,一个表中只有一行数据被锁定。这就意味着很多应用程序能够更新同一个表中的不同行的数据,而不会引起锁定的问题。只有InnoDB存储引擎支持行级锁定。

来源: http://blog.csdn.net/koudaidai/article/details/7495738

 

*修改存储引擎,可以用命令Alter table tableName engine =engineName

假如,若需要将表user的存储引擎修改为archive类型,则可使用命令alter table user engine=archive。

*创建数据库表时设置存储存储引擎的基本语法是:
Create table tableName(
columnName(列名1)  type(数据类型)  attri(属性设置),
columnName(列名2)  type(数据类型)  attri(属性设置),
……..) engine = engineName

事物:

 

何为数据库事务 “一荣俱荣,一损俱损”这句话很能体现事务的思想,很多复杂的事物要分步进行,但它们组成一个整体,要么整体生效,要么整体失效。这种思想反映到数据库上,就是多个SQL语句,要么所有执行成功,要么所有执行失败。 数据库事务有严格的定义,它必须同时满足四个特性:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)和持久性(Durabiliy),简称为ACID。下面是对每个特性的说明: 1. 原子性:表示组成一个事务的多个数据库操作是一个不可分隔的原子单元,只有所有的操作执行成功,整个事务才提交,事务中任何一个数据库操作失败,已经执行的任何操作都必须撤销,让数据库返回到初始状态; 2. 一致性:事务操作成功后,数据库所处的状态和它的业务规则是一致的,即数据不会被破坏。如从A账户转账100元到B账户,不管操作成功与否,A和B的存款总额是不变的; 3. 隔离性:在并发数据操作时,不同的事务拥有各自数据空间,它们的操作不会对对方产生干扰。准确的说,并非要求做到完全无干扰,数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性越好,但并发性越弱; 4. 持久性:一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证能够通过某种机制恢复数据。
在这些事务特性中,数据“一致性”是最终目标,其它的特性都是为达到这个目标的措施、要求或手段。 数据库管理系统一般采用重执行日志保证原子性、一致性和持久性,重执行日志记录了数据库变化的每一个动作,数据库在一个事务中执行一部分操作后发生错误退出,数据库即可以根据重执行日志撤销已经执行的操作。此外,对于已经提交的事务,即使数据库崩溃,在重启数据库时也能够根据日志对尚未持久化的数据进行相应的重执行操作。
和Java程序采用对象锁机制进行线程同步类似,数据库管理系统采用数据库锁机制保证事务的隔离性。当多个事务试图对相同的数据进行操作时,只有持有锁的事务才能操作数据,直到前一个事务完成后,后面的事务才有机会对数据进行操作。Oracle数据库还使用了数据版本的机制,在回滚段为数据的每个变化都保存一个版本,使数据的更改不影响数据的读取。

数据并发的问题     一个数据库可能拥有多个访问客户端,这些客户端都可以并发方式访问数据库。数据库中的相同数据可能同时被多个事务访问,如果没有采取必要的隔离措施,就会导致各种并发问题,破坏数据的完整性。这些问题可以归结为5类,包括3类数据读问题(脏读、幻象读和不可重复读)以及2类数据更新问题(第一类丢失更新和第二类丢失更新)。下面,我们分别通过实例讲解引发问题的场景。

脏读(dirty read)     在讲解脏读前,我们先讲一个笑话:一个有结巴的人在饮料店柜台前转悠,老板很热情地迎上来:“喝一瓶?”,结巴连忙说:“我…喝…喝…”,老板麻利地打开易拉罐递给结巴,结巴终于憋出了他的那句话:“我…喝…喝…喝不起啊!”。在这个笑话中,饮料店老板就对结巴进行了脏读。 A事务读取B事务尚未提交的更改数据,并在这个数据的基础上操作。如果恰巧B事务回滚,那么A事务读到的数据根本是不被承认的。来看取款事务和转账事务并发时引发的脏读场景:

时间转账事务A取款事务B
T1 开始事务
T2开始事务 
T3     查询账户余额为1000元    
T4        取出500元把余额改为500元
T5查询账户余额为500元(脏读) 
T6 撤销事务余额恢复为1000元
T7汇入100元把余额改为600元 
T8提交事务 

在这个场景中,B希望取款500元而后又撤销了动作,而A往相同的账户中转账100元,就因为A事务读取了B事务尚未提交的数据,因而造成账户白白丢失了500元。在Oracle数据库中,不会发生脏读的情况。

不可重复读(unrepeatable read)    不可重复读是指A事务读取了B事务已经提交的更改数据。假设A在取款事务的过程中,B往该账户转账100元,A两次读取账户的余额发生不一致:

 

时间取款事务A转账事务B
T1 开始事务
T2开始事务                          
T3                              查询账户余额为1000元     
T4查询账户余额为1000元                          
T5                  取出100元把余额改为900元
T6 提交事务                  
T7查询账户余额为900元(和T4读取的不一致) 

在同一事务中,T4时间点和T7时间点读取账户存款余额不一样。

幻象读(phantom read)     A事务读取B事务提交的新增数据,这时A事务将出现幻象读的问题。幻象读一般发生在计算统计数据的事务中,举一个例子,假设银行系统在同一个事务中,两次统计存款账户的总金额,在两次统计过程中,刚好新增了一个存款账户,并存入100元,这时,两次统计的总金额将不一致:   如果新增数据刚好满足事务的查询条件,这个新数据就进入了事务的视野,因而产生了两个统计不一致的情况。

幻象读和不可重复读是两个容易混淆的概念,前者是指读到了其它已经提交事务的新增数据,而后者是指读到了已经提交事务的更改数据(更改或删除),为了避免这两种情况,采取的对策是不同的,防止读取到更改数据,只需要对操作的数据添加行级锁,阻止操作中的数据发生变化,而防止读取到新增数据,则往往需要添加表级锁——将整个表锁定,防止新增数据(Oracle使用多版本数据的方式实现)。 第一类丢失更新      A事务撤销时,把已经提交的B事务的更新数据覆盖了。这种错误可能造成很严重的问题,通过下面的账户取款转账就可以看出来:      

时间取款事务A转账事务B
T1开始事务 
T2 开始事务
T3查询账户余额为1000元     
T4 查询账户余额为1000元
T5 汇入100元把余额改为1100元
T6 提交事务
T7取出100元把余额改为900元 
T8撤销事务 
T9余额恢复为1000元(丢失更新) 

A事务在撤销时,“不小心”将B事务已经转入账户的金额给抹去了。

第二类丢失更新  A事务覆盖B事务已经提交的数据,造成B事务所做操作丢失:  

时间转账事务A取款事务B
T1 开始事务
T2开始事务                         
T3               查询账户余额为1000元    
T4查询账户余额为1000元                         
T5 取出100元把余额改为900元
T6 提交事务           
T7汇入100元 
T8提交事务 
T9把余额改为1100元(丢失更新) 

    上面的例子里由于支票转账事务覆盖了取款事务对存款余额所做的更新,导致银行最后损失了100元,相反如果转账事务先提交,那么用户账户将损失100元。

数据库锁机制      数据并发会引发很多问题,在一些场合下有些问题是允许的,但在另外一些场合下可能却是致命的。数据库通过锁的机制解决并发访问的问题,虽然不同的数据库在实现细节上存在差别,但原理基本上是一样的。      按锁定的对象的不同,一般可以分为表锁定和行锁定,前者对整个表进行锁定,而后者对表中特定行进行锁定。从并发事务锁定的关系上看,可以分为共享锁定和独占锁定。共享锁定会防止独占锁定,但允许其它的共享锁定。而独占锁定既防止其它的独占锁定,也防止其它的共享锁定。为了更改数据,数据库必须在进行更改的行上施加行独占锁定,INSERT、UPDATE、DELETE和SELECT FOR UPDATE语句都会隐式采用必要的行锁定。下面我们介绍一下ORACLE数据库常用的5种锁定:  l 行共享锁定:一般通过SELECT FOR UPDATE语句隐式获得行共享锁定,在Oracle中你也可以通过LOCK TABLE IN ROW SHARE MODE语句显式获得行共享锁定。行共享锁定并不防止对数据行进行更改的操作,但是可以防止其它会话获取独占性数据表锁定。允许进行多个并发的行共享和行独占性锁定,还允许进行数据表的共享或者采用共享行独占锁定;  l 行独占锁定:通过一条INSERT、UPDATE或DELETE语句隐式获取,或者通过一条LOCK TABLE IN ROW EXCLUSIVE MODE语句显式获取。这个锁定可以防止其它会话获取一个共享锁定、共享行独占锁定或独占锁定;  l 表共享锁定:通过LOCK TABLE IN SHARE MODE语句显式获得。这种锁定可以防止其它会话获取行独占锁定(INSERT、UPDATE或DELETE),或者防止其它表共享行独占锁定或表独占锁定,它允许在表中拥有多个行共享和表共享锁定。该锁定可以让会话具有对表事务级一致性访问,因为其它会话在你提交或者回溯该事务并释放对该表的锁定之前不能更改这个被锁定的表;  l 表共享行独占:通过LOCK TABLE IN SHARE ROW EXCLUSIVE MODE语句显式获得。这种锁定可以防止其它会话获取一个表共享、行独占或者表独占锁定,它允许其它行共享锁定。这种锁定类似于表共享锁定,只是一次只能对一个表放置一个表共享行独占锁定。如果A会话拥有该锁定,则B会话可以执行SELECT FOR UPDATE操作,但如果B会话试图更新选择的行,则需要等待;  l 表独占:通过LOCK TABLE IN EXCLUSIVE MODE显式获得。这个锁定防止其它会话对该表的任何其它锁定。 
事务隔离级别      尽管数据库为用户提供了锁的DML操作方式,但直接使用锁管理是非常麻烦的,因此数据库为用户提供了自动锁机制。只要用户指定会话的事务隔离级别,数据库就会分析事务中的SQL语句,然后自动为事务操作的数据资源添加上适合的锁。此外数据库还会维护这些锁,当一个资源上的锁数目太多时,自动进行锁升级以提高系统的运行性能,而这一过程对用户来说完全是透明的。      ANSI/ISO SQL 92标准定义了4个等级的事务隔离级别,在相同数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力是不同的。          表 1 事务隔离级别对并发问题的解决情况 

隔离级别脏读不可
重复读
幻象读第一类丢失更新第二类丢失更新
READ UNCOMMITED允许允许允许不允许允许
READ COMMITTED不允许允许允许不允许允许
REPEATABLE READ不允许不允许允许不允许不允许
SERIALIZABLE不允许不允许不允许不允许不允许

    事务的隔离级别和数据库并发性是对立的,两者此增彼长。一般来说,使用READ UNCOMMITED隔离级别的数据库拥有最高的并发性和吞吐量,而使用SERIALIZABLE隔离级别的数据库并发性最低。
    SQL 92定义READ UNCOMMITED主要是为了提供非阻塞读的能力,Oracle虽然也支持READ UNCOMMITED,但它不支持脏读,因为Oracle使用多版本机制彻底解决了在非阻塞读时读到脏数据的问题并保证读的一致性,所以,Oracle的READ COMMITTED隔离级别就已经满足了SQL 92标准的REPEATABLE READ隔离级别。
    SQL 92推荐使用REPEATABLE READ以保证数据的读一致性,不过用户可以根据应用的需要选择适合的隔离等级。 JDBC对事务的支持      并不是所有的数据库都支持事务,即使支持事务的数据库也并非支持所有的事务隔离级别,你可以通过Connection# getMetaData()方法获取DatabaseMetaData对象,并通过该对象的supportsTransactions()、supportsTransactionIsolationLevel(int level)方法查看底层数据库的事务支持情况。Connection默认情况下是自动提交的,也即每条执行的SQL都对应一个事务,为了能够将多条SQL当成一个事务执行,必须先通过Connection#setAutoCommit(false)阻止Connection自动提交,并可通过Connection#setTransactionIsolation()设置事务的隔离级别,Connection中定义了对应SQL 92标准4个事务隔离级别的常量。通过Connection#commit()提交事务,通过Connection#rollback()回滚事务。下面是典型的JDBC事务数据操作的代码:     代码清单 1 JDBC事务代码

Connection conn ; try{ conn = DriverManager.getConnection();①获取数据连接 conn.setAutoCommit(false); ②关闭自动提交的机制 conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); ③设置事务隔离级别 Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate( "INSERT INTO t_topic VALUES(1,’tom’) " ); rows = stmt.executeUpdate( "UPDATE t_user set topic_nums = topic_nums +1 "+"WHERE user_id = 1"); conn.commit();④提交事务 }catch(Exception e){ … conn.rollback();⑤提交事务 }finally{ … }

     在JDBC 2.0中,事务最终只能有两个操作:要么提交要么回滚。但是,有些应用可能需要对事务进行更多的控制,而不是简单地提交或回滚。JDBC 3.0(JDK 1.4及以后的版本)引入了一个全新的保存点特性,Savepoint 接口允许你将事务分割为多个阶段,你可以指定回滚到事务的特定保存点,而非象JDBC 2.0一样只回滚到开始事务的点,如图 1所示:

                                                                                图 1 带Savepoint的事务 

    下面的代码使用了保存点的功能,在发生特定问题时,回滚到指定的保存点,则非回滚整个事务,如代码清单 2所示:  代码清单 2使用保存点的事务代码

… Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate( "INSERT INTO t_topic VALUES(1,’tom’) " ); Savepoint svpt = conn.setSavepoint("savePoint1");①设置一个保存点 rows = stmt.executeUpdate( "UPDATE t_user set topic_nums = topic_nums +1 "+"WHERE user_id = 1"); … conn.rollback(svpt); ②回滚到①处的savePoint1,①之前的SQL操作,在整个事务提交后依然提交,但①到②之间的SQL操作被撤销了 … conn.commit();③提交事务

    并非所有数据库都支持保存点功能,你可以通过DatabaseMetaData#supportsSavepoints()方法查看是否支持。
小结      数据一致性和访问的并发性两者之间的最佳平衡永远是数据库应用程序开发所追求的终极目录。数据事务是保证数据访问一致性的不二法门,使用API进行数据库事务应用开发时,必须深刻了解事务控制属性对应用性能和数据一致性两者的影响,并根据项目实际需要进行合理的设置。

来源: http://geeksun.iteye.com/blog/757413
 
 
存储过程:存储过程是SQL语句和控制语句的预编译集合,以一个名称存储并作为一个单元处理,存储过程实际上是存储在数据库内,可以通过应用程序通过调用来执行,存储过程可以包括程序流、逻辑和对数据的查询,它可以接受参数,并存在多个返回值,它的效率比SQL语句高,以为他只有在第一次进行语法分析和编译,以后客户端再次调用,直接调用编译结果就可以啦,所以它的效率比较高。
 优点:增强SQL语句的功能和灵活性(因为在存储过程中可以写控制语句)。
           实现较快的执行速度。
           减少网络流量(因为他通过参数传递,可以减少传送数据,所以相对应的减少了网络流量)。
创建存储过程:
          
     
存储过程通过call来调用。
 
什么叫存储引擎:
     MySQL可以讲数据以不同的技术存储在文件或内存中,这种技术就叫存储引擎。每一种存储引擎数用不同的存储机制,索引技巧,锁定水平,最终提供广泛切不同的功能。
 
并发控制:当多个连接对记录进行操作时保证数据的一致性和完整性。
 
锁(是为了解决并发问题)
   共享锁(读锁):在同一时间段内,多个用户可以读取同一个资源,读取过程中数据不会发生任何变化。
    排他锁(写锁):在任何时候只能有一个用户写入资源,当进行写锁时会阻塞其他的读锁或者写锁操作。
锁的力度(即所得颗粒)
      ---表锁,是一种开销最小的锁策略。当用户针对数据表操作时,用户获得了这张表的写锁权限,写锁会禁止其他用户对这张表的读写操作。
      ---行锁,是一种开销最大的锁策略。也是支持最大并发处理的一种策略。(对数据表的每一行都加锁,所以它的开销最大)
 
索引:是对数据表中一列或多列的值进行排序的一种结构。可快速定位。就相当于书的目录。

修改存储引擎的方法:
  1. 通过修改MySQL配置文件实现,在MySQL5.5中默认的存储引擎是innoDB.
  2.  通过创建数据表命令实现:
           --create table table_name(
             、、、
              )ENGINE=engine;
 3.通过修改数据表命令实现
      --alter table table_name ENGINE[=] engine_name;
 
MySQL数据库的优化:
   数据库优化的目的:
          1、避免出现页面访问错误(
                          由于数据库连接timeout产生的5XX错误
                          由于慢查询造成页面无法加载
                          由于阻塞造成数据无法提交)
          2、 增加数据库的稳定性(很多数据库问题都是由于低低效查询引起的)
          3、优化用户体验(
                 流畅页面的访问速度
                  良好的网站功能体)
   可以从以下几个方面进行优化:SQL及索引,数据表结构,系统配置,硬件。其中SQL及索引最重要,首先我们要根据我们的需求写出结构良好的SQL,另外要根据SQL在表中建立有效的索引,但是如果我们的索引过多,不但会影响我们写入的效率,同时还会影响我们查询的效率,所以索引建立要适量有效。但是如果表结构设计不合理,我们就很难写出结构良好的SQL,所以要建立简洁明了的表结构,所以说在设计表结构的时候,我们要考虑怎样对表结构进行查询,怎样的表结构的设计才是有利于表结构的查询,然后是系统配置的优化,但是当前我们大多数的MySQL都是在lnuix系统上,但是系统上是有一些本身的限制,比如说:TCP/IP连接数的限制,打开文件数的限制和一些安全上的限制,因为MySQL查询是基于文件的,没查询一个表就要打开一个文件,如果文件数达到一定的限制,这个文件就无法打开。硬件优化,就是我们要选择更适合数据库的CPU,更快的IO,以及更多的内存,数据库数据要放在内存中查询修改,所以内存越大,对我们数据库的性能就越好,但CPU却不是这样的,CPU越大,不见得对数据库性能越好,因为SQL会对CPU的可数有限制,比如说他并不会用到太多的核数,有的查询他只用于单核,所以说CUP也对数据库有影响,并不是核数越多越好,而IO,目前由于多新型IO设备,如 ssd,,但它并不能减少数据库锁的机制,因为锁是数据库保存完整性的一种机制,虽然IO很快,但它并不能减少阻塞,所以我们说硬件上的优化是成本最高但效果最差的,所以说如果慢查询很多,阻塞很多,那么并发量就会上去,导致应用响应缓慢。
 
1.SQL及索引的优化:
    对Max(),Count()函数的优化,子查询的优化,group by 的优化(目的是减少IO),limit优化(使用有索引的列或主键进行orderby操作以避免IO)
 
     a. 如何选择合适的列建立索引:
            在where从句,group by, order by,on从句中出现的列建立索引;索引字段越小越好;离散度大的列放到联合索引的前面。
       b.索引的维护及优化------重复及冗余索引和对不用索引的删除
 2.数据库结构的优化
    a.选择合适的数据类型,数据类型的选择,重点在于合适,
     
     b.表的范式化和反范式化(范式化指的是表设计的规则) 
         反范式化是指为了查询效率的考虑把原本符合第三范式的表适当的增加冗余,已达到优化效率的目的,反范式化是以空间换时间的做法。
     c.表的垂直拆分,解决了表的宽度问题。将不常用的字段拆分出来。
     d.表的水平拆分,解决表的数据量过大的问题。
3.系统配置的优化。及MySQL配置文件的优化   
 
SQL语句;
 
查找:select
       
别名:AS
    select id AS userId,username AS uname From users;
查询结果分组:group by
   select sex from users group by sex;
  分组条件:HAVING +聚合函数、或者是having后的字段出现在select后面。
    select age,sex from users group by sex HAVING age>2;
  对分组结果进行排序:order by    DESC 表示降序 默认为ASC升序
      select * from users order by id DESC; 
限制查询结果返回的数量:limit
    select * from users LIMIT 2;/LIMIT 2,2 (指的是从第三条开始,限制2条)
插入insert:
    insert test(username) select username from users where age>27;
更新:update
子查询:(not)in,(not)exists
向单表插入:insert table_user1(username) select age from table_user2 group by age;
连接类型:inner join,内连接
              在MySQL中,join,cross join 和 inner join 是等价的。
       left [outer] join,左外连接
       right [outer] join,右外连接
   select username,age,sex 
   inner join  user2;
函数:
select CONCAT(username,age) AS u FROM user;//字符串链接
聚合函数:Avg(),Count(),Max(),Min(),Sum()
加密函数:MD5(),Password()