ClickHouse新增用户、赋予权限及其三种连接测试方式

一、说明


官网说明:

By default, the ClickHouse server provides the default user account which is not allowed using SQL-driven access control and account management but has all the rights and permissions. The default user account is used in any cases when the username is not defined, for example, at login from client or in distributed queries. In distributed query processing a default user account is used, if the configuration of the server or cluster does not specify the user and password properties.
默认情况下,ClickHouse服务器提供默认default的用户帐户,不允许使用sql驱动的访问控制和帐户管理,但拥有所有的权限和权限。如果用户名没有定义,则在任何情况下使用默认用户帐户,例如,在从客户端登录时或在分布式查询中。在分布式查询处理中,如果服务器或集群的配置没有指定用户和密码属性,则使用默认用户帐户。
如在代码中使用sql驱动的方式且使用default账号进行增删改查,会报如下错误:Code: 497. DB::Exception: default: Not enough privileges.

由于default无法使用sql驱动访问和管理账号,故我们需要重新创建新的用户和授权

二、配置


  1. 开启default用户的access_management权限,需在/etc/clickhouse-server/users.d目录下新增user-custom.xml文件,添加如下内容:
    <?xml version="1.0"?>
    <clickhouse>
        <users>
            <default>
                <!-- User can create other users and grant rights to them. -->
                <access_management>1</access_management>
            </default>
        </users>
    </clickhouse>
    
  2. 重启clickhouse-server服务:
    systemctl restart clickhouse-server.service
    
  3. 登录clickhouse,执行:clickhouse-client --host niit04,其中niit04是虚拟机主机名,并创建新的管理员账号suben_dba并完成授权,具体语句如下:
    CREATE USER suben_dba HOST IP '0.0.0.0' IDENTIFIED WITH sha256_password BY 'suben_dba'; ## 创建用户
    GRANT ALL ON *.* TO suben_dba WITH GRANT OPTION; // 给用户授权
    show create user suben_dba; ## 查看用户权限
    show grants for suben_dba; ## 查看授权
    
    其中IP '0.0.0.0'表示允许使用user_dba从任何一台主机上登录clickhouse。新增的用户的相关信息会被保存在/var/lib/clickhouse/access目录下的user.list和某xxx.sql文件中,如下图所示:
    在这里插入图片描述
  4. 如使用上述的密码登录clickhouse会报错(不知道其他人有没有遇到这种情况),说密码不对,故需要重置suben_dba密码,采用需改配置文件的形式覆盖原来的密码,需要修改/etc/clickhouse-server/users.d目录下user-custom.xml文件,修改后文件内容如下:
    <?xml version="1.0"?>
    <clickhouse>
        <users>
            <default>
                <!-- User can create other users and grant rights to them. -->
                <access_management>1</access_management>
            </default>
            <!-- 新增的suben_dba用户的密码设置为123456 -->
            <suben_dba>
                <password>123456</password>
                <networks incl="networks" replace="replace">
                    <ip>::/0</ip>
                </networks>
                <profile>default</profile>
                <quota>default</quota>
            </suben_dba>
        </users>
    </clickhouse>
    
  5. 重启clickhouse服务,如上步骤:
    systemctl restart clickhouse-server.service
    
  6. 配置结束

三、测试


  1. 使用suben_dba用户登录到clickhouse,执行:

    clickhouse-client --host niit04 --user suben_dba --password 123456
    

    登录成功如下所示:
    在这里插入图片描述
    创建数据库suben_test和student表,创建语句如下所示:

    ## 创建数据库
    create database suben_test;
    ## 创建表
    	CREATE TABLE student
    (
        `StudentID` UInt32,
    	`StudentName` String,
    	`Grade` Int8,
    	`Class` String,
        `Address` String,
        `Age` Int8,
        `Sex` UInt8,
    	`Phone` String,
        `StartTime` DateTime
    )
    ENGINE = CollapsingMergeTree(Grade)
    PARTITION BY toYYYYMM(StartTime)
    ORDER BY (StudentID);
    
  2. 使用IDEA中的提供的clickhouse可视化界面登录:
    在这里插入图片描述
    在这里插入图片描述

  3. 使用代码方式实现对clickhouse的增加和查询的操作,如下所示:

    1. 在idea中引入clickhouse的maven依赖,如下:
      <dependency>
          <groupId>ru.yandex.clickhouse</groupId>
          <artifactId>clickhouse-jdbc</artifactId>
          <version>0.1.40</version>
      </dependency>
      
    2. 编写测试代码,如下所示:
      package com.youfan;
      
      import java.sql.*;
      
      public class TestConnectionToClickHouse {
          private static Connection connection = null;
          static {
              try {
                  Class.forName("ru.yandex.clickhouse.ClickHouseDriver");// 驱动包
                  String url = "jdbc:clickhouse://192.168.88.131:8123/suben_test";// url路径
                  String user = "suben_dba";// 账号
                  String password = "123456";// 密码
                  connection = DriverManager.getConnection(url, user, password);
              }catch (Exception e){
                  e.printStackTrace();
              }
          }
      
          public static void main(String[] args) throws SQLException {
              insert();
              select();
          }
      
          /**
           * 插入数据,建表语句如下:
           * CREATE TABLE student
           * (
           *     `StudentID` UInt32,
           * 	    `StudentName` String,
           * 	    `Grade` Int8,
           * 	    `Class` String,
           *     `Address` String,
           *     `Age` Int8,
           *     `Sex` UInt8,
           * 	    `Phone` String,
           *     `StartTime` DateTime
           * )
           * ENGINE = CollapsingMergeTree(Grade)
           * PARTITION BY toYYYYMM(StartTime)
           * ORDER BY (StudentID);
           * @throws SQLException
           */
          public static void insert() throws SQLException {
              PreparedStatement prepareStatement = connection.prepareStatement("insert into suben_test.student values (?,?,?,?,?,?,?,?,?)");
              prepareStatement.setInt(1,1001);
              prepareStatement.setString(2,"苏江明");
              prepareStatement.setInt(3,1);// 年级
              prepareStatement.setString(4,"2019级大数据一班");
              prepareStatement.setString(5,"中国-贵州-黔东南");
              prepareStatement.setInt(6,20);
              prepareStatement.setInt(7,1); // 1:男,0:女
              prepareStatement.setString(8,"18275127765");
              prepareStatement.setDate(9,new Date(2021,12,22));
              prepareStatement.executeUpdate();
              if (prepareStatement != null){
                  prepareStatement.close();
              }
              if (connection != null){
                  connection.close();
              }
          }
      
          public static void select() throws SQLException {
              PreparedStatement statement = connection.prepareStatement("select * from suben_test.student");
              ResultSet resultSet = statement.executeQuery();
              while (resultSet.next()){
                  int studentID = resultSet.getInt(1);
                  String studentName = resultSet.getString(2);
                  System.out.println(studentID + "," + studentName);
              }
          }
      }
      
      
    3. 运行测试后,数据库正常插入和查询数据
      在这里插入图片描述
      在这里插入图片描述
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