Skip to content

Latest commit

 

History

History
1138 lines (827 loc) · 70.8 KB

02-mysql-faq.md

File metadata and controls

1138 lines (827 loc) · 70.8 KB

关系型和非关系型数据库比较

  • 关系型数据库
    • SQLite、Oracle、mysql 等
  • 特性
    • 1、关系型数据库,是指采用了关系模型来组织数据的数据库;
    • 2、关系型数据库的最大特点就是事务的一致性
    • 3、简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
    • 4、在关系型数据库当中一个表就是一个关系,一个关系数据库可以包含多个表。
  • 优点
    • 1、容易理解:二维表结构是非常贴近逻辑世界一个概念,关系模型相对网状、层次等其它模型来说更容易理解;
    • 2、使用方便:通用的 SQL 语言使得操作关系型数据库非常方便;
    • 3、易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率;
    • 4、支持 SQL,可用于复杂的查询。
    • 5、事务一致性:通过事务处理保持数据的一致性
  • 缺点
    • 1、为了维护一致性所付出的巨大代价就是其读写性能比较差
    • 2、固定的表结构,表结构更新困难;
    • 3、高并发(差) 读写需求,硬盘 I/O 是一个很大的瓶颈;
    • 4、海量数据的读写效率低
  • 非关系型数据库
    • MongoDb、redis、Hbase 等
  • 特性
    • 1、使用键值对存储数据;
    • 2、分布式;
    • 3、一般不支持 ACID 特性;
    • 4、非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。
    • 【非关系型数据库(NoSQL)是对不同于传统的关系数据库的数据库管理系统的统称。】
  • 优点
    • 1、无需经过 sql 层的解析,读写性能很高
    • 2、基于键值对,数据没有耦合性,容易扩展
    • 3、存储数据的格式丰富:nosql 的存储格式是 key,value 形式、文档形式、图片形式等等,文档形式、图片形式等等,而关系型数据库则只支持基础类型。
  • 缺点
    • 1、不提供 sql 支持,学习和使用成本较高;
    • 2、无事务处理,附加功能 bi 和报表等支持也不好;

注 1:数据库事务必须具备 ACID 特性,ACID 是 Atomic 原子性,Consistency 一致性,Isolation 隔离性,Durability 持久性。 注 2:数据的持久存储,尤其是海量数据的持久存储,还是需要一种关系数据库。

View

视图的定义

视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个 select 语句保存在数据字典中的。 通过视图,可以展现基表的部分数据;视图数据来自定义视图的查询中使用的表,使用视图动态生成。

基表:用来创建视图的表叫做基表 base table

视图的优点

  • 1)简单:使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤好的复合条件的结果集。

  • 2)安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行某个列,但是通过视图就可以简单的实现。

  • 3)数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。

    总而言之,使用视图的大部分情况是为了保障数据安全性,提高查询效率。

视图的限制

  • 1、同一 database,view 名称不可重复,也不能与 table 名重复;
  • 2、view 不能跟 triggers 建立关联。
  • 3、view 在使用查询时:
    • 1 只能使用已存在的 table 和 view;
    • 2 查询 from 子句不能使用子查询;
    • 3 不能使用 tempporary table;
    • 4 不能自定义变量、procedure 和 prepared statement 参数

使用示例

创建视图:

create view countryview as
	select Continent,region,code,code2,name
		from world.country
		order by continent,region,code

使用视图:

select continent,count(*)
	from world.countryview
		group by continent

可与正常 table 一起使用:

select name,Language
from world.countryview,countrylanguage
where code=countrycode;

索引(index)

索引是关系数据库中对某一列或多个列的值进行预排序的数据结构。 通过使用索引,可以让数据库系统不必扫描整个表,而是直接定位到符合条件的记录,这样就大大加快了查询速度。

为什么要建立索引呢?

因为,建立索引可以大大提高系统的效能。

  • 第一、通过建立唯一性索引,可以保证数据库表中每一行数据的唯一性。
  • 第二、可以大大加快数据的检索速度,这也是建立索引的最主要的原因。
  • 第三、可以加速表和表之间的联机,特别是在实现数据的参考完整性方面特别有意义。
  • 第四、在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
  • 第五、通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的效能。

增加索引也有许多不利的方面

  • 第一、建立索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
  • 第二、索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间。如果要建立聚簇索引,那么需要的空间就会更大。
  • 第三、当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

什么样的字段适合建立索引

  • 第一、在经常需要搜寻的列上,可以加快搜索的速度;
  • 第二、在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
  • 第三、在经常用在联机的列上,这些列主要是一些外来键,可以加快联机的速度;
  • 第四、在经常需要根据范围进行搜寻的列上建立索引,因为索引已经排序,其指定的范围是连续的;
  • 第五、在经常需要排序的列上建立索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
  • 第六、在经常使用在 WHERE 子句中的列上面建立索引,加快条件的判断速度。

建立索引,一般按照 select 的 where 条件来建立, 比如: select 的条件是 where f1 and f2,那么如果我们在字段 f1 或字段 f2 上建立索引是没有用的,只有在字段 f1 和 f2 上同时建立索引才有用等。

