Mysql知识汇总(二)

事务


1. 什么是数据库事务?

事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态变到另一种一致性状态。事务是逻辑上的一组操作,要么都执行,要么都不执行。

事务最经典也经常被拿出来说例子就是转账了。

假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误比如银行系统崩溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要失败。

2. 事物的四大特性(ACID)介绍一下?

关系性数据库需要遵循ACID规则,具体内容如下:


原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;

  1. 一致性:执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;

  2. 隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;

  3. 持久性:一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

    3. 同时有多个事务在进行会怎么样呢?(脏读,幻读,不可重复读)
    多事务的并发进行一般会造成以下几个问题:
  • 脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

  • 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

  • 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

4. 怎么解决这些问题呢?MySQL的事务隔离级别了解吗?

MySQL的四种隔离级别如下:
  • 1.未提交读(READ UNCOMMITTED)

这就是上面所说的例外情况了,这个隔离级别下,其他事务可以看到本事务没有提交的部分修改.因此会造成脏读的问题(读取到了其他事务未提交的部分,而之后该事务进行了回滚).
这个级别的性能没有足够大的优势,但是又有很多的问题,因此很少使用.
  • 2.已提交读(READ COMMITTED)

其他事务只能读取到本事务已经提交的部分.这个隔离级别有 不可重复读的问题,在同一个事务内的两次读取,拿到的结果竟然不一样,因为另外一个事务对数据进行了修改.
  • 3.REPEATABLE READ(可重复读)

可重复读隔离级别解决了上面不可重复读的问题(看名字也知道),但是仍然有一个新问题,就是幻读
当你读取id> 10 的数据行时,对涉及到的所有行加上了读锁,此时例外一个事务新插入了一条id=11的数据,因为是新插入的,所以不会触发上面的锁的排斥
那么进行本事务进行下一次的查询时会发现有一条id=11的数据,而上次的查询操作并没有获取到,再进行插入就会有主键冲突的问题.
  • 4.SERIALIZABLE(可串行化)

这是最高的隔离级别,可以解决上面提到的所有问题,因为他强制将所以的操作串行执行,这会导致并发性能极速下降,因此也不是很常用.

5. 什么是事务的隔离级别?MySQL的默认隔离级别是什么?

为了达到事务的四大特性,数据库定义了4种不同的事务隔离级别,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。

SQL 标准定义了四个隔离级别:

  • READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

  • READ-COMMITTED(读取已提交):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

  • REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  • SERIALIZABLE(可串行化):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

这里需要注意的是:Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别

事务隔离机制的实现基于锁机制和并发调度。其中并发调度使用的是MVVC(多版本并发控制),通过保存修改的旧版本信息来支持并发一致性读和回滚等特性。

因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取提交内容):,但是你要知道的是InnoDB 存储引擎默认使用 **REPEATABLE-READ(可重读)**并不会有性能损失。

InnoDB 存储引擎在 分布式事务 的情况下一般会用到**SERIALIZABLE(可串行化)**隔离级别。


1. 对MySQL的锁了解吗

当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制。

就像酒店的房间,如果大家随意进出,就会出现多人抢夺同一个房间的情况,而在房间上装上锁,申请到钥匙的人才可以入住并且将房间锁起来,其他人只有等他使用完毕才可以再次使用。

2. 隔离级别与锁的关系

在Read Uncommitted级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的排他锁冲突

在Read Committed级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁;

在Repeatable Read级别下,读操作需要加共享锁,但是在事务提交之前并不释放共享锁,也就是必须等待事务执行完毕以后才释放共享锁。

SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。

3. 按照锁的粒度分数据库锁有哪些?锁机制与InnoDB锁算法

在关系型数据库中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎)表级锁(MYISAM引擎)页级锁(BDB引擎 )

MyISAM和InnoDB存储引擎使用的锁:

  • MyISAM采用表级锁(table-level locking)。

  • InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁

