【问题标题】:Hive insert query like SQLHive 插入查询,如 SQL
【发布时间】:2013-06-29 19:33:37
【问题描述】:

我是 Hive 新手,想知道是否有像我们在 SQL 中那样将数据插入 Hive 表的方法。我想将我的数据插入蜂巢中

INSERT INTO tablename VALUES (value1,value2..)

我了解到您可以将数据从文件加载到 hive 表,或者您可以将数据从一个表导入到 hive 表,但是有没有办法像在 SQL 中一样附加数据?

【问题讨论】:

标签: sql hadoop hive hiveql


【解决方案1】:

向Hive表中插入数据的方式: 为了演示,我使用表名作为 table1table2

  1. create table table2 as select * from table1 where 1=1; 要么 create table table2 as select * from table1;

  2. insert overwrite table table2 select * from table1; --它将数据从一个插入另一个。注意:它会刷新目标。

  3. insert into table table2 select * from table1; --它将数据从一个插入另一个。注意:它将附加到目标中。

  4. load data local inpath 'local_path' overwrite into table table1; --它将数据从本地加载到目标表中并刷新目标表。

  5. load data inpath 'hdfs_path' overwrite into table table1; --它将从hdfs位置加载数据并刷新目标表。 或

    创建表table2( col1 字符串, col2 字符串, col3 字符串) 以“,”结尾的行格式分隔字段 位置'hdfs_location';

  6. load data local inpath 'local_path' into table table1; --它将从本地加载数据并附加到目标表中。

  7. load data inpath 'hdfs_path' into table table1; --它将从hdfs位置加载数据并附加到目标表中。

  8. insert into table2 values('aa','bb','cc'); --假设table2只有3列。

  9. 多次插入hive表