什么样的字段不适合建立索引

  • 第一,对于那些在查询中很少使用或者参考的列不应该建立索引。
    • 这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。
    • 相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
  • 第二,对于那些只有很少数据值的列也不应该增加索引。
    • 这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,
    • 即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
  • 第三,对于那些定义为 text, image 和 bit 数据型别的列不应该增加索引。
    • 这是因为,这些列的资料量要么相当大,要么取值很少。
  • 第四,当修改效能远远大于检索效能时,不应该建立索引。
    • 这是因为,修改效能和检索效能是互相矛盾的。当增加索引时,会提高检索效能,但是会降低修改效能。
    • 当减少索引时,会提高修改效能,降低检索效能。
    • 因此,当修改效能远远大于检索效能时,不应该建立索引。

优化使用原则

  1. 择唯一性索引
  2. 为经常需要排序、分组和联合操作的字段建立索引。ORDER BY、GROUP BY、DISTINCT 和 UNION 等操作的字段,
  3. 常作为查询条件的字段建立索引
  4. 限制索引的数目
  5. 尽量使用数据量少的索引(char10 建索引比 char100 在检索时耗时更少,效率更高)
  6. 尽量使用前缀来索引
  • 例如,TEXT 和 BLOG 型别的字段,进行全文检索会很浪费时间。
  • 如果只检索字段的前面的若干个字符,这样可以提高检索速度。
  1. 删除不再使用或者很少使用的索引
  2. 最左前缀匹配原则,非常重要的原则。
  • MySQL 会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,
  • 比如 a 1=”” and=”” b=”2” c=”“> 3 and d = 4
    • 如果建立(a,b,c,d)顺序的索引,d 是用不到索引的,
    • 如果建立(a,b,d,c)的索引则都可以用到,a,b,d 的顺序可以任意调整。
  1. = 和 in 可以乱序
  • 比如 a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql 的查询优化器会帮你优化成索引可以识别的形式
  1. 尽量选择区分度高的列作为索引
  • 区分度的公式是 count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,
  • 唯一键的区分度是 1,而一些状态、性别字段可能在大数据面前区分度就 是 0,
  • 那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要 join 的字段我们都要求是 0.1 以上,即平均 1 条扫描 10 条记录
  1. 索引列不能参与计算,保持列“干净”
  • 比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,
  • 原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函式才能比较,显然成本太大。
  • 所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
  1. 尽量的扩充套件索引,不要新建索引。
  • 比如表中已经有 a 的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可

注意:选择索引的最终目的是为了使查询的速度变快。 上面给出的原则是最基本的准则,但不能拘泥于上面的准则。 在学习和工作中进行不断的实践。根据应用的实际情况进行分析和判断,选择最合适的索引方式。

三大范式

数据库逻辑设计之三大范式通俗理解,一看就懂,书上说的太晦涩

第一范式(1NF)无重复的列:实体中的某个属性不能有多个值或者不能有重复的属性。 第二范式(2NF)就是非主属性完全依赖于主关键字。[ 消除部分子函数依赖 ] 第三范式(3NF)属性不依赖于其它非主属性 [ 消除传递依赖 ] 一个数据库表中不包含已在其它表中已包含的非主关键字信息。 BCNF 范式:不存在关键字段决定关键字段的情况。数据库表中不存在任何字段对任一候选关键字段的传递函数依赖。

即:栏位不可再细分、表不可再拆分、数据不冗余

例如 学生(学号,姓名,性别,出生年月日),出生年月日还可以再拆分为年、月、日等,那就不满足第一范式。 学生学分(学号、课程号、姓名、学分),学分依赖课程号,姓名依赖与学号,所以不符合二范式。 学生(学号, 姓名, 年龄, 学院名称, 学院电话),因为存在依赖传递: (学号) → (学生)→(所在学院) → (学院电话),所有不满足第三范式。

反范式化: 常用降低范式就是增加字段,允许冗余,达到以空间换时间的目的。

常用防止 SQL 注入攻击

SQL 注入是用户输入的数据,在拼接 SQL 语句的过程中,超越了数据本身,成为了 SQL 语句查询逻辑的一部分,然后这样被拼接出来的 SQL 语句被数据库执行,产生了开发者预期之外的动作。

  1. 代码层防止 sql 注入攻击的最佳方案就是 sql 预编译
  2. 确认每种数据的类型,比如是数字,数据库则必须使用 int 类型来存储
  3. 规定数据长度,能在一定程度上防止 sql 注入
  4. 严格限制数据库权限,能最大程度减少 sql 注入的危害
  5. 避免直接响应一些 sql 异常信息,sql 发生异常后,自定义异常进行响应
  6. 过滤参数中含有的一些数据库关键词

使用 Explain 查看可优化 SQL 语句

用 explain 的方式,来看看 sql 语法,哪里可以做优化!

# 查询所有栏位
mysql> explain select * from user;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | user  | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)

# 查询添加了索引的栏位 employee_id
mysql> explain select employee_id from user;
+----+-------------+-------+------------+-------+---------------+--------------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key                | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+--------------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | index | NULL          | employee_id_UNIQUE | 62      | NULL |    3 |   100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+--------------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

# 查询所有栏位使用了where
mysql> explain select * from user where employee_id >20;
+----+-------------+-------+------------+------+--------------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys      | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+--------------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ALL  | employee_id_UNIQUE | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+--------------------+------+---------+------+------+----------+-------------+
1 row in set, 2 warnings (0.00 sec)

