数据库面试题总结二(varchar / char、delete / drop / truncate、MyISAM / InnoDB、优化方法)

目录

char 和 varchar区别、numeric

delete、drop 和 truncate 区别

MyISAM 和 InnoDB 区别

数据库优化方式


数据库面试题总结一(范式、视图、索引、授权、事务、触发器、连接方式)

https://blog.csdn.net/zhsihui429/article/details/86530609

 

char 和 varchar区别、numeric

  • char(n):固定长度的字符串,用户指定长度n
  • varchar(n):可变长度的字符串,用户指定最大长度n

例子:属性A的类型是char(10),若为此属性存入“Avi”,那么该字符串后会追加7个空格来使其达到10个字符的串长度。反之,如果属性B的类型是varchar(10),在属性B中存放字符串“Avi”,则不会增加空格。

当比较两个char类型的值时,如果它们的长度不同,在比较之前会自动在短值后加上额外的空格以使它们的长度一致。

但当比较一个char类型和一个varchar类型时,不一定会在varchar后加上额外的空格以使长度一致,取决于数据库系统,因此,即使都存放“Avi”,A = B的比较也可能返回假。

建议使用varchar类型来存放字符串。

  • numeric(p,d):定点数,精度由用户指定。这个数有p位数字(加上一个符号位,即不含符号位)其中d位数字在小数点右边

 

delete、drop 和 truncate 区别

【1】delete

  • delete是DML,执行delete操作时,每次从表中删除一行,并且同时将该行的的删除操作记录在redo和undo表空间(日志)中以便进行回滚(rollback)和重做操作,但要注意表空间要足够大,事务需要手动提交(commit)操作才能生效,可以通过rollback撤消操作。如果有相应的 tigger,执行的时候将被触发。
  • delete 可对 table 和 view 操作只删除数据。delete 操作不会减少表或索引所占用的空间。
  • delete可根据条件删除表中满足条件的数据,如果不指定where子句,那么删除表中所有记录。
  • delete语句不影响表所占用的extent,高水线(high watermark)保持原位置不变。
  • 使用:如果想删除部分数据注意带上where子句,回滚段要足够大;如果和事务有关,或者想触发trigger;如果想保留标识计数值,用delete。

【2】truncate

  • truncate是DDL,会隐式提交,操作立即生效,原数据不放到 rollback segment中,即删除操作记录不写入日志保存,所以执行速度快,但不能回滚,不会触发触发器。
  • 只能对 table 操作只删除数据。当表被 truncate 后,这个表和索引所占用的空间会恢复到初始大小。
  • truncate会一次性删除表中所有行,但表结构及其列、约束、索引等保持不变
  • 对于外键(foreignkey)约束引用的表,不能使用 truncate table,而应使用不带 where 子句的 delete 语句。
  • truncatetable不能用于参与了索引视图的表。
  • truncate 会重新设置高水线和所有的索引,缺省情况下将空间释放到minextents个extent,除非使用reuse storage。
  • 如果一不小心把一个表truncate掉,也是可以恢复的,只是不能通过rollback来恢复。
  • 使用:如果想保留表而将所有数据删除,且和事务无关,用truncate;如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据。

【3】drop

  • drop是DDL,会隐式提交,操作立即生效,原数据不放到 rollback segment中,不能回滚,不会触发触发器。
  • 删除整个表(结构和数据)。drop语句将表所占用的空间全释放掉。
  • drop语句将删除表的结构所依赖的约束,触发器,索引,依赖于该表的存储过程/函数将保留,但是变为invalid状态。
  • 使用:如果想删除表定义及其数据,用drop。

【总结】

  • 执行速度:drop> truncate > delete
  • 在没有备份情况下,谨慎使用 drop 与 truncate。
  • truncate table 在功能上与不带 where 子句的 delete 语句相同:二者均删除表中的全部行。但 truncate 比 delete 速度快,且使用的系统和事务日志资源少。delete 语句每次删除一行,并在事务日志中为所删除的每行记录一项。truncate 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。
  • truncate与不带where的delete :只删除数据,而不删除表的结构(定义)

 

MyISAM 和 InnoDB 区别

  • MyISAM默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不支持事务,而且不支持外键,如果执行大量的select的时候,MyISAM比较适合。只支持表级锁,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。提供高速存储和检索,以及全文搜索能力。支持(FULLTEXT类型的)全文索引。索引和数据分离,是天生非聚簇索引,最多有一个unique性质。占用空间小。执行速度更快,性能好。
  • InnoDB:支持事务安全的引擎,支持外键、行级锁、事务是它最大特点。如果有大量的update和insert,建议使用InnoDB,可以提高多用户并发操作的性能,特别是针对多个并发和QPS较高的情况。主要用于事务处理应用程序。索引和数据不分离,其本身就是主键索引文件(聚簇索引)。主键范围更大。

MySQL主要的两种锁的特性可大致归纳如下:

  • 表级锁: 开销小,加锁快;不会出现死锁(因为MyISAM会一次性获得SQL所需的全部锁);锁定粒度大,发生锁冲突的概率最高,并发度最低。
  • 行级锁: 开销大(占更多内存),加锁慢(因为要获得更多的锁);会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高,即使有许多线程访问不同的行时,也只存在少量的冲突;回滚时只有少量的更改;可以长时间锁定单一的行。

考虑上述特点,表级锁使用与并发性不高,以查询为主,少量更新的应用,比如小型的web应用;而行级锁适用于高并发环境下,对事务完整性要求较高的系统,如在线事务处理系统。

  • 页级锁:页级锁是表级锁和行级锁的折中,一次锁定相邻的一组记录。

 

数据库优化方式

  • 使用索引:成本最低,见效最快的解决方案。但索引不是越多越好,因为写入时可能重建索引结构,降低了效率。
  • 对查询进行优化。要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
  • 避免使用NULL值。尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。char中null占空间,varchar中不占空间。可设置默认值为0。
  • 尽量避免在 where 子句中对字段进行表达式操作 / 尽量避免在where子句中对字段进行函数操作 / 尽量避免在 where 子句中使用 != 或 <> 操作符 / 尽量避免在 where 子句中使用参数 / 尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,否则将引擎放弃使用索引而进行全表扫描
  • in 和 not in 也要慎用。对于连续的数值,尽量用 between 代替 in 。有时也可用 exists 代替 in 。
  • 不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
  • 尽可能的使用 varchar / nvarchar 代替 char / nchar。首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
  • 尽量使用表变量来代替临时表。如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
  • 尽量避免使用游标,因为游标的效率较差。
  • 数据库引擎选择:myisam 和 innodb。一般,由于mysiam的索引结构是在内存中存的,所以比innodb快一些。但mysiam是表级锁,而innodb是行级锁,所以,mysiam适用于一次插入,多次查询的表,或者是读写分离中的读库中的表,而对于修改插入删除操作比较频繁的表,就很不合适了。
  •  尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。
  • 尽量避免大事务操作,提高系统并发能力。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章