You need to enable JavaScript to run this app.
导航
ATTACH 语句 (ATTACH)
最近更新时间:2025.08.14 10:17:09首次发布时间:2025.05.07 15:04:15
复制全文
我的收藏
有用
有用
无用
无用

ATTACH 语句可用于附加表或字典,可适用于将数据库迁移至另一台服务器的场景。

语法
ATTACH TABLE|DICTIONARY|DATABASE [IF NOT EXISTS] [db.]name 

该查询不会在存储上创建数据,而是假设数据已经在适当的位置,只是将指定表、字典或数据库的信息添加到服务器中。执行 ATTACH 查询后,服务器将知道表、字典或数据库的存在。
如果表之前已被分离(DETACH 查询),意味着其结构已知,则可以使用简写形式而不定义结构。

附加现有表

ATTACH TABLE 语句显式注册已存在数据文件的表元数据,主要用于两种场景:

  1. 服务器启动时:服务器将表的元数据存储为包含 ATTACH 查询的文件,并在启动时运行这些查询。某些系统表除外,这些系统表会在服务器上显式创建。
  2. 永久分离恢复:如果表被永久分离,可使用 ATTACH TABLE 语句手动重新附加被永久分离的表。

语法

ATTACH TABLE [IF NOT EXISTS] [db.]name  

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建表
DROP TABLE IF EXISTS sample_db.sample_detach ON CLUSTER sample_cluster;
CREATE TABLE sample_db.sample_detach ON CLUSTER sample_cluster (
  id Int64
) 
ENGINE = MergeTree() 
ORDER BY id;

-- 3. 插入测试数据
INSERT INTO sample_db.sample_detach SELECT number FROM numbers(10);

-- 4. 查询表中数据
SELECT * FROM sample_db.sample_detach;

-- 5. 分离表
DETACH TABLE sample_db.sample_detach;

-- 6. 此时查询报错,该表不存在
SELECT * FROM sample_db.sample_detach; 

-- 7. 附加表
ATTACH TABLE sample_db.sample_detach;

-- 8. 验证附加表,有结果表示附加成功
SELECT * FROM sample_db.sample_detach; 

创建新表并附加数据

使用指定的表数据路径

该查询使用提供的结构创建一张新表,并从 user_files 中提供的目录附加表数据。

语法

ATTACH TABLE name FROM 'path/to/data/' (col1 Type1, ...) 

参数说明

参数

是否必填

说明

FROM 'path/to/data/'

user_files 目录下的数据路径,路径需已存在且包含数据文件。

(col1 Type1, ...)

表结构定义,需与数据文件格式匹配。

示例

完整工作流示例如下:

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 准备测试数据(使用表函数写入文件)
DROP TABLE IF EXISTS sample_db.attach_from_path ON CLUSTER sample_cluster;
INSERT INTO TABLE FUNCTION file(
    '/data00/clickhouse/data/user_files/attach_test/data.TSV', 
    'TSV', 
    's String, n UInt64'
) 
VALUES ('x', 100);

-- 3. 验证文件是否存在(通过尝试读取文件内容)
SELECT *
FROM file(
    '/data00/clickhouse/data/user_files/attach_test/data.TSV',  -- 完整文件路径
    'TSV',
    's String, n Int64'
)
LIMIT 1;  -- 若能返回结果,说明文件存在且可读

-- 4. 创建表结构并附加现有数据
ATTACH TABLE sample_db.attach_from_path
FROM '/data00/clickhouse/data/user_files/attach_test' 
(
    s String, 
    n UInt64
) 
ENGINE = File(TSV);

-- 5. 即时查询附加数据
SELECT * FROM sample_db.attach_from_path;

输出结果

┌─s────┬──n─┐
│ x        │ 100  │
└──────┴───┘

附加现有字典

附加一个先前分离的字典。

语法

ATTACH DICTIONARY [IF NOT EXISTS] [db.]name 

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建字典
CREATE DICTIONARY IF NOT EXISTS sample_db.sample_dict ON CLUSTER sample_cluster (
    `user_id` UInt64,
    `username` String,
    `age` UInt8 DEFAULT 0,
    `gender` UInt8 DEFAULT 0,
    `last_login` DateTime
)
PRIMARY KEY user_id
SOURCE(MySQL(
    host 'mysql_host.example.com'
    port 3306
    user 'dict_reader'
    password 'secure_password'
    db 'user_db'
    table 'users'
))
LAYOUT(FLAT())
LIFETIME(MIN 300 MAX 900);

-- 3. 分离字典
DETACH DICTIONARY sample_db.sample_dict;

-- 4. 验证字典已分离(无结果)
SHOW DICTIONARIES LIKE 'sample_db.sample_dict';

-- 5. 附加字典
ATTACH DICTIONARY IF NOT EXISTS sample_db.sample_dict;

-- 6. 验证附加字典,如果有结果则表示成功
SHOW DICTIONARIES LIKE 'sample_db.sample_dict';

附加现有数据库

附加一个先前分离的数据库。

语法

ATTACH DATABASE [IF NOT EXISTS] name [ENGINE=]

示例

-- 1. 创建 Ordinary 引擎数据库
CREATE DATABASE IF NOT EXISTS sample_db ENGINE = Ordinary;

-- 2. 分离数据库
DETACH DATABASE sample_db;

-- 3. 附加
ATTACH DATABASE sample_db ENGINE = Ordinary; 

注意

分离数据库后,如果重新附加数据库,需确保分离前后指定的数据库 engine 类型相同。如果 engine 类型不同,会导致之前创建的库、表无法删除。