# 查询添加了索引的栏位 employee_id 使用where
mysql> explain select employee_id from user where employee_id >20;
+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys      | key                | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | user  | NULL       | index | employee_id_UNIQUE | employee_id_UNIQUE | 62      | NULL |    3 |    33.33 | Using where; Using index |
+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+--------------------------+
1 row in set, 2 warnings (0.00 sec)

mysql>

输出栏位说明

  • id: 没有意义
  • select_type: 查询类型,是单表查询、联合查询还是子查询等
  • table: 查询的表名
  • type: 连接使用的类型(重要项) 显示连接使用的类型,按最优到最差的类型排序
    • System
      • 表只有一行,这是一个 const type 的特殊情况
    • const
      • 使用主键或者唯一索引的时候,当查询的表仅有一行时,使用 System
    • eq_ref
      • MySQL 在连接查询时,会从最前面的数据表,对每一个记录的联合,从数据表中读取一个记录,在查询时会使用索引为主键或唯一键的全部
    • ref
      • 只有在查询使用了非唯一键或主键时才会发生
    • fulltext
      • 使用全文索引的时候才会出现
    • ref_or_null
      • 查询类型和 ref 很像,但是 MySQL 会做一个额外的查询,来看哪些行包含了 NULL。这种类型常见于解析子查询的优化
    • index_merge
      • 在一个查询里面很有多索引用被用到,可能会触发 index_merge 的优化机制
    • unique_subquery
      • 比 eq_ref 复杂的地方是使用了 in 的子查询,而且是子查询是主键或者唯一索引
    • index_subquery
      • 和 unique_subquery 类似,但是它在子查询里使用的是非唯一索引。
    • range
      • 使用索引返回一个范围的结果,例如:使用大于 > 或小于 < 查询时发生。
    • index
      • 全表扫瞄,此为针对索引中的数据进行查询,主要优点就是避免了排序,但是开销仍然非常大
    • ALL
      • 针对每一笔记录进行完全扫瞄,此为最坏的情况,应该尽量避免
  • prossible_keys: 能在该表中使用哪些索引有助于查询
  • key:实际使用的索引
  • key_len:索引的长度,在不损失精确性的情况 下,长度越短越好
  • ref:索引的哪一列被使用了
  • rows:返回的结果的行数
  • Extra:其它说明

隔离级别

脏读(Dirty Read)
不可重复读(NonRepeatable Read)
幻读(Phantom Read)

脏读 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。 一个事务中访问到了另外一个事务未提交的数据

不可重复读 是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。 那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。 这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。 一个事务读取同一条记录 2 次,得到的结果不一致(主要 update 导致)

幻读 第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。 同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。 那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。 一个事务读取 2 次,得到的记录条数不一致(主要 insert 导致)

