DDL数据库定义和DML数据操作语言

数据库DDL

1.创建库的语法

CREATE DATABASE [IF NOT EXISTS] database_name   [IF NOT EXISTS] --增强代码的健壮性  
[COMMENT database_comment]                                      --这个库是干嘛的
[LOCATION hdfs_path]                                            --你当前的库存储的hdfs路径
[WITH DBPROPERTIES (property_name=property_value, ...)];        --一点用没有(鸡肋)

create database db_hive
comment 'this in my first db'

2.创建数据库: (增)
创建一个数据库,指定数据库在HDFS上存放的位置

hive (default)> create database db_hive2 location '/db_hive2';

--在你不指定的location的情况下 默认在你的hdfs/user/hive/warehouse下创建一个以database_name.db名的文件夹 来当做库
--在你指定location的情况下 拿最后一级目录当做库的名字



3.过滤显示查询的数据库: (查)

hive> show databases like 'db_hive*';
OK
db_hive
db_hive_1

显示数据库信息:

hive> desc database extended db_hive;
OK
db_hive		hdfs://hadoop102:8020/user/hive/warehouse/db_hive.db	atguiguUSER	

4.改
用户可以使用ALTER DATABASE命令为某个数据库的DBPROPERTIES设置键-值对属性值,来描述这个数据库的属性信息。数据库的其他元数据信息都是不可更改的,包括数据库名和数据库所在的目录位置。

alter database db_hive set dbproperties('dbtype'='db');  --修改原来的属性
alter database db_hive set dbproperties('createtime'='2020-08-19');  --增加原来的属性

所以其实数数据库的属性就是为了凑一个改的效果,并不怎么用

5.删

drop database if exists db_hive2; --加上 if exists 增加代码的健壮性

drop database db_hive cascade; --强制删除 (当你库下面有表的时候) 慎用(只有你确定所有表都没用的时候)

表DDL

创建表

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
 --external表示创建的表是否为外部表,内外部表的效果底下介绍
 
[(col_name data_type [COMMENT col_comment], ...)]
--列名--列的类型 --列的注释(列拿来干什么的)
例子: create table test (age int comment 'agemean');
可能会有问题的是,这里为什么列名和列的类型都是可选项,因为我们可以用底下写的模范命令(as,like)来模仿一个数据库,这样原本数据库的列的架构就是可选项了。!!!
=================================================================================
[COMMENT table_comment]                          --表的注释  这个表拿来干嘛的
=================================================================================
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]   --分区表
[CLUSTERED BY (col_name, col_name, ...)                            --分桶表
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]   --桶内分通字段,桶内以什么排序
注:后面在出文章写!!!
=================================================================================
[
 ROW FORMAT DELIMITED                                            
    --这行数据分隔符      
    [FIELDS TERMINATED BY char]                         --!!!
    --字段分隔符
    -- songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing_10010 字段分隔符是 ','
    --有默认值  默认值是 ascii 码表  0001  ^A    ctrl+v  ctrl+a
 [COLLECTION ITEMS TERMINATED BY char]                           
    --集合(map array struct)分隔符
    --bingbing_lili xiao song:18_xiaoxiao song:19 hui long guan_beijing_10010 分隔符是'_'
    --有默认值  默认值是 ascii 码表  0010  ^B    ctrl+v  ctrl+b
 [MAP KEYS TERMINATED BY char] 
    --map的kv分隔符
    --xiao song:18   分隔符是 ':'
    --有默认值  默认值是 ascii 码表  0100  ^C    ctrl+v  ctrl+c
 [LINES TERMINATED BY char]
    --行分隔符   默认值是 '\n'
] 
注:举例:

create table test(
name string,
friends array,
children map<string, int>,
address structstreet:string,city:string,email:int
)
row format delimited fields terminated by ‘,’
collection items terminated by ‘_’
map keys terminated by ‘:’
lines terminated by ‘\n’;


数据为:
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing_10010
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing_10011
=================================================================================!!!

[STORED AS file_format]                 --当前创建的表存储格式           --比如表可以以压缩文件存储,默认是textfile
=================================================================================!!!
[LOCATION hdfs_path]                    --当前表的hdfs存储路径 注:此时路径填的是目录也就是文件夹,为什么不能是文件呢
因为如果是文件的话,就相当于这个表就是这个文件,而我们后续还需要对表进行一些增加的操作,就没法实现了。