行级锁,表级锁和页级锁对比

行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。

特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

表级锁 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。

特点:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

页级锁 页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。

特点:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

4. 从锁的类别上分MySQL都有哪些锁呢?像上面那样子进行锁定岂不是有点阻碍并发效率了

从锁的类别上来讲,有共享锁和排他锁。

共享锁: 又叫做读锁。当用户要进行数据的读取时,对数据加上共享锁。共享锁可以同时加上多个。

排他锁: 又叫做写锁。当用户要进行数据的写入时,对数据加上排他锁。排他锁只可以加一个,他和其他的排他锁,共享锁都相斥。

用上面的例子来说就是用户的行为有两种,一种是来看房,多个用户一起看房是可以接受的。一种是真正的入住一晚,在这期间,无论是想入住的还是想看房的都不可以。

锁的粒度取决于具体的存储引擎,InnoDB实现了行级锁,页级锁,表级锁。

他们的加锁开销从大到小,并发能力也是从大到小。

5. MySQL中InnoDB引擎的行锁是怎么实现的?

答:InnoDB是基于索引来完成行锁

例: select * from tab_with_index where id = 1 for update;

for update 可以根据条件来完成行锁锁定,并且 id 是有索引键的列,如果 id 不是索引键那么InnoDB将完成表锁,并发将无从谈起

6. InnoDB存储引擎的锁的算法有三种

  • Record lock:单个行记录上的锁

  • Gap lock:间隙锁,锁定一个范围,不包括记录本身

  • Next-key lock:record+gap 锁定一个范围,包含记录本身

相关知识点:

  1. innodb对于行的查询使用next-key lock

  2. Next-locking keying为了解决Phantom Problem幻读问题

  3. 当查询的索引含有唯一属性时,将next-key lock降级为record key

  4. Gap锁设计的目的是为了阻止多个事务将记录插入到同一范围内,而这会导致幻读问题的产生

  5. 有两种方式显式关闭gap锁:(除了外键约束和唯一性检查外,其余情况仅使用record lock) A. 将事务隔离级别设置为RC B. 将参数innodb_locks_unsafe_for_binlog设置为1

7. 什么是死锁?怎么解决?

死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。

常见的解决死锁的方法

1、如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。

2、在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;

3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

如果业务处理不好可以用分布式事务锁或者使用乐观锁

8. 数据库的乐观锁和悲观锁是什么?怎么实现的?

数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。在查询完数据的时候就把事务锁起来,直到提交事务。实现方式:使用数据库中的锁机制

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。在修改数据的时候把事务锁起来,通过version的方式来进行锁定。实现方式:乐一般会使用版本号机制或CAS算法实现。

两种锁的使用场景

从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。

但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

视图


1. 为什么要使用视图?什么是视图?

为了提高复杂SQL语句的复用性和表操作的安全性,MySQL数据库管理系统提供了视图特性。所谓视图,本质上是一种虚拟表,在物理上是不存在的,其内容与真实的表相似,包含一系列带有名称的列和行数据。但是,视图并不在数据库中以储存的数据值形式存在。行和列数据来自定义视图的查询所引用基本表,并且在具体引用视图时动态生成。

视图使开发者只关心感兴趣的某些特定数据和所负责的特定任务,只能看到视图中所定义的数据,而不是视图所引用表中的数据,从而提高了数据库中数据的安全性。

2. 视图有哪些特点?

视图的特点如下:

  • 视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系。

  • 视图是由基本表(实表)产生的表(虚表)。

  • 视图的建立和删除不影响基本表。

  • 对视图内容的更新(添加,删除和修改)直接影响基本表。

  • 当视图来自多个基本表时,不允许添加和删除数据。

视图的操作包括创建视图,查看视图,删除视图和修改视图。

3. 视图的使用场景有哪些?

视图根本用途:简化sql查询,提高开发效率。如果说还有另外一个用途那就是兼容老的表结构。