隔离级别 脏读 不可重复读 幻读
未提交读(Read uncommitted) 可能 可能 可能
已提交读(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能

•未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据 •提交读(Read Committed):只能读取到已经提交的数据。Oracle 等多数数据库默认都是该级别 (不重复读) •可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB 默认级别。在 SQL 标准中,该隔离级别消除了不可重复读,但是还存在幻象读 •串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

当隔离级别是可重复读,且禁用 innodb_locks_unsafe_for_binlog 的情况下,在搜索和扫描 index 的时候使用的 next-key locks 可以避免幻读。

in 和 exists 孰快孰慢

-- (id为主键,name为普通索引)
select * from t1 where name not in (select name from t2);
select * from t1 where not exists (select name from t2 where t1.name=t2.name);

在使用 not in 的时候,需要保证子查询的匹配字段是非空的。如若不然,就会导致 not in 返回的整个结果集为空。 exists 返回的结果是一个 boolean 值 true 或者 false ,而不是某个结果集。因为它不关心返回的具体数据是什么,只是外层查询需要拿这个布尔值做判断。

-- 以上代码改为更佳:
select * from t1 where not exists (select 1 from t2 where t1.name=t2.name);

因为从执行效率来说,1 > column > * 。因此推荐用 select 1。(准确的说应该是常量值)

select * from t1 where id in (select id from t2);
select * from t1 where exists (select 1 from t2 where t1.id=t2.id);

外层大表内层小表,用 in。外层小表内层大表,in 和 exists 效率差不多(甚至 in 比 exists 还快,而并不是网上说的 exists 比 in 效率高)。

exists 它是以外层表为驱动表,无论如何都会循环遍历的,所以会全表扫描。而内层表通过走索引,可以快速判断当前记录是否匹配。


摘抄的一些 MySQL Q&A

(https://blog.csdn.net/Design407/article/details/108055113)

MySQL 中有哪几种锁?

(1)表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最 高,并发度最低。 (2)行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最 低,并发度也最高。 (3)页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表 锁和行锁之间,并发度一般。

MySQL 中有哪些不同的表格(表类型/存储引擎)?

  • (1)MyISAM
  • (2)MEMORY (HEAP)
  • (3)Merge
  • (4)INNODB
  • (5)ISAM
  • ……

简述在 MySQL 数据库中 MyISAM 和 InnoDB 的区别

MyISAM:

  • (1)不支持事务,但是每次查询都是原子的;
  • (2)支持表级锁,即每次操作是对整个表加锁;
  • (3)存储表的总行数;
  • (4)一个 MYISAM 表有三个文件:索引文件、表结构文件、数据文件;
  • (5)采用菲聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性。

InnoDb:

  • (1)支持 ACID 的事务,支持事务的四种隔离级别;
  • (2)支持行级锁及外键约束:因此可以支持写并发;
  • (3)不存储总行数:
  • (4)一个 InnoDb 引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多个文件里),也有可能为多个(设置为独立表空,表大小受操作系统文件大小限制,一般为 2G),受操作系统文件大小的限制;
  • (5)主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅索引查找数据,需要先通过辅索引找到主键值,再访问辅索引;最好使用自增主键,防止插入数据时,为维持 B+树结构,文件的大调整。

MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别?

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

  • (1)read uncommited :读到未提交数据
  • (2)read committed:读已提交 脏读,不可重复读
  • (3)repeatable read:可重读
  • (4)serializable :串行事物

CHAR 和 VARCHAR 的区别?

  • (1)CHAR 和 VARCHAR 类型在存储和检索方面有所不同
  • (2)CHAR 列长度固定为创建表时声明的长度,长度值范围是 1 到 255 当 CHAR 值被存储时,它们被用空格填充到特定长度,检索 CHAR 值时需删除尾随空格。

主键和候选键有什么区别?

  • 表格的每一行都由主键唯一标识,一个表只有一个主键。
  • 主键也是候选键。按照惯例,候选键可以被指定为主键,并且可以用于任何外键引用。

myisamchk 是用来做什么的?

  • 它用来获取有关数据库 table 或检查,修复或优化它们的信息。 myisamchk 与 MyISAMtable(具有.MYD 和.MYI 文件用于存储数据和索引的 table)一起使用。
  • 它用来压缩 MyISAM 表,这减少了磁盘或内存使用。
  • MyISAM Static 和 MyISAM Dynamic 有什么区别?
  • 在 MyISAM Static 上的所有字段有固定宽度。动态 MyISAM 表将具有像 TEXT,BLOB 等字段,以适应不同长度的数据类型。
  • MyISAM Static 在受损情况下更容易恢复。

如果一个表有一列定义为 TIMESTAMP,将发生什么?

  • 每当行被更改时,时间戳字段将获取当前时间戳。

列设置为 AUTO INCREMENT 时,如果在表中达到最大值,会发生什么情况?

  • 它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。 怎样才能找出最后一次插入时分配了哪个自动增量?
  • LAST_INSERT_ID 将返回由 Auto_increment 分配的最后一个值,并且不需要指定表名称。

你怎么看到为表格定义的所有索引?

索引是通过以下方式为表格定义的:

SHOW INDEX FROM <tablename>;

LIKE 声明中的%和_是什么意思?

  • 对应于 0 个或更多字符,_只是 LIKE 语句中的一个字符。

如何在 Unix 和 MySQL 时间戳之间进行转换?

  • UNIX_TIMESTAMP 是从 MySQL 时间戳转换为 Unix 时间戳的命令
  • FROM_UNIXTIME 是从 Unix 时间戳转换为 MySQL 时间戳的命令

列对比运算符是什么?

在 SELECT 语句的列比较中使用=,<>,<=,<,> =,>,<<,>>,<=>,AND,OR 或 LIKE 运算符。

BLOB 和 TEXT 有什么区别?

  • BLOB 是一个二进制对象,可以容纳可变数量的数据。TEXT 是一个不区分大小写的 BLOB。
  • BLOB 和 TEXT 类型之间的唯一区别在于对 BLOB 值进行排序和比较时区分大小写,对 TEXT 值不区分大小写。

MySQL_fetch_array 和 MySQL_fetch_object 的区别是什么?

  • MySQL_fetch_array() – 将结果行作为关联数组或来自数据库的常规数组返回。
  • MySQL_fetch_object – 从数据库返回结果行作为对象。

MyISAM 表格将在哪里存储,并且还提供其存储格式?

每个 MyISAM 表格以三种格式存储在磁盘上:

  • (1)·“.frm”文件存储表定义
  • (2)·数据文件具有“.MYD”(MYData)扩展名
  • (3)索引文件具有“.MYI”(MYIndex)扩展名

MySQL 如何优化 DISTINCT?

DISTINCT 在所有列上转换为 GROUP BY,并与 ORDER BY 子句结合使用。

SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;

如何显示前 50 行?

在 MySQL 中,使用以下代码查询显示前 50 行:

SELECT * FROM
LIMIT 0,50;

可以使用多少列创建索引?

(https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html) (https://dev.mysql.com/doc/refman/8.0/en/myisam-storage-engine.html)

  • innoDB:
    • 一个表最多可以包含 1017 列。虚拟生成的列包含在此限制中。
    • 一个表最多可以包含 64 个 二级索引,
    • InnoDB 对于使用 DYNAMIC 或 COMPRESSED 行格式 的表,索引键前缀长度限制为 3072 字节 。
    • 多列索引最多允许 16 列。超过限制会返回错误。
  • mysiam
    • 最多 4096 列,
    • 最多 64 个二级索引, 单个索引最多包含 16 列, 索引最大长度 1000 字节, 行大小最大 65536 字节

NOW()CURRENT_DATE()有什么区别?

NOW()命令用于显示当前年份,月份,日期,小时,分钟和秒。

CURRENT_DATE()仅显示当前年份,月份和日期。

什么是非标准字符串类型?

  • (1)TINYTEXT
  • (2)TEXT
  • (3)MEDIUMTEXT
  • (4)LONGTEXT

什么是通用 SQL 函数?

  • (1)CONCAT(A, B) – 连接两个字符串值以创建单个字符串输出。通常用于将两个或多个字段合并为一个字段。
  • (2)FORMAT(X, D)- 格式化数字 X 到 D 有效数字。
  • (3)CURRDATE(), CURRTIME()- 返回当前日期或时间。
  • (4)NOW() – 将当前日期和时间作为一个值返回。
  • (5)MONTH(),DAY(),YEAR(),WEEK(),WEEKDAY() – 从日期值中提取给定数据。
  • (6)HOUR(),MINUTE(),SECOND() – 从时间值中提取给定数据。
  • (7)DATEDIFF(A,B) – 确定两个日期之间的差异,通常用于计算年龄
  • (8)SUBTIMES(A,B) – 确定两次之间的差异。
  • (9)FROMDAYS(INT) – 将整数天数转换为日期值。

MySQL 支持事务吗?

  • 在缺省模式下,MySQL 是 autocommit 模式的,所有的数据库更新操作都会即时提交,所以在缺省情况下,MySQL 是不支持事务的。
  • 但是如果你的 MySQL 表类型是使用 InnoDB Tables 或 BDB tables 的话,你的 MySQL 就可以使用事务处理,
    • 使用 SETAUTOCOMMIT=0 就可以使 MySQL 允许在非 autocommit 模式,
    • 在非 autocommit 模式下,你必须使用 COMMIT 来提交你的更改,或者用 ROLLBACK 来回滚你的更改。

MySQL 里记录货币用什么字段类型好

NUMERIC 和 DECIMAL 类型被 MySQL 实现为同样的类型,这在 SQL92 标准允许。 他们被用于保存值,该值的准确精度是极其重要的值,例如与金钱有关的数据。 当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定。

例如:

salary DECIMAL(9,2)

在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而 2(scale)代 表将被用于存储小数点后的位数。

因此,在这种情况下,能被存储在 salary 列中的值的范围是从-9999999.99 到 9999999.99。

MySQL 有关权限的表都有哪几个?

MySQL 服务器通过权限表来控制用户对数据库的访问,权限表存放在 MySQL 数据库里,由 MySQL_install_db 脚本初始化。这些权限表分别 user,db,table_priv,columns_priv 和 host。

列的字符串类型可以是什么?

字符串类型是:

  • (1)SET
  • (2)BLOB
  • (3)ENUM
  • (4)CHAR
  • (5)varchar
  • (6)TEXT

锁的优化策略

  • (1)读写分离
  • (2)分段加锁
  • (3)减少锁持有的时间
  • (4)多个线程尽量以相同的顺序去获取资源

不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。

索引的底层实现原理和优化

B+树,经过优化的 B+树

主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此 InnoDB 建议为大部分表使用默认自增的主键作为主索引。

什么情况下设置了索引但无法使用

  • (1)以“%”开头的 LIKE 语句,模糊匹配
  • (2)OR 语句前后没有同时使用索引
  • (3)数据类型出现隐式转化(如 varchar 不加单引号的话可能会自动转换为 int 型)

简单描述 MySQL 中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)

  • 索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
  • 普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的访问速度。
  • 普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字 UNIQUE 把它定义为一个唯一索引。也就是说,唯一索引可以保证数据记录的唯一性。
  • 主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字 PRIMARY KEY 来创建。
  • 索引可以覆盖多个数据列,如像 INDEX(columnA, columnB)索引,这就是联合索引。
  • 索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件。

数据库中的事务是什么?

事务(transaction)是作为一个单元的一组有序的数据库操作。 如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。 如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。 如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。

事务特性(ACID):

  • (1)原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。
  • (2)一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态。
  • (3)隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务。
  • (4)持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。

或者这样理解:

事务就是被绑定在一起作为一个逻辑工作单元的 SQL 语句分组, 如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。 为了确保要么执行,要么不执行,就可以使用事务。 要将有组语句作为事务考虑,就需要通过 ACID 测试,即原子性,一致性,隔离性和持久性。

SQL 注入漏洞产生的原因?如何防止?

SQL 注入产生的原因:程序开发过程中不注意规范书写 sql 语句和对特殊字符进行过滤,导致客户端可以通过全局变量 POST 和 GET 提交一些 sql 语句正常执行。

防止 SQL 注入的方式:

  • 开启配置文件中的 magic_quotes_gpcmagic_quotes_runtime 设置
  • 执行 sql 语句时使用 addslashes 进行 sql 语句转换
  • Sql 语句书写尽量不要省略双引号和单引号。
  • 过滤掉 sql 语句中的一些关键词:update、insert、delete、select、 * 。
  • 提高数据库表和字段的命名技巧,对一些重要的字段根据程序的特点命名,取不易被猜到的。

为表中得字段选择合适得数据类型

字段类型优先级: 整形>date,time>enum,char>varchar>blob,text

优先考虑数字类型,其次是日期或者二进制类型,最后是字符串类型,同级别得数据类型,应该优先选择占用空间小的数据类型

存储时期

Datatime: 以 YYYY-MM-DD HH:MM:SS 格式存储时期时间,精确到秒,占用 8 个字节得存储空间,datatime 类型与时区无关

Timestamp:以时间戳格式存储,占用 4 个字节,范围小 1970-1-1 到 2038-1-19,显示依赖于所指定得时区,默认在第一个列行的数据修改时可以自动得修改 timestamp 列得值

Date: 占用得字节数比使用字符串.datatime.int 储存要少,使用 date 只需要 3 个字节,存储日期月份,还可以利用日期时间函数进行日期间得计算

Time: 存储时间部分得数据

注意: 不要使用字符串类型来存储日期时间数据(通常比字符串占用得储存空间小,在进行查找过滤可以利用日期得函数)

使用 int 存储日期时间不如使用 timestamp 类型

对于关系型数据库而言,索引是相当重要的概念,请回答有关索引的几个问题:

  • (1)索引的目的是什么?
    • 快速访问数据表中的特定信息,提高检索速度
    • 创建唯一性索引,保证数据库表中每一行数据的唯一性。
    • 加速表和表之间的连接
    • 使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间
  • (2)索引对数据库系统的负面影响是什么?
    • 创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;
    • 索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;
    • 当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。
  • (3)为数据表建立索引的原则有哪些?
    • 在最频繁使用的、用以缩小查询范围的字段上建立索引。
    • 在频繁使用的、需要排序的字段上建立索引
  • (4)什么情况下不宜建立索引?
    • 对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。
    • 对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等

解释 MySQL 外连接、内连接与自连接的区别

先说什么是交叉连接: 交叉连接又叫笛卡尔积,它是指不使用任何条件,直接将一个表的所有记录和另一个表中的所有记录一一匹配。

内连接

  • 则是只有条件的交叉连接,根据某个条件筛选出符合条件的记录,不符合条件的记录不会出现在结果集中,即内连接只连接匹配的行。

外连接

  • 其结果集中不仅包含符合连接条件的行,而且还会包括左表、右表或两个表中的所有数据行,这三种情况依次称之为左外连接,右外连接,和全外连接。

左外连接

  • 也称左连接,左表为主表,左表中的所有记录都会出现在结果集中,对于那些在右表中并没有匹配的记录,仍然要显示,右边对应的那些字段值以 NULL 来填充。 右外连接
  • 也称右连接,右表为主表,右表中的所有记录都会出现在结果集中。左连接和右连接可以互换,MySQL 目前还不支持全外连接。

Myql 中的事务回滚机制概述

事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位,事务回滚是指将该事务已经完成的对数据库的更新操作撤销。

要同时修改数据库中两个不同表时,如果它们不是一个事务的话,当第一个表修改完,可能第二个表修改过程中出现了异常而没能修改,此时就只有第二个表依旧是未修改之前的状态,而第一个表已经被修改完毕。而当你把它们设定为一个事务的时候,当第一个表修改完,第二表修改出现异常而没能修改,第一个表和第二个表都要回到未修改的状态,这就是所谓的事务回滚

SQL 语言包括哪几部分?每部分都有哪些操作关键字?

SQL 语言包括数据定义(DDL)、数据操纵(DML),数据控制(DCL)和数据查询(DQL) 四个部分。

数据定义:

  • Create Table,Alter Table,Drop Table, Craete/Drop Index 等

数据操纵:

  • Select ,insert,update,delete,

数据控制:

  • grant,revoke

数据查询:

  • select

完整性约束包括哪些?

数据完整性(Data Integrity)是指数据的精确(Accuracy)和可靠性(Reliability)。

分为以下四类:

  • (1)实体完整性:
    • 规定表的每一行在表中是惟一的实体。
  • (2)域完整性:
    • 是指表中的列必须满足某种特定的数据类型约束,其中约束又包括取值范围、精度等规定。
  • (3)参照完整性:
    • 是指两个表的主关键字和外关键字的数据应一致,保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据库中扩散。
  • (4)用户定义的完整性:
    • 不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。
    • 用户定义的完整性即是针对某个特定关系数据库的约束条件,它反映某一具体应用必须满足的语义要求。

与表有关的约束: 包括列约束(NOT NULL(非空约束))和表约束(PRIMARY KEY、foreign key、check、UNIQUE) 。

什么是锁?

数据库是一个多用户使用的共享资源。 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。 若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。 当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。 加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

基本锁类型:锁包括行级锁和表级锁

什么叫视图?游标是什么?

视图是一种虚拟的表,具有和物理表相同的功能。 可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。 对视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。

游标:是对查询出来的结果集作为一个单元来有效的处理。 游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。 一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。

什么是基本表?什么是视图?

基本表是本身独立存在的表,在 SQL 中一个关系就对应一个表。 视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库中,是一个虚表

试述视图的优点?

  • (1) 视图能够简化用户的操作
  • (2) 视图使用户能以多种角度看待同一数据;
  • (3) 视图为数据库提供了一定程度的逻辑独立性;
  • (4) 视图能够对机密数据提供安全保护。

什么是存储过程?用什么来调用?

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

如何通俗地理解三个范式?

第一范式:1NF 是对属性的原子性约束,要求属性具有原子性,不可再分解; 第二范式:2NF 是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性; 第三范式:3NF 是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。。

范式化设计优缺点: 优点:可以尽量得减少数据冗余,使得更新快,体积小 缺点:对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引优化

反范式化: 优点:可以减少表得关联,可以更好得进行索引优化 缺点:数据冗余以及数据异常,数据得修改需要更多的成本

NULL 是什么意思

NULL 这个值表示 UNKNOWN(未知):它不表示“”(空字符串)。 对 NULL 这个值的任何比较都会生产一个 NULL 值。 您不能把任何值与一个 NULL 值进行比较,并在逻辑上希望获得一个答案。

使用 IS NULL 来进行 NULL 判断

主键、外键和索引的区别?

定义:

  • 主键——唯一标识一条记录,不能有重复的,不允许为空
  • 外键——表的外键是另一表的主键, 外键可以有重复的, 可以是空值
  • 索引——该字段没有重复值,但可以有一个空值

作用:

  • 主键——用来保证数据完整性
  • 外键——用来和其他表建立联系用的
  • 索引——是提高查询排序的速度

个数:

  • 主键—— 主键只能有一个
  • 外键—— 一个表可以有多个外键
  • 索引—— 一个表可以有多个唯一索引

你可以用什么来确保表格里的字段只接受特定范围里的值?

  • Check 限制,它在数据库表格里被定义,用来限制输入该列的值。
  • 触发器也可以被用来限制数据库表格里的字段能够接受的值,
    • 但是这种办法要求触发器在表格里被定义,这可能会在某些情况下影响到性能。

MySQL 数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?

  • (1)设计良好的数据库结构,允许部分数据冗余,尽量避免 join 查询,提高效率。
  • (2)选择合适的表字段数据类型和存储引擎,适当的添加索引。
  • (3)MySQL 库主从读写分离。
  • (4)找规律分表,减少单表中的数据量提高查询速度。
  • (5)添加缓存机制,比如 memcached,apc 等。
  • (6)不经常改动的页面,生成静态页面。
  • (7)书写高效率的 SQL。比如 SELECT * FROM TABEL 改为 SELECT field_1, field_2, field_3 FROM TABLE.

实践中如何优化 MySQL

最好是按照以下顺序优化:

  • (1)SQL 语句及索引的优化
  • (2)数据库表结构的优化
  • (3)系统配置的优化
  • (4)硬件的优化

优化数据库的方法

  • (1)选取最适用的字段属性,尽可能减少定义字段宽度,尽量把字段设置 NOTNULL,例如’省份’、’性别’最好适用 ENUM
  • (2)使用连接(JOIN)来代替子查询
  • (3)适用联合(UNION)来代替手动创建的临时表
  • (4)事务处理
  • (5)锁定表、优化事务处理
  • (6)适用外键,优化锁定表
  • (7)建立索引
  • (8)优化查询语句

说说对 SQL 语句优化有哪些方法?(选择几条)

  • (1)Where 子句中:where 表之间的连接必须写在其他 Where 条件之前,那些可以过滤掉最大数量记录的条件必须写在 Where 子句的末尾.HAVING 最后。
  • (2)用 EXISTS 替代 IN、用 NOT EXISTS 替代 NOT IN。
  • (3) 避免在索引列上使用计算
  • (4)避免在索引列上使用 IS NULL 和 IS NOT NULL
  • (5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
  • (6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
  • (7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描

(https://zhuanlan.zhihu.com/p/23713529)

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

存储过程是一些预编译的 SQL 语句。

更加直白的理解: 存储过程可以说是一个记录集,它是由一些 T-SQL 语句组成的代码块, 这些 T-SQL 语句代码像一个方法一样实现一些功能(对单表或多表的增删改查), 然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了。

存储过程是一个预编译的代码块,执行效率比较高 一个存储过程替代大量 T_SQL 语句 ,可以降低网络通信量,提高通信速率 可以一定程度上确保数据安全 如果你对存储过程不熟悉,建议阅读:存储过程详解-博客园

(二)索引是什么?有什么作用以及优缺点?

索引是对数据库表中一或多个列的值进行排序的结构,是帮助 MySQL 高效获取数据的数据结构

你也可以这样理解:索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。 在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。 在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。

MySQL 数据库几个基本的索引类型:普通索引、唯一索引、主键索引、全文索引

索引加快数据库的检索速度 索引降低了插入、删除、修改等维护任务的速度 唯一索引可以确保每一行数据的唯一性 通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能 索引需要占物理和数据空间 如果你对索引还不太熟悉,建议阅读:漫谈数据库索引

(三)什么是事务?

事务(Transaction)是并发控制的基本单位。 所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。 事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。

(四)数据库的乐观锁和悲观锁是什么?

数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。

乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。

(五) 使用索引查询一定能提高查询的性能吗?为什么

通常,通过索引查询数据比全表扫描要快.但是我们也必须注意到它的代价.

  • 索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时,索引本身也会被修改.
    • 这意味着每条记录的 INSERT,DELETE,UPDATE 将为此多付出 4,5 次的磁盘 I/O.
  • 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.

使用索引查询不一定能提高查询性能,索引范围查询(INDEX RANGE SCAN)适用于两种情况:

  • 基于一个范围的检索,一般查询返回结果集小于表中记录数的 30%
  • 基于非唯一性索引的检索

(六)简单说一说 drop、delete 与 truncate 的区别

SQL 中的 drop、delete、truncate 都表示删除,但是三者有一些差别

  • delete 和 truncate 只删除表的数据不删除表的结构
  • 速度,一般来说: drop> truncate >delete
  • delete 语句是 dml,这个操作会放到 rollback segement 中,事务提交之后才生效;
    • 如果有相应的 trigger,执行的时候将被触发.
  • truncate,drop 是 ddl, 操作立即生效,原数据不放到 rollback segment 中,不能回滚. 操作不触发 trigger.

(七)drop、delete 与 truncate 分别在什么场景之下使用?

不再需要一张表的时候,用 drop 想删除部分数据行时候,用 delete,并且带上 where 子句 保留表而删除所有数据的时候用 truncate

(八) 超键、候选键、主键、外键分别是什么?

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

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

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

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

(九)什么是视图?以及视图的使用场景有哪些?

https://dev.mysql.com/doc/refman/8.0/en/view-updatability.html

视图是一种虚拟的表,具有和物理表相同的功能。 可以对视图进行增,改,查,操作,试图通常是有一个表或者多个表的行或列的子集。 它使得我们获取数据更容易,相比多表查询。

普通视图本身是没有数据的,你可以理解为它只是一个 sql 查询语句的名称,为了简化 sql 而用的, 你查询这个视图,实际上是执行的视图内部的 sql 查询,所以不存在所谓的数据同步。

当你直接修改视图数据,如果能修改成功的话,实际上是直接修改的基础表数据。

大多数视图由于关联了很多表或者使用了聚合,是无法通过 update、insert、delete 视图来修改数据的

只暴露部分字段给访问者,所以就建一个虚表,就是视图。 查询的数据来源于不同的表,而查询者希望以统一的方式查询,这样也可以建立一个视图,把多个表查询结果联合起来,查询者只需要直接从视图中获取数据,不必考虑数据来源于不同表所带来的差异

(十)说一说三个范式。

第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。

第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。

第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。 所谓传递函数依赖,指的是如 果存在"A → B → C"的决定关系,则 C 传递函数依赖于 A。 因此,满足第三范式的数据库表应该不存在如下依赖关系: 关键字段 → 非关键字段 x → 非关键字段 y


(https://github.com/DmrfCoder/interview/blob/master/DataBase/DataBase常见面试题.md)

MySQL 有哪些日志,分别是什么用处?

mysql 日志一般分为 5 种

错误日志:-log-err (记录启动,运行,停止 mysql 时出现的信息) 二进制日志:-log-bin (记录所有更改数据的语句,还用于复制,恢复数据库用) 查询日志:-log (记录建立的客户端连接和执行的语句) 慢查询日志: -log-slow-queries (记录所有执行超过 long_query_time 秒的所有查询) 更新日志: -log-update (二进制日志已经代替了老的更新日志,更新日志在 MySQL5.1 中不再使用)

除传统的关系型数据库之外,有哪些 NoSQL 数据库?

Memcached:分布式内存对象缓存系统,可以与 MySQL 数据库协同使用。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的访问速度。Memcached 基于一个存储键/值对的 HashMap。Memcached 可以用于解决数据读的性能,但是对写操作不能有提高。 Redis:基于内存亦可持久化的日志型、Key-Value 数据库。和 Memcached 类似,但是它支持存储的 value 类型相对更多。同时可以实现主从同步,即分布式。 MongoDB:基于分布式文件存储的数据库。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似 json 的 bson 格式,因此可以存储比较复杂的数据类型。 HBase:是一个分布式的、面向列的开源数据库。HBase 是 Apache 的 Hadoop 项目的子项目。HBase 不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是 HBase 基于列的而不是基于行的模式。

视图由多个表连接而成,可以对视图进行插入操作么?

若视图是由两个以上基本表导出的,则此视图不允许更新。 若视图的字段来自字段表达式或常数,则不允许对视图执行 INSTER 和 UPDATE 操作,但允许 delete。 若视图的字段来自聚集函数,则此视图不允许更新。 若视图中含有 GROUP by 子句,则此视图不允许更新。 若视图中含有 DISTINCT 短语,则此视图不允许更新。. 若视图定义中有嵌套查询,并且内层查询的 FROM 子句中涉及的表也是导出该视图的基本表,则此视图不允许更新。. 一个不允许更新的视图上定义的视图不允许更新。

UNION 和 UNION ALL 有什么区别?

UNION 用于 合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。 UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

UNION ALL 基本使用和 UNION 是一致的,但是 UNION ALL 不会消除表中的重复行。

主键和唯一键有什么区别?

主键不能重复,不能为空,唯一键不能重复,可以为空。 建立主键的目的是让外键来引用。 一个表最多只有一个主键,但可以有很多唯一键。

MySQL 中空值和 NULL 的区别?

空值('')是不占用空间的,判断空字符用 = '' 或者 <> '' 来进行处理。 NULL 值是未知的,且占用空间,不走索引;判断 NULL 用 IS NULL 或者 is not null ,SQL 语句函数中可以使用 ifnull ()函数来进行处理。 无法比较 NULL 和 0;它们是不等价的。 无法使用比较运算符来测试 NULL 值,比如 =, <, 或者 <>。 NULL 值可以使用 <=> 符号进行比较,该符号与等号作用相似,但对 NULL 有意义。 进行 count ()统计某列的记录数的时候,如果采用的 NULL 值,会别系统自动忽略掉,但是空值是统计到其中。


ref:

tidb