uptate
This commit is contained in:
0
.env.example
Normal file
0
.env.example
Normal file
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,6 @@
|
|||||||
.env
|
.env
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
|
./docker/data
|
||||||
|
|
||||||
|
!.env*.example
|
||||||
25
docker/clickhouse/config.xml
Normal file
25
docker/clickhouse/config.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<yandex>
|
||||||
|
<logger>
|
||||||
|
<level>information</level>
|
||||||
|
<console>true</console>
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<http_port>8123</http_port>
|
||||||
|
<tcp_port>9000</tcp_port>
|
||||||
|
|
||||||
|
<listen_host>::</listen_host>
|
||||||
|
|
||||||
|
<max_connections>4096</max_connections>
|
||||||
|
<keep_alive_timeout>3</keep_alive_timeout>
|
||||||
|
<max_concurrent_queries>100</max_concurrent_queries>
|
||||||
|
|
||||||
|
<path>/var/lib/clickhouse/</path>
|
||||||
|
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
|
||||||
|
<user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
|
||||||
|
|
||||||
|
<users_config>users.xml</users_config>
|
||||||
|
|
||||||
|
<default_profile>default</default_profile>
|
||||||
|
<default_database>default</default_database>
|
||||||
|
</yandex>
|
||||||
34
docker/clickhouse/users.xml
Normal file
34
docker/clickhouse/users.xml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<yandex>
|
||||||
|
<profiles>
|
||||||
|
<default>
|
||||||
|
<max_memory_usage>10000000000</max_memory_usage>
|
||||||
|
<use_uncompressed_cache>0</use_uncompressed_cache>
|
||||||
|
<load_balancing>random</load_balancing>
|
||||||
|
</default>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<users>
|
||||||
|
<default>
|
||||||
|
<password>password</password>
|
||||||
|
<networks>
|
||||||
|
<ip>::/0</ip>
|
||||||
|
</networks>
|
||||||
|
<profile>default</profile>
|
||||||
|
<quota>default</quota>
|
||||||
|
</default>
|
||||||
|
</users>
|
||||||
|
|
||||||
|
<quotas>
|
||||||
|
<default>
|
||||||
|
<interval>
|
||||||
|
<duration>3600</duration>
|
||||||
|
<queries>0</queries>
|
||||||
|
<errors>0</errors>
|
||||||
|
<result_rows>0</result_rows>
|
||||||
|
<read_rows>0</read_rows>
|
||||||
|
<execution_time>0</execution_time>
|
||||||
|
</interval>
|
||||||
|
</default>
|
||||||
|
</quotas>
|
||||||
|
</yandex>
|
||||||
26
docker/compose.yml
Normal file
26
docker/compose.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
services:
|
||||||
|
clickhouse:
|
||||||
|
image: clickhouse/clickhouse-server:latest
|
||||||
|
container_name: clickhouse-server
|
||||||
|
ports:
|
||||||
|
- "8123:8123" # HTTP接口
|
||||||
|
- "9000:9000" # TCP接口
|
||||||
|
volumes:
|
||||||
|
- ./data/clickhouse_data:/var/lib/clickhouse
|
||||||
|
- ./data/clickhouse_logs:/var/log/clickhouse-server
|
||||||
|
- ./clickhouse/config.xml:/etc/clickhouse-server/config.xml
|
||||||
|
- ./clickhouse/users.xml:/etc/clickhouse-server/users.xml
|
||||||
|
environment:
|
||||||
|
- CLICKHOUSE_DB=default
|
||||||
|
- CLICKHOUSE_USER=default
|
||||||
|
- CLICKHOUSE_PASSWORD=password
|
||||||
|
ulimits:
|
||||||
|
nofile:
|
||||||
|
soft: 262144
|
||||||
|
hard: 262144
|
||||||
|
networks:
|
||||||
|
- clickhouse-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
clickhouse-network:
|
||||||
|
driver: bridge
|
||||||
10
package.json
10
package.json
@@ -10,14 +10,14 @@
|
|||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"packageManager": "pnpm@10.6.2",
|
"packageManager": "pnpm@10.19.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clickhouse/client": "^1.11.0",
|
"@clickhouse/client": "^1.12.1",
|
||||||
"dotenv": "^16.4.7"
|
"dotenv": "^17.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.13.11",
|
"@types/node": "^24.9.1",
|
||||||
"typescript": "^5.8.2"
|
"typescript": "^5.9.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
56
pnpm-lock.yaml
generated
56
pnpm-lock.yaml
generated
@@ -9,57 +9,57 @@ importers:
|
|||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@clickhouse/client':
|
'@clickhouse/client':
|
||||||
specifier: ^1.11.0
|
specifier: ^1.12.1
|
||||||
version: 1.11.0
|
version: 1.12.1
|
||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^16.4.7
|
specifier: ^17.2.3
|
||||||
version: 16.4.7
|
version: 17.2.3
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.13.11
|
specifier: ^24.9.1
|
||||||
version: 22.13.11
|
version: 24.9.1
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.8.2
|
specifier: ^5.9.3
|
||||||
version: 5.8.2
|
version: 5.9.3
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
'@clickhouse/client-common@1.11.0':
|
'@clickhouse/client-common@1.12.1':
|
||||||
resolution: {integrity: sha512-O0xbwv7HiMXayokrf5dYIBpjBnYekcOXWz60T1cXLmiZ8vgrfNRCiOpybJkrMXKnw9D0mWCgPUu/rgMY7U1f4g==}
|
resolution: {integrity: sha512-ccw1N6hB4+MyaAHIaWBwGZ6O2GgMlO99FlMj0B0UEGfjxM9v5dYVYql6FpP19rMwrVAroYs/IgX2vyZEBvzQLg==}
|
||||||
|
|
||||||
'@clickhouse/client@1.11.0':
|
'@clickhouse/client@1.12.1':
|
||||||
resolution: {integrity: sha512-VYTQfR0y/BtrIDEjuSce1zv85OvHak5sUhZVyNYJzbAgWHy3jFf8Os7FdUSeqyKav0xGGy+2X+dRanTFjI5Oug==}
|
resolution: {integrity: sha512-7ORY85rphRazqHzImNXMrh4vsaPrpetFoTWpZYueCO2bbO6PXYDXp/GQ4DgxnGIqbWB/Di1Ai+Xuwq2o7DJ36A==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
'@types/node@22.13.11':
|
'@types/node@24.9.1':
|
||||||
resolution: {integrity: sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==}
|
resolution: {integrity: sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==}
|
||||||
|
|
||||||
dotenv@16.4.7:
|
dotenv@17.2.3:
|
||||||
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
|
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
typescript@5.8.2:
|
typescript@5.9.3:
|
||||||
resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
|
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
undici-types@6.20.0:
|
undici-types@7.16.0:
|
||||||
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
|
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@clickhouse/client-common@1.11.0': {}
|
'@clickhouse/client-common@1.12.1': {}
|
||||||
|
|
||||||
'@clickhouse/client@1.11.0':
|
'@clickhouse/client@1.12.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@clickhouse/client-common': 1.11.0
|
'@clickhouse/client-common': 1.12.1
|
||||||
|
|
||||||
'@types/node@22.13.11':
|
'@types/node@24.9.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.20.0
|
undici-types: 7.16.0
|
||||||
|
|
||||||
dotenv@16.4.7: {}
|
dotenv@17.2.3: {}
|
||||||
|
|
||||||
typescript@5.8.2: {}
|
typescript@5.9.3: {}
|
||||||
|
|
||||||
undici-types@6.20.0: {}
|
undici-types@7.16.0: {}
|
||||||
|
|||||||
131
src/app.ts
131
src/app.ts
@@ -3,16 +3,135 @@ import { createClient } from '@clickhouse/client';
|
|||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
// 定义数据类型接口
|
||||||
|
interface DataRecord {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
created_at: Date;
|
||||||
|
}
|
||||||
|
|
||||||
const clickhouse = createClient({
|
const clickhouse = createClient({
|
||||||
url: process.env.CLICKHOUSE_URL,
|
url: process.env.CLICKHOUSE_URL,
|
||||||
username: process.env.CLICKHOUSE_USERNAME,
|
username: process.env.CLICKHOUSE_USERNAME,
|
||||||
password: process.env.CLICKHOUSE_PASSWORD,
|
password: process.env.CLICKHOUSE_PASSWORD,
|
||||||
});
|
});
|
||||||
|
|
||||||
clickhouse
|
// 生成随机数据的函数
|
||||||
.query({
|
function generateRandomData(count: number): DataRecord[] {
|
||||||
query: 'SELECT 1',
|
const titles = [
|
||||||
})
|
'人工智能的未来', '云计算发展趋势', '区块链技术应用', '大数据分析实践',
|
||||||
.then((res) => {
|
'机器学习入门', '网络安全防护', '物联网架构设计', '5G技术展望',
|
||||||
console.log(res);
|
'量子计算突破', '自动驾驶技术', '虚拟现实体验', '智能家居系统',
|
||||||
|
'数字化转型', '边缘计算应用', '分布式存储方案', '微服务架构实践',
|
||||||
|
'容器化部署', 'DevOps最佳实践', 'API设计原则', '数据库优化技巧'
|
||||||
|
];
|
||||||
|
|
||||||
|
const descriptions = [
|
||||||
|
'深入探讨技术发展趋势和未来前景,为行业发展提供重要参考。',
|
||||||
|
'详细介绍技术原理和实现方法,帮助读者快速掌握核心概念。',
|
||||||
|
'分析实际应用场景和案例研究,展示技术的实际价值。',
|
||||||
|
'总结最佳实践和经验教训,避免常见陷阱和错误。',
|
||||||
|
'展望未来发展方向和机遇挑战,为决策提供依据。'
|
||||||
|
];
|
||||||
|
|
||||||
|
const data: DataRecord[] = [];
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
for (let i = 1; i <= count; i++) {
|
||||||
|
data.push({
|
||||||
|
id: i,
|
||||||
|
title: titles[Math.floor(Math.random() * titles.length)],
|
||||||
|
description: descriptions[Math.floor(Math.random() * descriptions.length)],
|
||||||
|
created_at: new Date(now.getTime() - Math.floor(Math.random() * 30 * 24 * 60 * 60 * 1000))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建表
|
||||||
|
async function createTable() {
|
||||||
|
const createTableQuery = `
|
||||||
|
CREATE TABLE IF NOT EXISTS data_records (
|
||||||
|
id UInt32,
|
||||||
|
title String,
|
||||||
|
description String,
|
||||||
|
created_at DateTime
|
||||||
|
) ENGINE = MergeTree()
|
||||||
|
ORDER BY id
|
||||||
|
`;
|
||||||
|
|
||||||
|
await clickhouse.query({
|
||||||
|
query: createTableQuery,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('Table created or already exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入数据 - 修复数据格式问题
|
||||||
|
async function insertData(records: DataRecord[]) {
|
||||||
|
// 将数据转换为JSONEachRow格式需要的对象数组
|
||||||
|
const values = records.map(record => ({
|
||||||
|
id: record.id,
|
||||||
|
title: record.title,
|
||||||
|
description: record.description,
|
||||||
|
created_at: record.created_at.toISOString().slice(0, 19).replace('T', ' ')
|
||||||
|
}));
|
||||||
|
|
||||||
|
await clickhouse.insert({
|
||||||
|
table: 'data_records',
|
||||||
|
values: values,
|
||||||
|
format: 'JSONEachRow'
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Inserted ${records.length} records`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主函数
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
// 测试连接
|
||||||
|
const pingResult = await clickhouse.query({
|
||||||
|
query: 'SELECT 1 as ping',
|
||||||
|
});
|
||||||
|
console.log('Connected to ClickHouse');
|
||||||
|
|
||||||
|
// 创建表
|
||||||
|
await createTable();
|
||||||
|
|
||||||
|
// 生成20条随机数据
|
||||||
|
const randomData = generateRandomData(20);
|
||||||
|
console.log('Generated 20 random records');
|
||||||
|
|
||||||
|
// 插入数据
|
||||||
|
await insertData(randomData);
|
||||||
|
|
||||||
|
// 验证数据
|
||||||
|
const result = await clickhouse.query({
|
||||||
|
query: 'SELECT COUNT(*) as total FROM data_records',
|
||||||
|
});
|
||||||
|
|
||||||
|
const countData = await result.json() as { data: { total: string }[] };
|
||||||
|
console.log('Total records in table:', countData.data[0].total);
|
||||||
|
|
||||||
|
// 显示前5条记录
|
||||||
|
const sample = await clickhouse.query({
|
||||||
|
query: 'SELECT id, title, description FROM data_records ORDER by id LIMIT 5',
|
||||||
|
});
|
||||||
|
|
||||||
|
const sampleData = await sample.json() as { data: Array<{ id: number; title: string; description: string }> };
|
||||||
|
console.log('Sample records:');
|
||||||
|
sampleData.data.forEach((record) => {
|
||||||
|
console.log(`${record.id}: ${record.title} - ${record.description}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
} finally {
|
||||||
|
await clickhouse.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行主函数
|
||||||
|
main();
|
||||||
|
|||||||
0
src/demo.ts
Normal file
0
src/demo.ts
Normal file
18
src/demo/connect.ts
Normal file
18
src/demo/connect.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import dotenv from 'dotenv';
|
||||||
|
import { createClient } from '@clickhouse/client';
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
const clickhouse = createClient({
|
||||||
|
url: process.env.CLICKHOUSE_URL,
|
||||||
|
username: process.env.CLICKHOUSE_USERNAME,
|
||||||
|
password: process.env.CLICKHOUSE_PASSWORD,
|
||||||
|
});
|
||||||
|
|
||||||
|
clickhouse
|
||||||
|
.query({
|
||||||
|
query: 'SELECT 1',
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
console.log('SELECT 1');
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user