【讨论】:

    【解决方案2】:

    是的,我们可以在 Hive 中使用插入查询。

    hive> create table test (id int, name string);
    

    INSERT:INSERT...VALUES 从 0.14 版开始可用。

    hive> insert into table test values (1,'mytest');
    

    这适用于insert。我们必须使用values 关键字。

    注意:用户不能使用INSERT INTO...VALUES 子句将数据插入到复杂数据类型列(数组、映射、结构、联合)中。

    【讨论】:

      【解决方案3】:

      设置几个属性以使 Hive 表支持 ACID 属性并将值插入到表中,就像在 SQL 中一样。

      在 Hive 中创建 ACID 表的条件。

      1. 该表应存储为 ORC 文件。目前只有 ORC 格式可以支持 ACID 属性。
      2. 表必须分桶

      用于创建 ACID 表的属性:

      set hive.support.concurrency =true;
      set hive.enforce.bucketing =true;
      set hive.exec.dynamic.partition.mode =nonstrict
      set hive.compactor.initiator.on = true;
      set hive.compactor.worker.threads= 1;
      set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
      

      在 hive.site.xml 中将属性 hive.in.test 设置为 true

      设置所有这些属性后,应使用 tblproperty 'transactional' ='true' 创建表。该表应分桶并保存为 orc

      CREATE TABLE table_name (col1 int,col2 string, col3 int) CLUSTERED BY col1 INTO 4 
      
      BUCKETS STORED AS orc tblproperties('transactional' ='true');
      

      现在可以像 SQL 查询一样将值插入到表中。

      INSERT INTO TABLE table_name VALUES (1,'a',100),(2,'b',200),(3,'c',300);

      【讨论】:

        【解决方案4】:

        您可以使用表格生成函数stack 将文字值插入表格中。

        首先,您需要一个只包含一行的虚拟表。你可以在limit的帮助下生成它。

        CREATE TABLE one AS
        SELECT 1 AS one
        FROM any_table_in_your_database
        LIMIT 1;
        

        现在您可以使用如下文字值创建一个新表:

        CREATE TABLE my_table AS
        SELECT stack(3
          , "row1", 1
          , "row2", 2
          , "row3", 3
        ) AS (column1, column2)
        FROM one
        ;
        

        stack 的第一个参数是您正在生成的行数。

        您还可以向现有表添加值:

        INSERT INTO TABLE my_table
        SELECT stack(2
          , "row4", 1
          , "row5", 2
        ) AS (column1, column2)
        FROM one
        ;
        

        【讨论】:

          【解决方案5】:

          您也可以为特定的列添加值,只需指定要在其中添加相应值的列名:

          Insert into Table (Col1, Col2, Col4,col5,Col7) Values ('Va11','Va2','Val4','Val5','Val7');
          

          确保您跳过的列没有空值类型。

          【讨论】:

            【解决方案6】:

            您仍然可以在 Hive 中插入复杂类型 - 它可以工作 (id 为 int,同事数组)

            insert into emp(id,colleagues) select 11, array('Alex','Jian') from (select '1')

            【讨论】:

              【解决方案7】:

              输入以下命令,在某些条件下将数据插入到 testlog 表中:

              INSERT INTO TABLE testlog SELECT * FROM table1 WHERE some condition;
              

              【讨论】:

                【解决方案8】:

                table2 的全部数据插入table1。下面是一个查询:

                INSERT INTO TABLE table1 SELECT * FROM table2; 
                

                【讨论】:

                  【解决方案9】:

                  这里的一些答案在 Hive 0.14 中已经过时了

                  https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML#LanguageManualDML-InsertingvaluesintotablesfromSQL

                  现在可以使用如下语法插入:

                  CREATE TABLE students (name VARCHAR(64), age INT, gpa DECIMAL(3, 2));
                  
                  INSERT INTO TABLE students
                    VALUES ('fred flintstone', 35, 1.28), ('barney rubble', 32, 2.32);
                  

                  【讨论】:

                    【解决方案10】:

                    unique2 建议的稍微好一点的版本如下:

                    insert overwrite table target_table
                    select * from 
                    (
                    select stack(
                        3,                 # generating new table with 3 records
                        'John', 80,        # record_1
                        'Bill', 61         # record_2
                        'Martha', 101      # record_3
                        ) 
                    ) s;
                    

                    这不需要使用已经存在的表进行破解。

                    【讨论】:

                    • 为什么要在select栈外加select语句,有必要吗?
                    【解决方案11】:

                    您可以使用以下方法。有了这个,您不需要创建临时表或 txt/csv 文件来分别进一步选择和加载。

                    INSERT INTO TABLE tablename SELECT value1,value2 FROM tempTable_with_atleast_one_records LIMIT 1.
                    

                    其中 tempTable_with_atleast_one_records 是具有至少一条记录的任何表。

                    但这种方法的问题在于,如果您有插入多行的 INSERT 语句,如下面的行。

                    INSERT INTO yourTable values (1 , 'value1') , (2 , 'value2') , (3 , 'value3') ;
                    

                    然后,您需要为每一行设置单独的 INSERT hive 语句。见下文。

                    INSERT INTO TABLE yourTable SELECT 1 , 'value1' FROM tempTable_with_atleast_one_records LIMIT 1;
                    INSERT INTO TABLE yourTable SELECT 2 , 'value2' FROM tempTable_with_atleast_one_records LIMIT 1;
                    INSERT INTO TABLE yourTable SELECT 3 , 'value3' FROM tempTable_with_atleast_one_records LIMIT 1;
                    

                    【讨论】:

                      【解决方案12】:

                      是的,您可以插入,但不像 SQL。

                      在SQL中我们可以插入行级数据,但是这里可以按字段(列)插入。

                      在此期间,您必须确保目标表和查询应具有相同的数据类型和相同的列数。

                      例如:

                      CREATE TABLE test(stu_name STRING,stu_id INT,stu_marks INT)
                      ROW FORMAT DELIMITED
                      FIELDS TERMINATED BY ','
                      STORED AS TEXTFILE;
                      
                      INSERT OVERWRITE TABLE test SELECT lang_name, lang_id, lang_legacy_id FROM export_table;
                      

                      【讨论】:

                        【解决方案13】:

                        您绝对可以将数据附加到现有表中。 (但它实际上不是 HDFS 级别的附加)。只是每当您在没有OVERWRITE 子句的情况下对现有 Hive 表执行 LOAD 或 INSERT 操作时,都会放入新数据而不替换旧数据。将为该表对应的目录中新插入的数据创建一个新文件。例如:

                        我有一个名为 demo.txt 的文件,它有 2 行:

                        ABC
                        XYZ
                        

                        创建一个表并将这个文件加载到其中

                        hive> create table demo(foo string);
                        hive> load data inpath '/demo.txt' into table demo;
                        

                        现在,如果我在这张桌子上执行 SELECT,它会给我:

                        hive> select * from demo;                        
                        OK    
                        ABC    
                        XYZ
                        

                        假设,我还有一个名为 demo2.txt 的文件:

                        PQR
                        

                        我在这个表上再次执行 LOAD 而不使用覆盖,

                        hive> load data inpath '/demo2.txt' into table demo;
                        

                        现在,如果我现在执行 SELECT,它会给我,

                        hive> select * from demo;                       
                        OK
                        ABC
                        XYZ
                        PQR
                        

                        HTH

                        【讨论】:

                          【解决方案14】:

                          我认为在这种情况下,您应该使用 HBASE,它有助于这种插入,但它不提供任何 SQL 类型的查询语言。您需要像 put 方法一样使用 HBASE 的 Java API 来进行这种插入。此外,HBASE 是面向列的 no-sql 数据库。

                          【讨论】:

                            【解决方案15】:

                            您不能插入到插入单条记录。 Hive 不支持它。您可以将要插入的所有新记录放入文件中,然后将该文件加载到 Hive 中的临时表中。然后使用 insert overwrite..select 命令将这些行插入到主 Hive 表的新分区中。这里的约束是您的主表必须预先分区。如果您不使用分区,那么您的整个表将被这些新记录替换。

                            【讨论】:

                            【解决方案16】:

                            没有。 Hive 目前不支持这种INSERT INTO tablename VALUES (x,y,z) 语法。

                            【讨论】:

                            • 有没有办法让我可以像在 SQL 中那样在表中追加数据。
                            • 支持INSERT INTO tablename SELECT ...,因此您可以将新数据放在临时表中,然后从中选择插入。
                            • 我想通过 java 客户端在 hive 中追加数据,如果我在 java 中创建一个临时数据表并仅在我的 java 客户端中编写插入和选择查询,它会工作吗?
                            • 如果你使用Java,为什么不直接追加到HDFS中的文件呢? Hive 不太适合这种东西。
                            猜你喜欢
                            • 2014-12-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2013-11-06
                            • 1970-01-01
                            • 2018-10-12
                            • 1970-01-01
                            • 2015-05-08
                            相关资源
                            最近更新 更多