30.域的含义
域英文叫DOMAIN——域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理,以及相互通信和数据传输。
域既是 Windows 网络操作系统的逻辑组织单元,也是Internet的逻辑组织单元,在 Windows 网络操作系统中,域是安全边界。域管理员只能管理域的内部,除非其他的域显式地赋予他管理权限,他才能够访问或者管理其他的域,每个域都有自己的安全策略,以及它与其他域的安全信任关系。
31.SQL CHECK 约束
CHECK 约束用于限制列中的值的范围。
如果对单个列定义 CHECK 约束,那么该列只允许特定的值。
如果对一个表定义 CHECK 约束,那么此约束会在特定的列中对值进行限制。
1.下面的 SQL 在 "Persons" 表创建时为 "Id_P" 列创建 CHECK 约束。CHECK 约束规定 "Id_P" 列必须只包含大于 0 的整数。
CREATE TABLE Persons
(
Id_P int NOT NULL CHECK (Id_P>0),
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
2.如果需要命名 CHECK 约束,以及为多个列定义 CHECK 约束,请使用下面的 SQL 语法:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')
)
SQL CHECK Constraint on ALTER TABLE
3.如果在表已存在的情况下为 "Id_P" 列创建 CHECK 约束,请使用下面的 SQL:
ALTER TABLE Persons
ADD CHECK (Id_P>0)
4.如果需要命名 CHECK 约束,以及为多个列定义 CHECK 约束,请使用下面的 SQL 语法:
ALTER TABLE Persons
ADD CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')
5.如需撤销 CHECK 约束,请使用下面的 SQL:
ALTER TABLE Persons
DROP CONSTRAINT chk_Person
32.Lpad函数
lpad(字段名,填充长度,填充的字符)
是用来在指定字段左侧填充字符,
比如select lpad('3',2,0) from dual; 就是在 3 这个基础上左侧补 0,一共是2位, 结果为 03
33.如何使主键的值自动加1并在前面补0
select LPAD(id+1,14,'0') 记录编号 from tetdmis
34.order by,decode对字符列进行特定的排序
大家还可以在Order by中使用Decode。
例:表table_subject,有subject_name列。要求按照:语、数、外的顺序进行排序。这时,就可以非常轻松的使用Decode完成要求了。
select * from table_subject order by decode(subject_name, '语文', 1, '数学', 2, , '外语',3)
35.decode取最小值
select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值
sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1
36.decode 查询某班男生和女生的数量分别是多少
select decode(性别,男,1,0),decode(性别,女,1,0) from 表
37.利用decode实现表或者试图的行列转换
SELECT
SUM(DECODE(ENAME,'SMITH',SAL,0)) SMITH,
SUM(DECODE(ENAME,'ALLEN',SAL,0)) ALLEN,
SUM(DECODE(ENAME,'WARD',SAL,0)) WARD,
SUM(DECODE(ENAME,'JONES',SAL,0)) JONES,
SUM(DECODE(ENAME,'MARTIN',SAL,0)) MARTIN FROM EMP
输出结果如下:
SMITH ALLEN WARD JONES MARTIN
800 1600 1250 2975 1250
38.使用decode函数来使用表达式来搜索字符串
SELECT ENAME,SAL,DECODE(INSTR(ENAME, 'S'),0,'不含有s','含有s') ASINFO ROM EMP
输出结果:
SMITH 800 含有s
ALLEN 1600 不含有s
39.iif函数的简单使用
IIf([发货日期]<Date(),"已发货",IIf([发货日期]=Date(),"今天发货","未发货"))
40.Exists函数的使用
如果exiists中不包含里外关联条件,如:
select * from emp where exists (select * from dept where dname like '%A%')
则其表命只要括号内子查询语句返回结果不为空说明where条件成立就会执行主sql语句,全部输出
如果exiists中还包含里外关联条件,如:
select * from emp where exists (select * from dept where dname like '%A%' and deptno = emp.deptno)
则其表明只有满足括号中条件的结果才会被输出
41.not exists函数的使用
not exists和exists相反,子查询语句结果为空,则表示where条件成立,执行sql语句
如果not exiists中不包含里外关联条件,如:
select * from emp where not exists (select * from dept where dname like '%A%')
则其表命只要括号内子查询语句返回结果为空说明where条件成立就会执行主sql语句,全部输出
如果not exiists中还包含里外关联条件,如:
select * from emp where exists (select * from dept where dname like '%A%' and deptno = emp.deptno)
则其表明只有满足括号中条件取反的结果才会被输出(包括没有相关数据的)
补充: “<>”与“!=”类似
补充:exiists与not exiists均与子查询结果无关,子查询结果只起到了一个判定的作用,里面的where条件才是关键
补充:exists可以改造为where的格式,例如:
select * from emp where exists (select * from dept where dname like '%A%' and deptno = emp.deptno)
可以改造为:
select * from emp e ,dept d where d.dname like '%A%' and d.deptno = e.deptno
42.Extract()函数
截取时间,如:
Extract(YEAR FROM SYSDATE)
43.SQL UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2
另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
44.各种关联查询的场景选择
商品表:存放商品信息
图片表:存放图片
商品表里有4个商品,其中两个商品没有图片
查询所有的商品的所有信息
正确的做法是列出所有的商品,如果图片不存在就显示为 NULL。这时候就可以使用左连接——LEFT JOIN
补充:
1.inner join相当于用where条件来关联
2.left join是指包含左边表的全部记录(而不是全部字段,具体输出什么字段是自己指定的)
3.查询所有商品信息,则商品表在左边;查询所有图片对应的商品,则图片表在左边
4.当多表联查使用left join的时候,只保证含有最左侧表中的全部记录即可,之后的若干表顺序无所谓(但是若是其中出现了依次right join,则以其右侧表记录为准;inner join与outer join同理)
45.catalog与schema
按照SQL标准的解释,在SQL环境下Catalog和Schema都属于抽象概念,主要用来解决命名冲突问题。
从概念上说,一个数据库系统包含多个Catalog,每个Catalog又包含多个Schema,而每个Schema又包含多个数据库对象(表、视图、序列等),反过来讲一个数据库对象必然属于一个Schema,而该Schema又必然属于一个Catalog,这样我们就可以得到该数据库对象的完全限定名称从而解决命名冲突的问题了
catalog是由一个数据库实例的元数据组成的
schema是对一个数据库的结构描述
46.Spark内存分配的优化
问题原因:查看到用于缓存RDD的内存有很大一部分没有利用上,因此我们可以对Spark内部的内存分配进行一下调整, 调高用于shuffle的内存, 调低用于缓存RDD的内存具体做法如下:减少配置项” spark.storage.memoryFraction”的比例数,增大配置项” spark.shuffle.memoryFraction”的比例数, 从RDD缓存区中拿一部分内存出来用于shuffle的计算
47.substring()内只有一个参数的用法
指的是从该位置以后开始截取
48.在Hive 中如何使用符合数据结构 maps,array,structs
1. Array的使用
create table person(name string,work_locations array<string>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ',';
数据:
biansutao beijing,shanghai,tianjin,hangzhou
linan changchu,chengdu,wuhan
2. Map 的使用
create table score(name string, score map<string,int>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':';
数据:
biansutao '数学':80,'语文':89,'英语':95
jobs '语文':60,'数学':80,'英语':99
3 Struct 的使用
CREATE TABLE test(id int,course struct<course:string,score:int>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ',';
数据:
1 english,80
2 math,89
3 chinese,95
49.对于以下数据样例,如何进行数据清洗:
fQShwYqGqsw lonelygirl15 736 People & Blogs 133 151763 3.01 666 765 fQShwYqGqsw LfAaY1p_2Is 5LELNIVyMqo vW6ZpqXjCE4 vPUAf43vc-Q ZllfQZCc2_M it2d7LaU_TA KGRx8TgZEeU aQWdqI1vd6o kzwa8NBlUeo X3ctuFCCF5k Ble9N2kDiGc R24FONE2CDs IAY5q60CmYY mUd0hcEnHiU 6OUcp6UJ2bA dv0Y_uoHrLc 8YoxhsUMlgA h59nXANN-oo 113yn3sv0eo
考虑点:在video.txt中,视频可以有多个所属分类,每个所属分类用&符号分割,并且分割的两边有空格字符,多个相关视频又用“tab”进行分割。为了分析数据时方便对存在多个子元素的数据进行操作,我们首先进行数据重组清洗操作。
具体做法:将所有的类别用“&”分割,同时去掉两边空格,多个相关视频 id 也使用“&”进行分割(如果用“tab”则与字段无法区分了)
注意事项:
1.这里的数据清洗不涉及reduce操作,所以只用map即可,视频的相关视频id可以没有,但是比如评论数必须有值,没有评论即为0,所以如果一条数据的字段缺少,也是脏数据,是要被清洗的
2.数据清洗时先拿单行数据测试
50.oracel新建函数包括存储过程与函数,其二者有何区别
oracle中存储过程和函数的区别如下:
1.存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。
2.对于存储过程来说可以返回参数,而函数只能返回值或者表对象。
3.存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。
4.当存储过程和函数被执行的时候,SQL Manager会到procedure cache中去取相应的查询语句,如果在procedure cache里没有相应的查询语句,SQL Manager就会对存储过程和函数进行编译。
5.返回值的区别,函数有1个返回值,而存储过程是通过参数返回的,可以有多个或者没有
6.调用的区别,函数可以在查询语句中直接调用,而存储过程必须单独调用. 函数一般情况下是用来计算并返回一个计算结果而存储过程一般是用来完成特定的数据操作(比如修改、插入数据库表或执行某些DDL语句等等) 参数的返回情况来看: 如果返回多个参数值最好使用存储过程,如果只有一个返回值的话可以使用函数; oracle函数和存储过程最大的区别就在于,函数必须带上一个return返回值,后面跟的是返回值的类型,而存储过程可以不带任何返回值。
51.oracel中的declare的用法
Declare用于定义变量,并为其赋值,在sql查询窗口执行即可,具体实例如下:
SQL> declare
empno emp.empno%TYPE; //声明的时候%TYPE前面一定要加上表的中列,具体执行流程为:首先它到emp表中去查找empno列 %TYPE返回其数据的数据类型(用于不清楚变量的数据类型的情况,若是已知数据类型,则可以直接写上)
ename emp.ename%TYPE;
job emp.job%TYPE;
begin
select empno,ename,job into empno,ename,job from emp where empno='7369';
dbms_output.put_line(empno||'/'||ename||'/'||job);
end;
注意:
1.使用select.....into....from语句只能返回单行数据,如果返回多行,则会出错。
2. dbms_output.put_line()可以输出括号内变量的值
3. 直接赋值要用 := ,并且赋值只能在begin…end中进行,否则会报错
4.适用以下条件和循环:
if … then…else…end if;
和
for … in …(1..20指经历20次循环) loop …(循环体) end loop;
5. oracle 数组类型,没有现成的类型,但是可以自己随意定义,很方便。
Oracle 数组可以分为定长数组和可变长的数组两类。以下主要是一维数组介绍:
定长数组:
/*定长字符数组,数组大小为10*/
declare
type v_arr is varray(10) of varchar2(30);
my_arr v_arr;
begin
my_arr:=v_arr('1','2','3');
for i in 1..my_arr.count
loop
dbms_output_line(my_arr(i));
end loop;
end;
变长数组:
/*可变长字符数组,元素大小30,索引标号integer类型自增长*/
declare
type v_table is table of varchar2(30) index by binary_integer;
--类型可以是前面的类型定义,index by binary_integer子句代表以符号整数为索引,
--这样访问表类型变量中的数据方法就是“表变量名(索引符号整数)”。
my_table v_table;
begin
for i in 1..20
loop
my_table(i):=i;
dbms_output.put_line(my_table(i));
end loop;
end
注意:虽然可以自定义数组类型的变量,但是仅限于用在本次会话中,因此无法在创建表的时候指定该种数据类型
63.Shullfe中默认的排序、分区、合并如何进行
1.shullfe中的排序:默认以mapoutkey进行排序
2.shullfe中的分区:默认分一个区
3.shullfe中的合并:默认相同的key进行合并
64.reduce端分组如何实现:
一般继承WritableComparator类,覆写public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)方法
65.reduce端排序如何实现:
一般继承WritableComparator类,覆写public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)方法
66.12.hive中使用orc的压缩方式建表如何导入数据
orc的压缩方式要想向表中导入数据需要使用子查询的方式导入,即把从另一张表中查询到的数据插入orc压缩格式的表汇中,所以这里需要四张表,两张textfile类型的表user和video,两张orc类型的表user_orc和video_orc
67.Hive中order by,sort by,distribute by,cluster by的区别
1.order by
全局排序
2.sort by和distribute by组合使用(效果与order by一样,但是使用场景不同)
当有多个reduce时(可以通过set mapred.reduce.tasks=n来指定reduce的个数),sort by仅保证在每个reduce内排序(部分有序),distribute by的作用是控制哪些行放入哪些reduce处理的(并不会排序),因此distribute by经常和sort by配合使用:SELECT * FROM year distribute by year sort by year asc,temp desc
3.CLUSTER BY
关键字是DISTRIBUTE BY和SORT BY的简写,这两者可以认为对应与Hadoop的partition和sort过程。如果partition和sort的key是不同的,可以使用DISTRIBUTE BY和SORT BY分别指定(如上面的例子)
注:Distribute by和sort by配合使用的场景
1.Map输出的文件大小不均。
2.Reduce输出文件大小不均。
3.小文件过多。
4.文件超大。
补充:hive中create table时的“clustered by(字段1)sorted by (字段2) into 8 buckets”是什么意思
create table时的clustered by其实仅仅是分布,与Select语句中的cluster by其实并不一样。而是和Select语句中的distribute by相同。所以create table的clustered by sorted by其实等价于select的distribute by sort by,即:按照字段1分布在8个buckets(桶)中,并且在每个buckets中按照字段2升序排序
68.hive中的buckets
Buckets 对指定列计算 hash,根据 hash 值切分数据,目的是为了并行,每一个 Bucket 对应一个文件。如将 user 列分散至 32 个 bucket,首先对 user 列的值计算 hash,对应 hash 值为 0 的 HDFS 目录为:/ warehouse /xiaojun/dt =20100801/ctry=US/part-00000;hash 值为 20 的 HDFS 目录为:/ warehouse /xiaojun/dt =20100801/ctry=US/part-00020
这段描述是说用了bucket之后的,那为什么要用bucket,没说,本着认真负责的态度,我从网上搜索到了Oreilly《Programming.Hive》这本书,然后在里面找到了答案,现在发出来和大家分享一下。
首先回顾一下分区,分区是切分数据的一种比较方便的方法,比较常用的就是按照日期来进行切分,bucket(中文意思就是篮子,可以放鸡蛋,哈哈)其实也是一种切分数据的方法。
假设我们有一张日志表,我们需要按照日期和用户id来分区,目的是为了加快查询谁哪天干了什么,如下:
CREATE TABLE weblog (url STRING, source_ip STRING)
> PARTITIONED BY (dt STRING, user_id INT);
但是这里面用user_id去切分的话,就会产生很多很多的分区了,这些分区可大可小,这个数量是文件系统所不能承受的。
在这种情况下,我们既想加快查询速度,又避免出现如此多的小分区,篮子(bucket)就出现了。
具体的用法是:
CREATE TABLE weblog (user_id INT, url STRING, source_ip STRING)
> PARTITIONED BY (dt STRING)
> CLUSTERED BY (user_id) INTO 96 BUCKETS;
首先按照日期分区,分区结束之后再按照user_id把日志放在96个篮子,这样同一个用户的所有日志都会在同一个篮子里面,并且一个篮子里面有好多用户的日志。
然后我们在插入数据的时候就要注意了,我们一定要设置hive.enforce.bucketing为true。
hive> SET hive.enforce.bucketing = true;
hive> FROM raw_logs
> INSERT OVERWRITE TABLE weblog
> PARTITION (dt='2009-02-25')
> SELECT user_id, url, source_ip WHERE dt='2009-02-25';
到此,bucket介绍完毕!
总结:分区与分桶的目的都是分布存储数据,但是以某些特定字段分区后会造成分区大小不一,并且存在大量小分区,这样十分影响效率,因此可以使用分桶表,可以控制桶的个数,并且使数据均匀分布在桶中!
69.Hive 自定义函数 UDF UDAF UDTF的区别
1、UDF:用户定义(普通)函数,只对单行数值产生作用;
2、UDAF:User- Defined Aggregation Funcation;用户定义聚合函数,可对多行数据产生作用;等同与SQL中常用的SUM(),AVG(),也是聚合函数;
3、UDTF:User-Defined Table-Generating Functions,用户定义表生成函数,用来解决输入一行输出多行;
70.拆解json字段,将其进行行转列,并获取key为monthSales的数据:
[{"source":"7fresh","monthSales":4900,"userCount":1900,"score":"9.9"},{"source":"jd","monthSales":2090,"userCount":78981,"score":"9.8"},{"source":"jdmart","monthSales":6987,"userCount":1600,"score":"9.0"}]
错误方法:
select get_json_object(explode(split(regexp_replace(regexp_replace(sale_info,'\\[\\{',''),'}]',''),'},\\{')),'$.monthSales') as sale_info from explode_lateral_view;
会报错:
FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions(即:UDTF 类型的explode函数不能写在别的函数内)
注:这时候就需要LATERAL VIEW出场了
正确方法:
select get_json_object(concat('{',sale_info_r,'}'),'$.monthSales') as monthSales from explode_lateral_view
LATERAL VIEW explode(split(regexp_replace(regexp_replace(sale_info,'\\[\\{',''),'}]',''),'},\\{'))sale_info as sale_info_r;
补充1:将json字段 完全转换成二维表的方式展现:
select get_json_object(concat('{',sale_info_1,'}'),'$.source') as source,
get_json_object(concat('{',sale_info_1,'}'),'$.monthSales') as monthSales,
get_json_object(concat('{',sale_info_1,'}'),'$.userCount') as monthSales,
get_json_object(concat('{',sale_info_1,'}'),'$.score') as monthSales
from explode_lateral_view
LATERAL VIEW explode(split(regexp_replace(regexp_replace(sale_info,'\\[\\{',''),'}]',''),'},\\{'))sale_info as sale_info_1;
补充2:LATERAL VIEW也可以多重使用
select goods_id2,sale_info,area2
from explode_lateral_view
LATERAL VIEW explode(split(goods_id,','))goods as goods_id2
LATERAL VIEW explode(split(area,','))area as area2;
以上结果为三个表(explode_lateral_view、goods、area)笛卡尔积的结果
补充3:如果你这么写,想查两个字段:
select explode(split(area,',')) as area,good_id from explode_lateral_view;
会报错:
FAILED: SemanticException 1:40 Only a single expression in the SELECT clause is supported with UDTF's. Error encountered near token 'good_id'(即:使用UDTF的时候,只支持一个字段)
注:这时候就需要LATERAL VIEW出场了
71.eclipse打包jar无法连带打包第三方lib,于是选择安装插件fatjar,但是目前高版本的eclipse无法兼容fatjar,解决方法如下:
https://www.cnblogs.com/lyh971134228/p/7144981.html
72.sql中any()和all()的使用
分别指任意和全部
73.数据库索引的利弊
索引能让数据库查询数据的速度上升, 而使写入数据的速度下降,原因很简单的, 因为平衡树这个结构必须一直维持在一个正确的状态, 增删改数据都会改变平衡树各节点中的索引数据内容,破坏树结构, 因此,在每次数据改变时, DBMS必须去重新梳理树(索引)的结构以确保它的正确,这会带来不小的性能开销,也就是为什么索引会给查询以外的操作带来副作用的原因
74.数据库索引的使用方式
1.单个字段建立索引
create index index_birthday on user_info(birthday);
//查询生日在1991年11月1日出生用户的用户名
select user_name from user_info where birthday = '1991-11-1'
这句SQL语句的执行过程如下:
首先,通过非聚集索引index_birthday查找birthday等于1991-11-1的所有记录的主键ID值
然后,通过得到的主键ID值执行聚集索引查找,找到主键ID值对就的真实数据(数据行)存储的位置
最后, 从得到的真实数据中取得user_name字段的值返回, 也就是取得最终的结果
2.多个字段建立组合索引
create index index_birthday_and_user_name on user_info(birthday, user_name);
这句SQL语句的执行过程就会变为:
通过非聚集索引index_birthday_and_user_name查找birthday等于1991-11-1的叶节点的内容,然而叶节点中除了有user_name表主键ID的值以外, user_name字段的值也在里面, 因此不需要通过主键ID值的查找数据行的真实所在,直接取得叶节点中user_name的值返回即可。 通过这种覆盖索引直接查找的方式, 可以省略不使用覆盖索引查找的后面两个步骤, 大大的提高了查询性能
117.flume中event事件头作用
可以添加一些数据正文之外的额外的数据
118.Map与mapPartitions方法的区别
map是对rdd中的每一个元素进行操作,而mapPartitions(foreachPartition)则是对rdd中的每个分区的迭代器进行操作。如果在map过程中需要频繁创建额外的对象(例如将rdd中的数据通过jdbc写入数据库,map需要为每个元素创建一个链接而mapPartition为每个partition创建一个链接),则mapPartitions效率比map高的多。
mapPartitions传入的参数是一个迭代器,里面包含rdd里的所有元素,返回结果也要是一个迭代器
119.Map与flatMap方法的区别
Flatmap与map类似,区别是原RDD中的元素经map处理后只能生成一个元素,而原RDD中的元素经flatmap处理后可生成多个元素来构建新RDD
例如:
sc.makeRDD(List("asf asx wwq laaa","saa wqe we ffff sss")).flatmap(_.split(" "))
可以生成含有9个元素的rdd
120.Map方法与reduce方法的作用
map的主要作用就是替换。reduce的主要作用就是计算。
reduce可以将所有元素从头开始每两个一组进行运算,最后返回一个结果元素