=================================================================================
[TBLPROPERTIES (property_name=property_value, ...)]  --表的属性 这个用处比较大
=================================================================================
[AS select_statement]                   --根据查询结果创建一张表 会带表的结构和数据,但是不会带分割方式
如:create table test1 as select * from stu;  速度慢因为要走MR,重新创建了一张表,使用默认的分割方式
注:不能与[(col_name data_type [COMMENT col_comment], ...)]同时使用



[LIKE table_name]                       --模仿一张表  只模仿表结构但是没有模仿表的数据

如: create table test2 like test1; 速度快

管理表(增)

增加内部表(管理表)

内部表的含义:hive掌握着表的数据的生命周期,当在Hive里删除表的时候,会一并把hdfs上数据给删了,用的较少,一般为 1.中间表 2.测试表
补充:默认创建的表都是所谓的管理表,有时也被称为内部表。因为这种表,Hive会(或多或少地)控制着数据的生命周期。Hive默认情况下会将这些表的数据存储在由配置项hive.metastore.warehouse.dir(例如,/user/hive/warehouse)所定义的目录的子目录下。 当我们删除一个管理表时,Hive也会删除这个表中数据。管理表不适合和其他工具共享数据。


–内部表测试
create table student(id int, name string)
row format delimited fields terminated by ‘\t’
–默认分隔符测试
create table test2(id int, name string)
–根据查询结构创建一张表 它虽然会带表结构和数据 但是分隔符不会带 会使用默认值^A
create table student2 as select * from student;
–根据查询结构创建一张表 他的分隔符跟模仿表的是一样的
create table student3 row format delimited fields terminated by ‘\t’ as select * from student;
–根据存在的表的结构来创建一张表 拿不到数据 --他的分隔符跟模仿表的是一样的
create table student4 like student;

增加外部表

外部表的含义:hive不掌握着表的数据生命周期,当在Hive里删除表的时候,不会一并把hdfs上数据给删了,只会删除元数据
除了上述内部表的情况 全是外部表

create external table if not exists dept(
deptno int,
dname string,
loc int)
row format delimited fields terminated by '\t'
location '/company/dept';

解释:也就是说表的内容我们可以通过往dept目录中传文件来改变,并且这张表被删除的时候,对应的表路径目录并不会删除

内部表和外部表相互转换

Table Type:            EXTERNAL_TABLE       
Table Parameters:      EXTERNAL            TRUE 
表是否为内部表还是外部表是由Table Parameters 里面的EXTERNAL属性来控制 包括TRUE和FALSE 都得大写
--内部表转换成外部表
alter table student4 set tblproperties('EXTERNAL'='TRUE');
--外部表转成内部表
alter table emp set tblproperties('EXTERNAL'='FALSE');     注:这里是区分大小写,为固定写法

查(表)

--展示库下面的所有表
show tables;
--描述表
desc student;
--描述表的详情
desc formatted student;   可以通过查看表详情来看是否是外部表,以计表中数据文件的数目(元数据),比如通过hadoop直接上传文件就不会走元数据,则这里查出的fils数目不会改变

在这里插入图片描述
这里MANAGED_TABLE表示为内部表,numFiles为地址内的文件数,通过hadoop直接上传文件就不会走元数据,则这里查出的fils数目不会改变

删(表)

1.1 删除内部表
drop table student;
1.2 删除外部表
drop table dept; --只能删除元数据 不能删除hdfs上的数据
1.3 清空表
truncate table student3;
清空外部表测试 --也是不能清空外部表
truncate table emp;

改(表)

--改表名  会连同你的hdfs文件夹名字一起改掉
alter table student3 rename to student2;

--更新列  注意改的列的数据类型 只能由小往大改 或者不变
**顺序按hive的类型转化来,但是string比float大**
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
alter table stu2 change column id id int;
alter table stu2 change column id id tinyint; --这是错的
alter table stu2 change column id ids bigint;
alter table stu2 change column id idss bigint;
举例,原本的test6的格式为int,这个时候只能往bigint转,然后再只能往float,double转,无法往下转成tinyint