下面是视图的常见使用场景:

  • 重用SQL语句;

  • 简化复杂的SQL操作。在编写查询后,可以方便的重用它而不必知道它的基本查询细节;

  • 使用表的组成部分而不是整个表;

  • 保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限;

  • 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。

4. 视图的优点

  1. 查询简单化。视图能简化用户的操作

  2. 数据安全性。视图使用户能以多种角度看待同一数据,能够对机密数据提供安全保护

  3. 逻辑数据独立性。视图对重构数据库提供了一定程度的逻辑独立性

5. 视图的缺点

  1. 性能。数据库必须把视图的查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,数据库也把它变成一个复杂的结合体,需要花费一定的时间。

  2. 修改限制。当用户试图修改视图的某些行时,数据库必须把它转化为对基本表的某些行的修改。事实上,当从视图中插入或者删除时,情况也是这样。对于简单视图来说,这是很方便的,但是,对于比较复杂的视图,可能是不可修改的

    这些视图有如下特征:1.有UNIQUE等集合操作符的视图。2.有GROUP BY子句的视图。3.有诸如AVG\SUM\MAX等聚合函数的视图。4.使用DISTINCT关键字的视图。5.连接表的视图(其中有些例外)

6. 什么是游标?

游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果,每个游标区都有一个名字。用户可以通过游标逐一获取记录并赋给主变量,交由主语言进一步处理。

存储过程与函数


什么是存储过程?有哪些优缺点?

存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需要创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。

优点

1)存储过程是预编译过的,执行效率高。

2)存储过程的代码直接存放于数据库中,通过存储过程名直接调用,减少网络通讯。

3)安全性高,执行存储过程需要有一定权限的用户。

4)存储过程可以重复使用,减少数据库开发人员的工作量。

缺点

1)调试麻烦,但是用 PL/SQL Developer 调试很方便!弥补这个缺点。

2)移植问题,数据库端代码当然是与数据库相关的。但是如果是做工程型项目,基本不存在移植问题。

3)重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。

4)如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。

触发器


1. 什么是触发器?触发器的使用场景有哪些?

触发器是用户定义在关系表上的一类由事件驱动的特殊的存储过程。触发器是指一段代码,当触发某个事件时,自动执行这些代码。

使用场景

  • 可以通过数据库中的相关表实现级联更改。

  • 实时监控某张表中的某个字段的更改而需要做出相应的处理。

  • 例如可以生成某些业务的编号。

  • 注意不要滥用,否则会造成数据库及应用程序的维护困难。

  • 大家需要牢记以上基础知识点,重点是理解数据类型CHAR和VARCHAR的差异,表存储引擎InnoDB和MyISAM的区别。

2. MySQL中都有哪些触发器?

在MySQL数据库中有如下六种触发器:

  • Before Insert

  • After Insert

  • Before Update

  • After Update

  • Before Delete

  • After Delete

常用SQL语句


1. SQL语句主要分为哪几类

数据定义语言DDL(Data Ddefinition Language)CREATE,DROP,ALTER

主要为以上操作 即对逻辑结构等有操作的,其中包括表结构,视图和索引。

数据查询语言DQL(Data Query Language)SELECT

这个较为好理解 即查询操作,以select关键字。各种简单查询,连接查询等 都属于DQL。

数据操纵语言DML(Data Manipulation Language)INSERT,UPDATE,DELETE

主要为以上操作 即对数据进行操作的,对应上面所说的查询操作 DQL与DML共同构建了多数初级程序员常用的增删改查操作。而查询是较为特殊的一种 被划分到DQL中。

数据控制功能DCL(Data Control Language)GRANT,REVOKE,COMMIT,ROLLBACK

主要为以上操作 即对数据库安全性完整性等有操作的,可以简单的理解为权限控制等。

