1.NoSQL,指的是非关系型的数据库。NoSQL 有时也称作 Not Only SQL 的缩写,是对不同于传统的关系 型数据库的数据库管理系统的统称。
2.NoSQL 用于超大规模数据的存储。(例如谷歌或 Facebook 每天为 他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,
无需多余操作就可以横向扩展。
1.NoSQL,指的是非关系型的数据库。NoSQL 有时也称作 Not Only SQL 的缩写,是对不同于传统的关系 型数据库的数据库管理系统的统称。
2.NoSQL 用于超大规模数据的存储。(例如谷歌或 Facebook 每天为 他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,
无需多余操作就可以横向扩展。
1、需要一个文件存储系统(RDBMS)
2、需要一个程序实例(对存储系统进行逻辑管理)
包括:存储管理、缓存机制、SQL解析、日志管理、权限划分、容灾机制、索引管理、锁管理
规范书写:
(1) FROM < left_table>
(2) ON < join_condition>
(3) < join_type> JOIN < right_table>
(4) WHERE < where_condition>
(5) GROUP BY < group_by_list>
(6) WITH {cube | rollup}
(7) HAVING < having_condition>
(8) SELECT (9) DISTINCT (11) < top_specification> < select_list>
(10) ORDER BY < order_by_list>
1.基本查询
select *(列名) from table_name(表名) where column_name operator value;
select DISTINCT 列名称 from表名称--------------------去重
条件举例:
stockname = 'str_name' or stockpath = 'stock_path' or stocknumber < 1000 and stockindex = 24 not stock*** = 'man'
stocknumber between 20 and 100
stocknumber in(10,20,30)
2.通配符
--------- 只能在使用like关键字的where子句中使用通配符)
语法
SELECT column_name(s)
FROM table_name
WHERE column_name LIKE pattern
通配符 描述
% 替代一个或多个字符
_ 仅替代一个字符
[charlist] 字符列中的任何单一字符
[^charlist]或者[!charlist] 不在字符列中的任何单一字符
举例:stockname like '% find this %'
stockname like '[a-zA-Z]%' --------- ([]指定值的范围)
stockname like '[^F-M]%' --------- (^排除指定范围)
stockname not like '[^F-M]%' --------- (not)
3.排序
order by stockid desc(asc) --------- by列名,desc-降序,asc-升序
order by 1,2 --------- by列号
order bY stockid DESC, stockname ASC ---------------------id降序 name升序
4.TOP子句
TOP 子句用于规定要返回的记录的数目。对于拥有数千条记录的大型表来说,TOP 子句是非常有用的。
通用
SELECT TOP 2 * FROM Persons
SELECT TOP 50 PERCENT * FROM Persons
MySQL 语法
SELECT column_name(s) FROM table_name LIMIT number
Oracle 语法
SELECT column_name(s) FROM table_name WHERE ROWNUM <= number
5.别名
通过使用 SQL,可以为列名称和表名称指定别名(Alias)。
表的 SQL Alias 语法
SELECT column_name(s) FROM table_name AS alias_name
列的 SQL Alias 语法
SELECT column_name AS alias_name FROM table_name
使用表名称别名
SELECT po.OrderID, p.LastName, p.FirstName
FROM Persons AS p, Product_Orders AS po
WHERE p.LastName='Adams' AND p.FirstName='John'
6.表的连接
inner join 表示内连接
Select a.id,a.name,b.name from dave a inner join bl b on a.id=b.id;
注意 a,b <=> a jion b <=> a inner jion b
nature join 自然连接
自然连接是在两张表中寻找那些数据类型和列名都相同的字段,然后自动地将他们连接起来,并返回所有符合条件按的结果。
Select id,name from dave a natural join bl b
left join表示左外连接
Select id,name from dave a natural join bl b
right join表示右外连接;
select * from dave a right join bl b on a.id = b.id
full join表示完全外连接;
select * from dave a full join bl b on a.id = b.id;
on子句 用于指定连接条件。
7.组函数
聚合函数是对一组值执行计算并返回单一的值的函数,它经常与SELECT语GROUP BY子句一同使用
1. AVG 返回指定组中的平均值,空值被忽略。
例:select prd_no,avg(qty) from sales group by prd_no
2. COUNT 返回指定组中项目的数量。
例:select count(prd_no) from sales
3. MAX 返回指定数据的最大值。
例:select prd_no,max(qty) from sales group by prd_no
4. MIN 返回指定数据的最小值。
例:select prd_no,min(qty) from sales group by prd_no
5. SUM 返回指定数据的和,只能用于数字列,空值被忽略。
例:select prd_no,sum(qty) from sales group by prd_no
6. COUNT_BIG 返回指定组中的项目数量,与COUNT函数不同的是COUNT_BIG返回bigint值,而COUNT返回的是int值。
例:select count_big(prd_no) from sales
7. GROUPING 产生一个附加的列,当用CUBE或ROLLUP运算符添加行时,输出值为1.当所添加的行不是由CUBE或ROLLUP产生时,输出值为0.
例:select prd_no,sum(qty),grouping(prd_no) from sales group by prd_no with rollup
8. BINARY_CHECKSUM 返回对表中的行或表达式列表计算的二进制校验值,用于检测表中行的更改。
例:select prd_no,binary_checksum(qty) from sales group by prd_no
9. CHECKSUM_AGG 返回指定数据的校验值,空值被忽略。
例:select prd_no,checksum_agg(binary_checksum(*)) from sales group by prd_no
10. CHECKSUM 返回在表的行上或在表达式列表上计算的校验值,用于生成哈希索引。
11. STDEV 返回给定表达式中所有值的统计标准偏差。
例:select stdev(prd_no) from sales
12. STDEVP 返回给定表达式中的所有值的填充统计标准偏差。
例:select stdevp(prd_no) from sales
13. VAR 返回给定表达式中所有值的统计方差。
例:select var(prd_no) from sales
14. VARP 返回给定表达式中所有值的填充的统计方差。
例:select varp(prd_no) from sales
8.子查询
1、单行子查询
select ename,deptno,sal
from emp
where deptno=(select deptno from dept where loc='NEW YORK');
2、多行子查询
SELECT ename,job,sal
FROM EMP
WHERE deptno in ( SELECT deptno FROM dept WHERE dname LIKE 'A%');
3、多列子查询
SELECT deptno,ename,job,sal
FROM EMP
WHERE (deptno,sal) IN (SELECT deptno,MAX(sal) FROM EMP GROUP BY deptno);
9.having
HAVING对由sum或其它集合函数运算结果的输出进行限制。
比如,我们可能只希望看到Store_Information数据表中销售总额超过1500美圆的商店的信息,这时我们就需要使用HAVING从句。语法格式为:
SELECT "column_name1", SUM("column_name2")
FROM "table_name"
GROUP BY "column_name1"
HAVING (arithematic function condition)
(GROUP BY从句可选)
SQL语言中设定集合函数的查询条件时使用HAVING从句而不是WHERE从句。通常情况下,HAVING从句被放置在SQL命令的结尾处。
10.sql语句执行顺序
(1).FROM 子句 组装来自不同数据源的数据
(2).WHERE 子句 基于指定的条件对记录进行筛选
(3).GROUP BY 子句 将数据划分为多个分组
(4).使用聚合函数进行计算
(5).使用HAVING子句筛选分组
(6).计算所有的表达式
(7).使用ORDER BY对结果集进行排序
Mysql 查询语句大全
\1.两表之间的查询,例如:查询员工表中部门号与部门表中部门号相等
select * from tb_emp ,tb_dept where tb_emp.deptno=tb_dept.deptno;
(这是同时显示两张表中相等的depton 所有字段)(tb_emp ,tb_dept这都是表名)
2.select tb_e.deptno from tb_e, tb_d where tb_e.deptno=tb_d.deptno;
(这是只显示员工表中的tb_e.deptno,并且条件是员工表中部门号与部门表中部门号相等)
3.给字段取别名
select product_price*12 totsl_product_price from productinfo;
等价select product_price*12 from productinfo;
也可以这样写 select product_price*12 " totsl product_price" from productinfo;
有特殊的字符时用双引号的方法,(特殊字符是:中文,日文,分号等)(totsl product_price是 product_price*12)
****** 0 和空 还有空格不是一个概念
例如:
select * from emp where description is null;
select * from emp where description =0;
select * from emp where description ='空格';
查询的结果都市不一样的。
distinct 关键字可以查询结果中清除重复的行,他的作用范围是后面的所有字段的组合;
例如:
select distinct deptno ,deptname from emp where deptno=23;
totsl_product_price是product_price的别名;
select ename, sal*12 as '年薪'from emp; 别名的作用是 让查询出来的结果可以让别人(外行)看了一目了然的作用
上面是针对产品价格计算出总金额,价格*12,也就是对字段值进行加减乘除,
*****任何含有空值的表达式计算后的值都是空值。( 空值+20=空值,等等)
不等值查询(mysql两者都支持)
select * from productinfo where product_id!=33;
oracl的不等值查询
select * from productinfo where product_id<>'33';
小于查询
select * from productinfo where product_id<'33';
大于查询
select * from productinfo where product_id>'33';
等于查询
select * from productinfo where product_id='33';
在一定值范围内查询 例如 1000--5000的查询
select ename, sal as '月薪'from emp where sal>=1000 and sal<=5000;
在两个值之间的查询 between...... and (包含最小值和最大值)
select ename, sal as '月薪'from emp where sal between 1000 and 5000;
in 查询 在什么里面
示例 :在emp表中查询部门编号为25 25 20 这三个值中的 某些字段
select ename, sal,deptno from emp where deptno in (25,26,20);
not in 刚好与上面的相反
like 是做模糊查询使用
and 表示要满足所有条件 例如:
select ename, sal,deptno from emp where ename like '%ff' and deptname='市场部';
or 查询 表示只要满足其中一个条件就行,例如
select ename, sal,deptno from emp where ename like '%ff' or deptname='市场部';
not in 取反的意思 表示不包含
优先级 级别 (可以用括号提高优先级别)
排序 用的是 order by
降序 desc
默认是升序
注意 排序时 排序的字段只能是int 类型 否则排序的效果会出现不理想的结果
*/*****可以在这样做 sal是varchar 对sal排序时:
select ename as '姓名', sal as'月薪' from emp order by sal+0;
例如:自己建表的时候,把一个字段类型创建为varchar(2) ,其实应该建为int(2)的。因为我只允许输出数字。这本来也没什么,无非就是占点空间,懒得改了。但是今天在后台发现排序有问题。于是,没办法,改之。下面简单说一下MySQL的varchar排序问题,引以为戒。
下面,我从数据库里面以server_id排一下序,大家来看一下排序后的结果:
select server_id from cardserver where game_id = 1 order by server_id desc limit 10;
+-----------+
| server_id |
+-----------+
| 8 |
| 7 |
| 6 |
| 5 |
| 4 |
| 3 |
| 2 |
| 10 |
| 1 |
+-----------+
很明显,我想要的结果应该是 10,8,7,6,5 这样的。但是这个10排在了2的后面。按照字符串来排的。其实我是想把它当做数值来排。
手动转换类型:
用下面的方法就可以了,使server_id+0之后再排序,问题解决了。
select server_id from cardserver where game_id = 1 order by server_id+0 desc limit 10;
+-----------+
| server_id |
+-----------+
| 10 |
| 8 |
| 7 |
| 6 |
| 5 |
| 4 |
| 3 |
| 2 |
| 1 |
+-----------+
使用MySQL函数CAST/CONVERT:
mysql为我们提供了两个类型转换函数:CAST和CONVERT,现成的东西我们怎能放过?
CAST() 和CONVERT() 函数可用来获取一个类型的值,并产生另一个类型的值。
这个类型 可以是以下值其中的 一个:
BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
所以我们也可以用CAST解决问题:
select server_id from cardserver where game_id = 1 order by CAST(server_id as SIGNED) desc limit 10;
也可以使用CONVERT来搞定此问题:
select server_id from cardserver where game_id = 1 order by CONVERT(server_id,SIGNED) desc limit 10;
在productinfo表中查询 update_time ,create_time这两个字段,条件是product_id='33';
select update_time ,create_time from productinfo where product_id='33';
在两个值之间的查询 between...... and
select ename, sal as '月薪'from emp where sal between 1000 and 5000;
插入数据时一定要注意字段的类型 int型不用加单引号,varchar 型的要加上单引号
例如:
insert into emp (deptno,ename ,sex, eemail ,deptname ,sal) values (30,'luo1','nan','123456','开发部','3000');
auto_increment 自动增长
description 描述,
修改列的类型
alter table 表名 modify 列名 列类型
修改列名
alter table 表名 change 旧列名 新列名 列类型
alter table emp change name ename varchar(20);
增加列
alter table 表名 add column 字段名(列名) 列类型 (column 可以有和无 标准的应该有 column )
alter table emp add column moblie int (11);
alter table 表名 add column 字段名(列名) 列类型 after/befor 列名(字段名)
删除列 把上面的add改为drop就行了;
修改表名 alter table 表名 rename 新表名;
alter table emp rename tb_emp;
rename table 表名 to新表名
rename table tb_emp to emp;
删除 表中的某一个字段 (注意 删除此字段时 此字段一低昂要是不关联的字段,否则删除失败,删除成功 数据也伴随着删除了)
语法是: alter table 表名 drop 字段名;
alter table emp drop eemail;
**** 删除表中的莫一条记录用的时候 delete 语句
例如 :delete from emp where id =40;
****** 更新某一条记录的数据时用 update语句 update ...set
例如; update emp set ename='kkkk22' where id=20;
更新多个字段的值 update emp set ename ='222255',sex='女'where id=10;
约束。
check 约束在mysql中不起作用;
>= ,=< ,= >xAND<x(不等于x的查询)
where 的条件
Incorrect integer value: '' for column 'sal' at row 10
函数,单行函数 ,字段值的函数
单行函数: concat(str1,str2,....) 连接函数
字段值的函数 select now();
插入 时间数据
insert into emp (birth) values ( now());
插入时间 可以用时间函数,也可以手动插入,
手动插入:
insert into emp (birth,birthday,hierday)values('1999-02-06','1998-03-02','2001-05-26');插入的时间要在单引号内。
insert into emp (birth,birthday,hierday)values('19990206','19980302','20010526');这样也行。
insert into emp (birth,birthday,hierday)value('1999/02/06','1998/05/02','2001/05/06');这也行
**** 注意 函数后面要紧跟着括号 ,不能有空格号;
常用的数据类型是 int ,char ,varchar, 时间的是:date,datetime,等
聚合函数是对一组值进行计算,并返回单个值,也叫组合函数,除了count()以外,聚合函数都会忽略null值。
下列是聚合函数(五个:avg,sum,max,min,count)
select avg(sal) from emp; 对emp表中的sal求平均值。
select sum(sal) from emp; 求和
select count(sal) from emp; 求总共的行数
select max(sal) from emp;
select min(sal) from emp;
select avg(sal) as '工资平均值',max(sal) as '最高工资',min(sal) as'最低工资',sum(sal) as'工资总和', count(sal) as '总共的记录' from emp;
****** count 不统计null,统计的事记录数;
select count(*) from emp; 星号是统计所有的记录。
ifnull(sal,0)是如果有值就取第一个sal,否则就取零。
例如:
select avg(ifnull(sal,0)) from emp;
分组统计:Group by 子句是真正作用在于与各种聚合函数配合使用。它是用来查询出来的数据进行分组。
分组的含义是:把该列具有相同值的多条记录当成一条记录处理,最后只输出一条记录。分组函数忽略空值。 如果需要排序在用order by 子句。
当查询时一定要注意
select deptno, avg(ifnull(sal,0)) from emp; 这个语句是错误的,因为deptno没有出现在聚合函数中,也没有出现在 Group by子句中,后面应该跟 Group by 子句;
select deptno, avg(sal) from emp group by deptno; 查询每一个部门的平均工资。
select deptno, count(*) from emp group by deptno; 查询每一个部门的总数
select deptno, avg(sal) as '工资平均值',max(sal) as '最高工资',min(sal) as'最低工资',sum(sal) as'工资总和', count(sal) as '总共的记录' from emp group by deptno;这是查询每一个部门的工资具体情况。
where 子句中部能使用分组函数,因此用 having 来代替 where;
例如: select deptno, avg(sal) as '工资平均值',max(sal) as '最高工资',min(sal) as'最低工资',sum(sal) as'工资总和', count(sal) as '总共的记录' from emp where avg(sal)>300 group by deptno;(错误语句)
select deptno, avg(sal) as '工资平均值',max(sal) as '最高工资',min(sal) as'最低工资',sum(sal) as'工资总和', count(sal) as '总共的记录' from emp group by deptno having avg(sal)>3000;******* having 语句只能在Group by 后面。
分组 加条件 只能用having,
where 是在分组前进行条件过滤,where子句中部能使用聚合函数
having是在分组后进行条件过滤。
select deptno, avg(sal) as '工资平均值',max(sal) as '最高工资',min(sal) as'最低工资',sum(sal) as'工资总和', count(sal) as '总共的记录' from emp group by deptno having avg(sal)>3000 order by avg(sal) asc; order by 一般是都在最后;
limit 用来限制显示的行数,他常用来分页。
select * from emp limit 5; 这是查询前五条记录
select * from emp limit 5,10;查询的是6——16条数据,10这个参数 表示要查10调记录,五代表偏移量为五。
limit 语句 还在 order by 的后面。limit 是mysql特有的。
语法: limit 偏移量 ,行数;
例如:select * from emp limit 4,2; 取出的数据是 第5,6条记录,
取第一条数据:select * from emp limit 0,1;
limit 的偏移量是从零开始的,所以取出的数据时从偏移量加上1开始取限制的行数。
select id,deptno,sex from emp limit 3,5; 取出的事从第四条记录开始取5条记录。
*****多表连接查询:
1.使用单个select语句从多个表中取出相关的数据。通过多表之间的关系,构建相关数据查询据。
2.多表连接通常是建立在相互关系的父子表上的。父子表示有关系的表。关系是通过外键形成的。
3.标准语法:select....from join_table JOIN_TYPE join_table on join_condition WHERE where_condition;
*join_table 参与连接的表
*JOIN_TYPE 连接的类型:内连接,外连接,交叉连接,自连接
*join_condition 连接条件
*where_condition where过滤条件
第一个;交叉连接/笛卡尔连接 select * from emp,dept;(在实际中此连接基本不用)
select count(*) from emp;//是17条记录
select count(*) from dept;//是4条记录
select count( *) from emp,dept;//是68=4*17;
select * from emp,dept; 返回的是两张表的交叉乘积
标准语法:select * from emp cross join dept;
第二 内连接 连接条件就是主外键关联
1.等值连接:select * from emp,dept where emp.deptno=dept.deptno;
select * from emp e , dept d where e.deptno=d.deptno;和上面的一样,只是省略了as
select * from emp as e , dept as d where e.deptno=d.deptno;
其中给了表取别名 emp as e。
标准写法是: select * from emp inner join dept on emp.deptno=dept.deptno;
第三:外连接:在外连接当中,某些building满足条件的列也会显示出来,也就是说,只限制其中一个表的行,而不限制另一个表的行
1.左外连接 标准语法
select * from dept left join emp on dept.deptno=emp.deptno; 这里部门表(dept)作为主表,或者说左边的表为主表,左边的记录会全部显示,如果没有找到记录就补null;
select * from dept left join emp on emp.deptno=dept.deptno;一样的效果
select * from dept left join emp on emp.deptno=dept.deptno;这就不一样了 左表(主表)发生该变了。
在Oracle中可以这样写;select * from emp,dept where emp.deptno=dept.deptno(+);
2.右外连接
select * from dept right join emp on emp.deptno=dept.deptno;
方法与左外连接一样,只是把left该为right就行了
3.自连接 :参与连接的表都是同一张表(通过给表取别名虚拟出)
第四 子查询:所查新出来的结果为主表提供查询的条件。
需求:查询工资比luoa高的所有员工,
第一步:select sal from emp where ename ='luoa'; 查出的结果是luoa的 sal为300
第二步: select * from emp where sal >300;
select * from emp where sal >(select sal from emp where ename = 'luoa');这里要求select sal from emp where ename = 'luoa'查出来的结果必须唯一。
查询和luoa同一个部门的员工
1.select deptno from emp where ename = 'luoa'; 查出的结果是luoa的deptno为35
2. select * from emp where deptno=35;
select * from emp where sal >(select deptno from emp where ename = 'luoa');
查询月薪工资最高的员工名字
select max(sal) from emp; 查出的max(sal)为65120
select ename from emp where sal='65120';
select ename from emp where sal=(select max(sal) from emp );
****单行只查询不能返回多个结果,如果子查询为空时,不会报错,查出的结果为空。
关系型数据库
Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL
非关系型
NoSql、Cloudant、MongoDb、redis、HBase
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.27 |
+-----------+
1 row in set (0.00 sec)
CREATE TABLE `t_order` (
`int` bigint(11) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL COMMENT '用户id',
`product_id` bigint(11) DEFAULT NULL COMMENT '产品id',
`count` int(11) DEFAULT NULL COMMENT '数量',
`money` decimal(11,0) DEFAULT NULL COMMENT '金额',
`status` int(1) DEFAULT NULL COMMENT '订单状态: 0:创建中 1:已完结',
PRIMARY KEY (`int`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表';
+----+----------------+----------------------------+-----+-------+---------+---------+
| id | name | url | age | alexa | uv | country |
+----+----------------+----------------------------+-----+-------+---------+---------+
| 1 | 百度 | https://www.baidu.com/ | 21 | 4 | 5010.5 | CN |
| 2 | 淘宝 | https://www.taobao.com/ | 17 | 8 | 3996.75 | CN |
| 3 | C语言中文网 | http://c.biancheng.net/ | 12 | 7923 | 11.62 | CN |
| 4 | Google | https://www.google.com/ | 23 | 1 | 36474 | US |
| 5 | GitHub | https://github.com/ | 13 | 95 | 216.3 | US |
| 6 | Stack Overflow | https://stackoverflow.com/ | 16 | 48 | 592.2 | US |
| 7 | Yandex | http://www.yandex.ru/ | 11 | 53 | 591.82 | RU |
| 8 | VK | https://vk.com/ | 23 | 23 | 1206 | RU |
+----+----------------+----------------------------+-----+-------+---------+---------+
GET /_search
{
"query":{
"match": {
"message": "this that"
}
}
}
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
1.原子性(Atomicity)
事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
2.一致性(Consistency)
数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
3.隔离性(Isolation)
并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
4.持久性(Durability)
一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
create table student(
sno int(10) primary key not null unique,
sname varchar(10) not null,
sex varchar(1) defualt '男',
semail varchar(20) unique
);
1.关系型数据库通过外键关联来建立表与表之间的关系,
2.非关系型数据库通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定
1) 对比和数据模型
1. HBase-Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩、实时读写的分布式数据库
2. 在Hadoop生态圈中,它是其中一部分且利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为其分布式协同服务,主要用来存储非结构化和半结构化的松散数据(NoSQL非关系型数据库有redis、MongoDB等)
3. 简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织
4. 关系型数据库的3大优点
1. 容易理解:二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解
2. 使用方便:通用的SQL语言使得操作关系型数据库非常方便
3. 易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率
2) 关系型数据库的3大瓶颈
1. 高并发读写需求:网站的用户并发性非常高,往往达到每秒上万次读写请求,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈,并且很难能做到数据的强一致性。
2. 海量数据的读写性能低:网站每天产生的数据量是巨大的,对于关系型数据库来说,在一张包含海量数据的表中查询,效率是非常低的。
3. 扩展性和可用性差:在基于web的结构当中,数据库是最难(但是可以)进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移。
4. 非关系型数据库特点:
1. 一般不支持ACID特性,无需经过SQL解析,读写性能高 存储格式:key value,文档,图片等等数据没有耦合性,容易扩展
2. 但非关系型数据库由于很少的约束,他也不能够提供像SQL所提供的where这种对于字段属性值情况的查询。并且难以体现设计的完整性。他只适合存储一些较为简单的数据,对于需要进行较复杂查询的数据,SQL数据库显的更为合适
3. 由于非关系型数据库本身天然的多样性,以及出现的时间较短,因此,不像关系型数据库,有几种数据库能够一统江山,非关系型数据库非常多,并且大部分都是开源的。
4. 这些数据库中,其实实现大部分都比较简单,除了一些共性外,很大一部分都是针对某些特定的应用需求出现的,因此,对于该类应用,具有极高的性能
5. 依据结构化方法以及应用场合的不同,主要分为以下几类:
1. 面向高性能并发读写的key-value数据库:Redis,Tokyo Cabinet,Flare
2. 面向海量数据访问的面向文档数据库:MongoDB以及CouchDB,可以在海量的数据中快速的查询数据
3. 面向可扩展性的分布式数据库:这类数据库想解决的问题就是传统数据库存在可扩展性上的缺陷,这类数据库可以适应数据量的增加以及数据结构的变化
3) 数据模型
1. ROW KEY
1. 决定一行数据
2. 按照字典顺序排序的
3. Row key只能存储64k的字节数据
2. Column Family列族 & qualifier列
1. HBase表中的每个列都归属于某个列族,列族必须作为表模式(schema) 定义的一部分预先给出。如 create ‘test’,‘course’;
2. 列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如course:math, course:english, 新的列可以随后按需、动态加入;权限控制、存储以及调优都是在列族层面进行的;
3. HBase把同一列族里面的数据存储在同一目录下,由几个文件保存
3. Cell单元格
1. 由行和列的坐标交叉决定; 单元格是有版本的;
2. 单元格的内容是未解析的字节数组;
3. 由{row key, column( =<family> +<qualifier>), version} 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。
4. Timestamp时间戳
1. 在HBase每个cell存储单元对同一份数据有多个版本,根据唯一的时间戳来区分每个 版本之间的差异,不同版本的数据按照时间倒序排序,最新的数据版本排在最前面。
2. 时间戳的类型是 64位整型。
3. 时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。 时间戳也可以由客户显式赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。
5. HLog(WAL log)
1. HLog文件就是一个普通的HadoopSequenceFile,Sequence File的Key是 HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,timestamp是”写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number。
2. HLog SequeceFile的Value是HBase的KeyValue对象,即对应HFile中的KeyValue。
4) 体系架构
1. Client
1. 包含访问HBase的接口并维护cache来加快对HBase的访问
2. Zookeeper
1. 保证任何时候,集群中只有一个master;
2. 存贮所有Region的寻址入口。
3. 实时监控Region server的上线和下线信息。并实时通知Master
4. 存储HBase的schema和table元数据
3. Master
1. 负责Region server的负载均衡;
2. 发现失效的Region server并重新分配其上的region;
3. 管理用户对table的增删改操作;
4. RegionServer
1. Region server维护region,处理对这些region的IO请求
2. Region server负责切分在运行过程中变得过大的region
5. Region
1. HBase自动把表水平划分成多个区域(region),每个region会保存一个表里 面某段连续的数据;每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region(裂变);
2. 当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Regionserver 上。
3. Memstore与storefile
1. 一个region由多个store组成,一个store对应一个CF(列族)
2. store包括位于内存中的memstore和位于磁盘的storefile写操作先写入
memstore,当memstore中的数据达到某个阈值,hregionserver会启动
flashcache进程写入storefile,每次写入形成单独的一个storefile;当storefile文件的数量增长到一定阈值后,系统会进行合并(minor、majorcompaction),在合并过程中会进行版本合并和删除工作(majar),形成更大的storefile
3. 当一个region所有storefile的大小和超过一定阈值后,会把当前的region分割为两个,并由hmaster分配到相应的regionserver服务器,实现负载均衡
4. 客户端检索数据,先在memstore找,找不到再找storefile
5. HRegion是HBase中分布式存储和负载均衡的最小单元。最小单元就表示不同的HRegion可以分布在不同的 HRegion server上。
6. HRegion由一个或者多个Store组成,每个store保存一个columns family。
7. 每个Strore又由一个memStore和0至多个StoreFile组成。如图:StoreFile以HFile格式保存在HDFS上。
ORM思想(Object Relational Mapping)体现:
数据库中的一个表 <—> Java或Python中的一个类
表中的一条数据 <—> 类中的一个对象(或实体)
表中的一个列 <—> 类中的一个字段、属性(field)
参考博主的理解:
前面讲过region的encode值就是存放region的文件的目录名,这些目录位于hdfs中的hbase相关的数据目录中.
所以HMaster可以扫描这些目录获取region的信息,根据region的名字就可以从hbase:meta中获取相应的HRegion Server信息
支持数据的持久化:可以将内存中的数据保持在磁盘中,重启redis服务或者服务器之后可以从备份文件中恢复数据到内存继续使用。支持更多的数据类型:支持string(字符串)、hash(哈希数据)、list(列表)、set(集合)、zet(有序集合)
支持数据的备份:可以实现类似于数据的master-slave模式的数据备份,另外也支持使用快照+AOF。
支持更大的value数据:memcache单个key value最大只支持1MB,而redis最大支持512MB。
Redis 是单线程,而memcache是多线程,所以单机情况下没有memcache并发高,但redis 支持分布式集群以实现更高的并发,单Redis实例可以实现数万并发。
支持集群横向扩展:基于redis cluster的横向扩展,可以实现分布式集群,大幅提升性能和数据安全性。
都是基于C语言开发。