-- 增加列
ALTER TABLE table_name ADD COLUMNS (col_name data_type [COMMENT col_comment], ...) 
alter table stu2 add columns(weight double,money bigint);
-- 替换列
ALTER TABLE table_name REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...) 
-- 替换之相同列,必须所有替换后的列都比原列等于或大于数据类型转化顺序。如string double类只能转换为string double,或者double double
-- 替换之减少列  如果你想替换时候较少列 那么你减少后剩余部分 应该和之前字段 满足类型的大小关系
alter table stu2 replace columns (id bigint , name string);
比如,double,double,int就无法变成double,int
-- 替换之增加列  增加部分可以没有类型大小的关系 ,如果有对应的部分则满足类型大小的对应关系
alter table stu2 replace columns (id bigint , name string , height double, hair bigint);

DML(数据操作语言)

数据导入

load 装载数据

load data [local] inpath ‘数据的path’ [overwrite] into table student [partition (partcol1=val1,…)];
测试表
create table student (id int ,name string) row format delimited fields terminated by ‘\t’;

–load 数据之追加数据 从本地(linux)导入 是复制进去的
load data local inpath ‘/opt/module/hive/datas/student.txt’ into table student;

–load 数据之覆盖数据,也就是会将student1.txt内的数据覆盖表中本来的数据
load data local inpath ‘/opt/module/hive/datas/student1.txt’ overwrite into table student;

–load 数据之hdfs导入 hdfs导入时剪切进去的 (从根目录的student.txt直接剪切到表的数据所放的hdfs的路径下,为了避免在hdfs中出现多份数据)
load data inpath ‘/student.txt’ into table student;

注:这里要区分与创建表时的location,load是在表创建好之后上传数据,location是在创建表时去就可以去相对目录下找寻数据

insert 插入数据

--追加插入
insert into table student2 values(1,'banzhang'),(2,'haiwangbin');
--覆盖插入
insert overwrite table student values(1,'banzhang'),(2,'haiwangbin');
--查询插入  --注意:第一你所插入的表必须存在 然后你查询的字段必须满足目标表的里的字段数
insert into table student  select id,name from student3;
--查询覆盖
insert overwrite table student  select id,name from student3;

as select方法直接在创建表的时候就往里搞数据

create table if not exists student3
as select id, name from student;

create as select, insert into table table_name select这两个方法就是拿来创建中间表

location,在创建表的时候就指定表内数据在hdfs中的文件夹,不能是文件

create  table if not exists student4(
id int, name string
)
row format delimited fields terminated by '\t'
location '/student4';
--指定location 必须是文件夹

import 导入

后续再说

数据导出

--无格式导出
insert overwrite local directory '/opt/module/hive/datas/export/student1' select * from student;
--有格式导出
insert overwrite local directory '/opt/module/hive/datas/export/student1' row format delimited fields terminated by '\t' select * from student;
--没有local 写在hdfs上
insert overwrite  directory '/test6' row format delimited fields terminated by '\t' select * from student;

在这里插入图片描述
然后可以通过hadoop fs -get方法下载下到本地

export 导出

后续说

数据查询

SELECT [ALL | DISTINCT] select_expr, select_expr, … all是默认值 distinct 对结果集做去重
FROM table_reference --从哪个表查
[WHERE where_condition] --过滤条件
[GROUP BY col_list] --以什么分组(可以多个列)
[HAVING col_list] --以结果过滤(可以多个列)
[ORDER BY col_list] --对结果做全局排序(可以有多个列)
[CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY col_list] --hive里面独有个3个by
]
[LIMIT number] --限制结果输出的行数(翻页)

select
count()
from join where group by having order by limit
运行顺寻:
from<join<where<group by<count(
)<having<select <order by <limit

join

可以理解为将某个表按一定要求和另一个表拼接到一起
内连接:

select
 e.empno,
 e.ename,
 d.dname
from emp e join dept d
on e.deptno=d.deptno

则就按照e.deptno=d.deptno的地方将两者拼接,没有的则补null

左外连接和右外连接意思一样,只不过是位置的问题
左外连接

select
*
from dept d  left join emp e
on d.deptno=e.deptno

则以deft为准,emp中没有对应到deft的就不显示

多表连接

多表连接查询
hive (default)>SELECT e.ename, d.dname, l.loc_name
FROM emp e
JOIN dept d
ON d.deptno = e.deptno
JOIN location l
ON d.loc = l.loc;

笛卡尔积

笛卡尔集会在下面条件下产生
(1)省略连接条件
(2)连接条件无效
(3)所有表中的所有行互相连接
hive (default)> select empno, dname from emp, dept;


版权声明:本文为weixin_45425054原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。