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
|
||||
node_modules
|
||||
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": [],
|
||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.6.2",
|
||||
"packageManager": "pnpm@10.19.0",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@clickhouse/client": "^1.11.0",
|
||||
"dotenv": "^16.4.7"
|
||||
"@clickhouse/client": "^1.12.1",
|
||||
"dotenv": "^17.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.13.11",
|
||||
"typescript": "^5.8.2"
|
||||
"@types/node": "^24.9.1",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
56
pnpm-lock.yaml
generated
56
pnpm-lock.yaml
generated
@@ -9,57 +9,57 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@clickhouse/client':
|
||||
specifier: ^1.11.0
|
||||
version: 1.11.0
|
||||
specifier: ^1.12.1
|
||||
version: 1.12.1
|
||||
dotenv:
|
||||
specifier: ^16.4.7
|
||||
version: 16.4.7
|
||||
specifier: ^17.2.3
|
||||
version: 17.2.3
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^22.13.11
|
||||
version: 22.13.11
|
||||
specifier: ^24.9.1
|
||||
version: 24.9.1
|
||||
typescript:
|
||||
specifier: ^5.8.2
|
||||
version: 5.8.2
|
||||
specifier: ^5.9.3
|
||||
version: 5.9.3
|
||||
|
||||
packages:
|
||||
|
||||
'@clickhouse/client-common@1.11.0':
|
||||
resolution: {integrity: sha512-O0xbwv7HiMXayokrf5dYIBpjBnYekcOXWz60T1cXLmiZ8vgrfNRCiOpybJkrMXKnw9D0mWCgPUu/rgMY7U1f4g==}
|
||||
'@clickhouse/client-common@1.12.1':
|
||||
resolution: {integrity: sha512-ccw1N6hB4+MyaAHIaWBwGZ6O2GgMlO99FlMj0B0UEGfjxM9v5dYVYql6FpP19rMwrVAroYs/IgX2vyZEBvzQLg==}
|
||||
|
||||
'@clickhouse/client@1.11.0':
|
||||
resolution: {integrity: sha512-VYTQfR0y/BtrIDEjuSce1zv85OvHak5sUhZVyNYJzbAgWHy3jFf8Os7FdUSeqyKav0xGGy+2X+dRanTFjI5Oug==}
|
||||
'@clickhouse/client@1.12.1':
|
||||
resolution: {integrity: sha512-7ORY85rphRazqHzImNXMrh4vsaPrpetFoTWpZYueCO2bbO6PXYDXp/GQ4DgxnGIqbWB/Di1Ai+Xuwq2o7DJ36A==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
'@types/node@22.13.11':
|
||||
resolution: {integrity: sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==}
|
||||
'@types/node@24.9.1':
|
||||
resolution: {integrity: sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==}
|
||||
|
||||
dotenv@16.4.7:
|
||||
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
|
||||
dotenv@17.2.3:
|
||||
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
typescript@5.8.2:
|
||||
resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@6.20.0:
|
||||
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@clickhouse/client-common@1.11.0': {}
|
||||
'@clickhouse/client-common@1.12.1': {}
|
||||
|
||||
'@clickhouse/client@1.11.0':
|
||||
'@clickhouse/client@1.12.1':
|
||||
dependencies:
|
||||
'@clickhouse/client-common': 1.11.0
|
||||
'@clickhouse/client-common': 1.12.1
|
||||
|
||||
'@types/node@22.13.11':
|
||||
'@types/node@24.9.1':
|
||||
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();
|
||||
|
||||
// 定义数据类型接口
|
||||
interface DataRecord {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
created_at: Date;
|
||||
}
|
||||
|
||||
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(res);
|
||||
// 生成随机数据的函数
|
||||
function generateRandomData(count: number): DataRecord[] {
|
||||
const titles = [
|
||||
'人工智能的未来', '云计算发展趋势', '区块链技术应用', '大数据分析实践',
|
||||
'机器学习入门', '网络安全防护', '物联网架构设计', '5G技术展望',
|
||||
'量子计算突破', '自动驾驶技术', '虚拟现实体验', '智能家居系统',
|
||||
'数字化转型', '边缘计算应用', '分布式存储方案', '微服务架构实践',
|
||||
'容器化部署', '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