2. 超键、候选键、主键、外键分别是什么?

  • 超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键。

  • 候选键:是最小超键,即没有冗余元素的超键。

  • 主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。

  • 外键:在一个表中存在的另一个表的主键称此表的外键。

3. SQL 约束有哪几种?

SQL 约束有哪几种?

  • NOT NULL: 用于控制字段的内容一定不能为空(NULL)。

  • UNIQUE: 控件字段内容不能重复,一个表允许有多个 Unique 约束。

  • PRIMARY KEY: 也是用于控件字段内容不能重复,但它在一个表只允许出现一个。

  • FOREIGN KEY: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。

  • CHECK: 用于控制字段的值范围。

4. 六种关联查询

  • 交叉连接(CROSS JOIN)

  • 内连接(INNER JOIN)

  • 外连接(LEFT JOIN/RIGHT JOIN)

  • 联合查询(UNION与UNION ALL)

  • 全连接(FULL JOIN)

  • 交叉连接(CROSS JOIN)

SELECT * FROM A,B(,C)或者SELECT * FROM A CROSS JOIN B (CROSS JOIN C)#没有任何关联条件,结果是笛卡尔积,结果集会很大,没有意义,很少使用内连接(INNER JOIN)SELECT * FROM A,B WHERE A.id=B.id或者SELECT * FROM A INNER JOIN B ON A.id=B.id多表中同时符合某种条件的数据记录的集合,INNER JOIN可以缩写为JOIN

内连接分为三类

  • 等值连接:ON A.id=B.id

  • 不等值连接:ON A.id > B.id

  • 自连接:SELECT * FROM A T1 INNER JOIN A T2 ON T1.id=T2.pid

外连接(LEFT JOIN/RIGHT JOIN)

  • 左外连接:LEFT OUTER JOIN, 以左表为主,先查询出左表,按照ON后的关联条件匹配右表,没有匹配到的用NULL填充,可以简写成LEFT JOIN

  • 右外连接:RIGHT OUTER JOIN, 以右表为主,先查询出右表,按照ON后的关联条件匹配左表,没有匹配到的用NULL填充,可以简写成RIGHT JOIN

联合查询(UNION与UNION ALL)

SELECT * FROM A UNION SELECT * FROM B UNION ...

  • 就是把多个结果集集中在一起,UNION前的结果为基准,需要注意的是联合查询的列数要相等,相同的记录行会合并

  • 如果使用UNION ALL,不会合并重复的记录行

  • 效率 UNION 高于 UNION ALL

全连接(FULL JOIN)

  • MySQL不支持全连接

  • 可以使用LEFT JOIN 和UNION和RIGHT JOIN联合使用

SELECT * FROM A LEFT JOIN B ON A.id=B.id UNIONSELECT * FROM A RIGHT JOIN B ON A.id=B.id

表连接面试题

有2张表,1张R、1张S,R表有ABC三列,S表有CD两列,表中各有三条记录。

R表


S表


  1. 1.交叉连接(笛卡尔积):

select r.*,s.* from r,s


  1. 2.内连接结果:

    select r.*,s.* from r inner join s on r.c=s.c


  1. 3.左连接结果:

    select r.*,s.* from r left join s on r.c=s.c


  1. 4.右连接结果:

    select r.*,s.* from r right join s on r.c=s.c


  1. 5.全表连接的结果(MySql不支持,Oracle支持):

    select r.*,s.* from r full join  s on r.c=s.c


5. 什么是子查询

  1. 条件:一条SQL语句的查询结果做为另一条查询语句的条件或查询结果

  2. 嵌套:多条SQL语句嵌套使用,内部的SQL查询语句称为子查询。

6. 子查询的三种情况

  1. 子查询是单行单列的情况:结果集是一个值,父查询使用:=、 <、 > 等运算符

-- 查询工资最高的员工是谁?
select * from employee where salary=(select max(salary) from employee);

  1. 子查询是多行单列的情况:结果集类似于一个数组,父查询使用:in 运算符

