MongoDB
介绍一下MongoDB
MongoDB 是一个高性能,开源,无模式的文档型数据库
,开发语言是C++。它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。
基本术语
SQL术语 | MongoDB术语 | 解释说明 |
---|---|---|
database | database | 数据库 |
table | collecion | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id设置为主键 |
将文档类比成数据库中的行,那么集合就可以类比成数据库的表
MySQL
主键 超键 候选键 外键
主键:数据库表中对存储数据对象予以唯一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null).
主键 : 表中每一行中可以唯一标识自己的一列(或一组列)。
超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键。
候选键:是最小超键,即没有冗余元素的超键。
外键:在一个表中存在的另一个表的主键称此表的外键。
MyISAM 与 InnoDB 区别
- InnoDB 支持事务,MyISAM 不支持,这一点是非常之重要。
- MyISAM 适合查询以及插入为主的应用,InnoDB 适合频繁修改以及涉及到安全性较高的应用;
- InnoDB 支持外键,MyISAM 不支持;
- 对于自增长的字段,InnoDB 中必须包含只有该字段的索引,但是在 MyISAM表中可以和其他字段一起建立联合索引;
- 清空整个表时,InnoDB 是一行一行的删除,效率非常慢。MyISAM 则会重建表;
MySQL常见数据库引擎及比较?
- InnoDB
支持事务、支持表锁、行锁(for update)
表锁:select * from tb for update
行锁:select id,name from tb where id=2 for update - MyISAM
查询速度快、全文索引、支持表锁
表锁:select * from tb for update - NDB
高可用、 高性能、高可扩展性的数据库集群系统 - Memory
默认使用的是哈希索引
Mysql怎么限制IP访问
1 | grant all privileges on . to "数据库中用户名“ @"ip地址" identified by "数据库密码"; |
什么是事务?MySQL如何支持事务?
数据库事务 ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
Mysql实现事务
InnoDB支持事务,MyISAM不支持
1 | # start transaction 手动开启事务 |
事务的特性
- 原子性
事务中的全部操作在数据库中是不分隔的,要么全部完成,要么均不执行 - 隔离型
事务的执行不受其他事务的干扰。 - 持久性
一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。 - 一致性
事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
数据库三范式
- 第一范式,基本上所有数据库的范式都是符合第一范式的,符合第一范式的表具有以下几个特点:
数据库表中的所有字段都只具有单一属性,单一属性的列是由基本的数据类型(整型,浮点型,字符型等)所构成的设计出来的表都是简单的二比表 - 第二范式,要求一个表中只具有一个业务主键,也就是说符合第二范式的表中不能存在非主键列对只对部分主键的依赖关系
- 第三范式,指每一个非主属性既不部分依赖与也不传递依赖于业务主键,也就是第二范式的基础上消除了非主属性对主键的传递依赖
- 每列保持原子性
- 表中的每列都是和主键相关
- 每列都和主键直接相关,而不是间接相关
数据库五大约束
primary key:设置主键约束;
unique:设置唯一性约束,不能有重复值;
default:默认值约束
not null:设置非空约束,该字段不能为空;
foreign key:设置外键约束。
简述触发器、函数、视图、存储过程?
触发器:
对数据库某张表的增加
、删除
,修改
前后定义一些操作函数:(触发函数是通过select)
聚合函数:max/sum/min/avg
时间格式化:date_format
字符串拼接:concat存储过程:
- 一组为了完成特定功能的SQL语句集,经编译后存储在数据库。
- 用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
- 存储过程在创建时即在服务器上进行编译,所以执行起来比单个SQL语句快,因为调用存储过程比直接向服务端发送大量SQL语句在执行速度快。
- 参数类型:
- in 只将参数传进去
- out 只拿结果
- inout 既可以传,可以取
函数与存储过程区别:本质上没区别。
- 函数只能返回一个变量。而存储过程可以返回多个。
- 函数是可以嵌入在sql中使用的,可以在select中调用,而存储过程不行。
- 存储过程可以调用函数。但函数不能调用存储过程。
视图:
视图是一个虚拟表,不是真实存在的(只能查,不能改)
视图的作用,视图可以更改么
- 视图是虚拟的表,视图只包含使用时动态检索数据的查询;不包含任何列或数据。
- 使用视图可以简化复杂的sql操作,隐藏具体的细节,保护数据;
- 视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新。
MySQL索引种类
- 普通索引 : 加速查找
- 唯一索引 : 加速查找 + 约束(不能重复)
- 主键索引 : 加速查找 + 约束(不能重复 + 不能为空)
- 组合索引 : 多个列创建索引
- 全文索引 : 查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎
索引在什么情况下遵循最左前缀的规则?
组合索引
1 | ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age); |
最左前缀:顾名思义,就是最左优先,上例中我们创建了lname_fname_age多列索引,相当于创建了(lname)
单列索引,(lname,fname)
组合索引以及(lname,fname,age)
组合索引。
所以在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。
列举创建索引但是无法命中索引的8种情况。
like ‘%xx’
1
select * from tb1 where name like '%cn';
使用函数
1
select * from tb1 where reverse(name) = 'wupeiqi';
or
1
select * from tb1 where nid = 1 or email = 'seven@live.com';
特别的:当or条件中有未建立索引的列才失效,以下会走索引
1
2select * from tb1 where nid = 1 or name = 'seven';
select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'类型不一致
如果列是字符串类型,传入条件是必须用引号引起来,不然…1
select * from tb1 where name = 999;
!=
1
select * from tb1 where name != 'alex'
特别的:如果是主键,则还是会走索引
1
select * from tb1 where nid != 123
>
1
select * from tb1 where name > 'alex'
特别的:如果是主键或索引是整数类型,则还是会走索引
1
2select * from tb1 where nid > 123
select * from tb1 where num > 123order by
1
select email from tb1 order by name desc;
特别的:当根据索引排序时候,选择的映射如果不是索引,则不走索引
特别的:如果对主键排序,则还是走索引:1
select * from tb1 order by nid desc;
drop,delete与truncate的区别
- drop直接删掉表,
- truncate删除表中数据,再插入时自增长id又从1开始,
- delete删除表中数据,可以加where字句。
如何基于数据库实现商城商品计数器?
假设有一个计数器表,只有一行数据,记录网站的点击次数。
1 | CREATE TABLE hit_counter( cnt int unsigned not null ) ENGINE=InnoDB; |
网站的每次点击都会导致对计数器的更新:
1 | UPDATE hit_counter SET cnt = cnt + 1; |
那么问题出现了,对于任何想要更新这一行的事务来说,这条记录上都有全局的互斥锁。这会使得这些事务只能串行执行。
将计数其保存在多行中,每次随机选择一行进行更新,这样需要对计数器表作如下修改:
1 | CREATE TABLE hit_counter( |
然后在这张数据表中增加100条数据。现在选择一个随机的槽(slot)进行更新:
1 | UPDATE hit_counter SET cnt = cnt + 1 where slot = RAND() * 100; |
要获得统计结果,使用具和函数sum()进行查询:
1 | SELECT SUM( cnt ) FROM hit_counter; |
简述乐观锁和悲观锁
- 悲观锁, 就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。
传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。 - 乐观锁,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制,乐观锁适用于多读的应用类型,这样可以提高吞吐量
Redis
介绍一下Redis
Redis 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
Redis五大数据类型
- 字符串String
- 列表List
- 集合Set
- 哈希Hash
- 有序集合Zset(sorted set)