-- 查询工资最高的员工是谁?
select * from employee where salary=(select max(salary) from employee);

  1. 子查询是多行多列的情况:结果集类似于一张虚拟表,不能用于where条件,用于select子句中做为子表

-- 1) 查询出2011年以后入职的员工信息
-- 2) 查询所有的部门信息,与上面的虚拟表中的信息比对,找出所有部门ID相等的员工。
select * from dept d, (select * from employee where join_date > '2011-1-1') e where e.dept_id = d.id;

– 使用表连接:

select d., e. from dept d inner join employee e on d.id = e.dept_id where e.join_date > ‘2011-1-1’

7. mysql中 in 和 exists 区别

mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询。一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的。这个是要区分环境的。

  1. 如果查询的两个表大小相当,那么用in和exists差别不大。

  2. 如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。

  3. not in 和not exists:如果查询语句使用了not in,那么内外表都进行全表扫描,没有用到索引;而not extsts的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

8. varchar与char的区别

char的特点

  • char表示定长字符串,长度是固定的;

  • 如果插入数据的长度小于char的固定长度时,则用空格填充;

  • 因为长度固定,所以存取速度要比varchar快很多,甚至能快50%,但正因为其长度固定,所以会占据多余的空间,是空间换时间的做法;

  • 对于char来说,最多能存放的字符个数为255,和编码无关

varchar的特点

  • varchar表示可变长字符串,长度是可变的;

  • 插入的数据是多长,就按照多长来存储;

  • varchar在存取方面与char相反,它存取慢,因为长度不固定,但正因如此,不占据多余的空间,是时间换空间的做法;

  • 对于varchar来说,最多能存放的字符个数为65532

总之,结合性能角度(char更快)和节省磁盘空间角度(varchar更小),具体情况还需具体来设计数据库才是妥当的做法。

9. varchar(50)中50的涵义

最多存放50个字符,varchar(50)和(200)存储hello所占空间一样,但后者在排序时会消耗更多内存,因为order by col采用fixed_length计算col长度(memory引擎也一样)。在早期 MySQL 版本中, 50 代表字节数,现在代表字符数。

10. int(20)中20的涵义

是指显示字符的长度。20表示最大显示宽度为20,但仍占4字节存储,存储范围不变;

不影响内部存储,只是影响带 zerofill 定义的 int 时,前面补多少个 0,易于报表展示

11. mysql为什么这么设计

对大多数应用没有意义,只是规定一些工具用来显示字符的个数;int(1)和int(20)存储和计算均一样;

12. mysql中int(10)和char(10)以及varchar(10)的区别

  • int(10)的10表示显示的数据的长度,不是存储数据的大小;chart(10)和varchar(10)的10表示存储数据的大小,即表示存储多少个字符。

    int(10) 10位的数据长度 9999999999,占32个字节,int型4位
    char(10) 10位固定字符串,不足补空格 最多10个字符
    varchar(10) 10位可变字符串,不足补空格 最多10个字符

  • char(10)表示存储定长的10个字符,不足10个就用空格补齐,占用更多的存储空间

  • varchar(10)表示存储10个变长的字符,存储多少个就是多少个,空格也按一个字符存储,这一点是和char(10)的空格不同的,char(10)的空格表示占位不算一个字符

13. FLOAT和DOUBLE的区别是什么?

  • FLOAT类型数据可以存储至多8位十进制数,并在内存中占4字节。

  • DOUBLE类型数据可以存储至多18位十进制数,并在内存中占8字节。

14. drop、delete与truncate的区别

三者都表示删除,但是三者有一些差别:

因此,在不再需要一张表的时候,用drop;在想删除部分数据行时候,用delete;在保留表而删除所有数据的时候用truncate。

15. UNION与UNION ALL的区别?

  • 如果使用UNION ALL,不会合并重复的记录行

  • 效率 UNION 高于 UNION ALL

全部评论