跳转到主要内容
ClickHouse 可在 Linux、FreeBSD 和 macOS 上构建。 如果你使用 Windows,仍然可以在运行 Linux 的虚拟机中构建 ClickHouse,例如在 VirtualBox 中运行 Ubuntu。

在 GitHub 上创建仓库

要开始为 ClickHouse 开发,您需要一个 GitHub 账户。 此外,请在本地生成一个 SSH 密钥 (如果您还没有) ,并将公钥上传到 GitHub,因为这是贡献补丁的前置条件。 接下来,点击右上角的 “fork” 按钮,在您的个人账户中 fork ClickHouse 仓库 要贡献更改,例如修复某个问题或添加某项功能,请先将更改提交到您 fork 的某个分支,然后向主仓库发起包含这些更改的 “拉取请求”。 如需使用 Git 仓库,请先安装 Git。例如,在 Ubuntu 中,运行:
sudo apt update
sudo apt install git
可在此处查看 Git 速查表。 更详细的 Git 手册见此处

将代码仓库克隆到开发机

首先,将源文件下载到你的工作机器上,也就是克隆该代码仓库:
git clone git@github.com:your_github_username/ClickHouse.git  # 将占位符替换为您的 GitHub 用户名
cd ClickHouse
此命令会创建一个名为 ClickHouse/ 的目录,其中包含源代码、测试和其他文件。 你可以在 URL 后指定一个自定义检出目录,但务必确保该路径不包含空格,否则后续构建可能会失败。 ClickHouse 的 Git 仓库使用子模块来拉取第三方库。 默认情况下不会检出子模块。 你可以选择以下任一方式
  • 运行带有 --recurse-submodules 选项的 git clone
  • 如果运行 git clone 时未使用 --recurse-submodules,请运行 git submodule update --init --jobs <N> 以显式检出所有子模块。 (例如,可将 <N> 设为 12 以并行下载。)
  • 如果运行 git clone 时未使用 --recurse-submodules,并且你希望使用 shallow 子模块检出以省略子模块中的历史记录、节省一些空间,请运行 ./contrib/update-submodules.sh。这种替代方案由 CI 使用,但不建议在本地开发中使用,因为它会让子模块的使用变得不那么方便,而且速度更慢。
要检查 Git 子模块的状态,请运行 git submodule status 如果你收到以下错误信息
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
用于连接 GitHub 的 SSH 密钥不存在。 这些密钥通常位于 ~/.ssh。 要让 GitHub 接受 SSH 密钥,您需要在 GitHub 的设置中上传它们。 您也可以通过 HTTPS 克隆仓库:
git clone https://github.com/ClickHouse/ClickHouse.git
不过,这样你将无法把更改推送到服务器。 你仍然可以暂时这样使用,之后再添加 SSH 密钥,并用 git remote 命令替换仓库的远程地址。 你也可以将原始 ClickHouse 仓库地址添加到本地仓库,以便从那里拉取更新:
git remote add upstream git@github.com:ClickHouse/ClickHouse.git
成功运行此命令后,你就可以通过执行 git pull upstream master 从 ClickHouse 主仓库拉取更新。
请不要直接使用 git push,否则你可能会推送到错误的远程仓库和/或错误的分支。 最好显式指定远程仓库名和分支名,例如 git push origin my_branch_name

编写代码

下面列出了一些快捷链接,在为 ClickHouse 编写代码时可能会用到:

IDE

Visual Studio CodeNeovim 都是过去开发 ClickHouse 时效果不错的选择。如果你使用 VS Code,我们建议使用 clangd extension 替代 IntelliSense,因为它的性能高得多。 CLion 也是一个很好的选择。不过,对于 ClickHouse 这样的大型项目,它可能会更慢一些。使用 CLion 时需要注意以下几点:
  • CLion 会自行创建一个 build 路径,并自动将构建类型设为 debug
  • 它使用的是 CLion 中指定的 CMake 版本,而不是你本地安装的版本
  • CLion 会使用 make 而不是 ninja 来运行构建任务 (这是正常行为)
你还可以使用其他 IDE,例如 Sublime TextQt CreatorKate

创建拉取请求

在 GitHub 的界面中进入你的 fork 仓库。 如果你是在某个分支上开发的,则需要选中该分支。 页面上会有一个“拉取请求”按钮。 其本质意思是:“创建一个请求,将我的更改合并到主仓库中”。 即使工作尚未完成,也可以创建拉取请求。 这种情况下,请在标题开头加上“WIP” (work in progress) ,后续可以再修改。 这有助于协作审查和讨论变更,也便于运行所有可用测试。 请务必简要说明你的更改,后续生成发布更新日志时会用到这段说明。 一旦 ClickHouse 员工给你的 PR 加上“can be tested”标签,测试就会开始。 前几项检查 (例如代码风格) 的结果会在几分钟内返回。 构建检查结果会在半小时内出来。 主要测试集会在一小时内给出结果。 系统会专门为你的拉取请求准备 ClickHouse 二进制构建产物。 要获取这些构建,请点击检查列表中“Builds”条目旁的“Details”链接。 在那里你会找到已构建的 ClickHouse .deb 包的直接链接,甚至可以将其部署到生产服务器上 (如果你不介意的话) 。

编写文档

凡是新增功能的拉取请求,都必须附带相应的文档。 如果你想预览文档改动,可在 这里 的 README.md 文件中查看如何在本地构建文档页面的说明。 向 ClickHouse 添加新函数时,可以参考下面的模板:
# newFunctionName

此处填写函数的简短描述,简要说明其功能及典型使用场景。

**语法**

\```sql
newFunctionName(arg1, arg2[, arg3])
\```

**参数**

- `arg1` — 参数说明。[DataType](../data-types/float.md){/* MIGRATE: unresolved relative link */}
- `arg2` — 参数说明。[DataType](../data-types/float.md){/* MIGRATE: unresolved relative link */}
- `arg3` — 可选参数说明(可选)。[DataType](../data-types/float.md){/* MIGRATE: unresolved relative link */}

**实现细节**

如有相关内容,在此填写实现细节说明。

**返回值**

- 返回 {此处填写函数返回内容}。[DataType](../data-types/float.md){/* MIGRATE: unresolved relative link */}

**示例**

\```sql title="Query"
SELECT 'write your example query here';
\```

\```response title="Response"
┌───────────────────────────────────┐
│ the result of the query           │
└───────────────────────────────────┘
\```

使用测试数据

开发 ClickHouse 时通常需要加载贴近真实场景的数据集。 这对于性能测试尤为重要。 我们专门准备了一组经过匿名化处理的网站分析数据。 还需要额外约 3GB 的可用磁盘空间。
    sudo apt install wget xz-utils

    wget https://datasets.clickhouse.com/hits/tsv/hits_v1.tsv.xz
    wget https://datasets.clickhouse.com/visits/tsv/visits_v1.tsv.xz

    xz -v -d hits_v1.tsv.xz
    xz -v -d visits_v1.tsv.xz

    clickhouse-client
clickhouse-client 中:
CREATE DATABASE IF NOT EXISTS test;

CREATE TABLE test.hits ( WatchID UInt64,  JavaEnable UInt8,  Title String,  GoodEvent Int16,  EventTime DateTime,  EventDate Date,  CounterID UInt32,  ClientIP UInt32,  ClientIP6 FixedString(16),  RegionID UInt32,  UserID UInt64,  CounterClass Int8,  OS UInt8,  UserAgent UInt8,  URL String,  Referer String,  URLDomain String,  RefererDomain String,  Refresh UInt8,  IsRobot UInt8,  RefererCategories Array(UInt16),  URLCategories Array(UInt16),  URLRegions Array(UInt32),  RefererRegions Array(UInt32),  ResolutionWidth UInt16,  ResolutionHeight UInt16,  ResolutionDepth UInt8,  FlashMajor UInt8,  FlashMinor UInt8,  FlashMinor2 String,  NetMajor UInt8,  NetMinor UInt8,  UserAgentMajor UInt16,  UserAgentMinor FixedString(2),  CookieEnable UInt8,  JavascriptEnable UInt8,  IsMobile UInt8,  MobilePhone UInt8,  MobilePhoneModel String,  Params String,  IPNetworkID UInt32,  TraficSourceID Int8,  SearchEngineID UInt16,  SearchPhrase String,  AdvEngineID UInt8,  IsArtifical UInt8,  WindowClientWidth UInt16,  WindowClientHeight UInt16,  ClientTimeZone Int16,  ClientEventTime DateTime,  SilverlightVersion1 UInt8,  SilverlightVersion2 UInt8,  SilverlightVersion3 UInt32,  SilverlightVersion4 UInt16,  PageCharset String,  CodeVersion UInt32,  IsLink UInt8,  IsDownload UInt8,  IsNotBounce UInt8,  FUniqID UInt64,  HID UInt32,  IsOldCounter UInt8,  IsEvent UInt8,  IsParameter UInt8,  DontCountHits UInt8,  WithHash UInt8,  HitColor FixedString(1),  UTCEventTime DateTime,  Age UInt8,  Sex UInt8,  Income UInt8,  Interests UInt16,  Robotness UInt8,  GeneralInterests Array(UInt16),  RemoteIP UInt32,  RemoteIP6 FixedString(16),  WindowName Int32,  OpenerName Int32,  HistoryLength Int16,  BrowserLanguage FixedString(2),  BrowserCountry FixedString(2),  SocialNetwork String,  SocialAction String,  HTTPError UInt16,  SendTiming Int32,  DNSTiming Int32,  ConnectTiming Int32,  ResponseStartTiming Int32,  ResponseEndTiming Int32,  FetchTiming Int32,  RedirectTiming Int32,  DOMInteractiveTiming Int32,  DOMContentLoadedTiming Int32,  DOMCompleteTiming Int32,  LoadEventStartTiming Int32,  LoadEventEndTiming Int32,  NSToDOMContentLoadedTiming Int32,  FirstPaintTiming Int32,  RedirectCount Int8,  SocialSourceNetworkID UInt8,  SocialSourcePage String,  ParamPrice Int64,  ParamOrderID String,  ParamCurrency FixedString(3),  ParamCurrencyID UInt16,  GoalsReached Array(UInt32),  OpenstatServiceName String,  OpenstatCampaignID String,  OpenstatAdID String,  OpenstatSourceID String,  UTMSource String,  UTMMedium String,  UTMCampaign String,  UTMContent String,  UTMTerm String,  FromTag String,  HasGCLID UInt8,  RefererHash UInt64,  URLHash UInt64,  CLID UInt32,  YCLID UInt64,  ShareService String,  ShareURL String,  ShareTitle String,  `ParsedParams.Key1` Array(String),  `ParsedParams.Key2` Array(String),  `ParsedParams.Key3` Array(String),  `ParsedParams.Key4` Array(String),  `ParsedParams.Key5` Array(String),  `ParsedParams.ValueDouble` Array(Float64),  IslandID FixedString(16),  RequestNum UInt32,  RequestTry UInt8) ENGINE = MergeTree PARTITION BY toYYYYMM(EventDate) SAMPLE BY intHash32(UserID) ORDER BY (CounterID, EventDate, intHash32(UserID), EventTime);

CREATE TABLE test.visits ( CounterID UInt32,  StartDate Date,  Sign Int8,  IsNew UInt8,  VisitID UInt64,  UserID UInt64,  StartTime DateTime,  Duration UInt32,  UTCStartTime DateTime,  PageViews Int32,  Hits Int32,  IsBounce UInt8,  Referer String,  StartURL String,  RefererDomain String,  StartURLDomain String,  EndURL String,  LinkURL String,  IsDownload UInt8,  TraficSourceID Int8,  SearchEngineID UInt16,  SearchPhrase String,  AdvEngineID UInt8,  PlaceID Int32,  RefererCategories Array(UInt16),  URLCategories Array(UInt16),  URLRegions Array(UInt32),  RefererRegions Array(UInt32),  IsYandex UInt8,  GoalReachesDepth Int32,  GoalReachesURL Int32,  GoalReachesAny Int32,  SocialSourceNetworkID UInt8,  SocialSourcePage String,  MobilePhoneModel String,  ClientEventTime DateTime,  RegionID UInt32,  ClientIP UInt32,  ClientIP6 FixedString(16),  RemoteIP UInt32,  RemoteIP6 FixedString(16),  IPNetworkID UInt32,  SilverlightVersion3 UInt32,  CodeVersion UInt32,  ResolutionWidth UInt16,  ResolutionHeight UInt16,  UserAgentMajor UInt16,  UserAgentMinor UInt16,  WindowClientWidth UInt16,  WindowClientHeight UInt16,  SilverlightVersion2 UInt8,  SilverlightVersion4 UInt16,  FlashVersion3 UInt16,  FlashVersion4 UInt16,  ClientTimeZone Int16,  OS UInt8,  UserAgent UInt8,  ResolutionDepth UInt8,  FlashMajor UInt8,  FlashMinor UInt8,  NetMajor UInt8,  NetMinor UInt8,  MobilePhone UInt8,  SilverlightVersion1 UInt8,  Age UInt8,  Sex UInt8,  Income UInt8,  JavaEnable UInt8,  CookieEnable UInt8,  JavascriptEnable UInt8,  IsMobile UInt8,  BrowserLanguage UInt16,  BrowserCountry UInt16,  Interests UInt16,  Robotness UInt8,  GeneralInterests Array(UInt16),  Params Array(String),  `Goals.ID` Array(UInt32),  `Goals.Serial` Array(UInt32),  `Goals.EventTime` Array(DateTime),  `Goals.Price` Array(Int64),  `Goals.OrderID` Array(String),  `Goals.CurrencyID` Array(UInt32),  WatchIDs Array(UInt64),  ParamSumPrice Int64,  ParamCurrency FixedString(3),  ParamCurrencyID UInt16,  ClickLogID UInt64,  ClickEventID Int32,  ClickGoodEvent Int32,  ClickEventTime DateTime,  ClickPriorityID Int32,  ClickPhraseID Int32,  ClickPageID Int32,  ClickPlaceID Int32,  ClickTypeID Int32,  ClickResourceID Int32,  ClickCost UInt32,  ClickClientIP UInt32,  ClickDomainID UInt32,  ClickURL String,  ClickAttempt UInt8,  ClickOrderID UInt32,  ClickBannerID UInt32,  ClickMarketCategoryID UInt32,  ClickMarketPP UInt32,  ClickMarketCategoryName String,  ClickMarketPPName String,  ClickAWAPSCampaignName String,  ClickPageName String,  ClickTargetType UInt16,  ClickTargetPhraseID UInt64,  ClickContextType UInt8,  ClickSelectType Int8,  ClickOptions String,  ClickGroupBannerID Int32,  OpenstatServiceName String,  OpenstatCampaignID String,  OpenstatAdID String,  OpenstatSourceID String,  UTMSource String,  UTMMedium String,  UTMCampaign String,  UTMContent String,  UTMTerm String,  FromTag String,  HasGCLID UInt8,  FirstVisit DateTime,  PredLastVisit Date,  LastVisit Date,  TotalVisits UInt32,  `TraficSource.ID` Array(Int8),  `TraficSource.SearchEngineID` Array(UInt16),  `TraficSource.AdvEngineID` Array(UInt8),  `TraficSource.PlaceID` Array(UInt16),  `TraficSource.SocialSourceNetworkID` Array(UInt8),  `TraficSource.Domain` Array(String),  `TraficSource.SearchPhrase` Array(String),  `TraficSource.SocialSourcePage` Array(String),  Attendance FixedString(16),  CLID UInt32,  YCLID UInt64,  NormalizedRefererHash UInt64,  SearchPhraseHash UInt64,  RefererDomainHash UInt64,  NormalizedStartURLHash UInt64,  StartURLDomainHash UInt64,  NormalizedEndURLHash UInt64,  TopLevelDomain UInt64,  URLScheme UInt64,  OpenstatServiceNameHash UInt64,  OpenstatCampaignIDHash UInt64,  OpenstatAdIDHash UInt64,  OpenstatSourceIDHash UInt64,  UTMSourceHash UInt64,  UTMMediumHash UInt64,  UTMCampaignHash UInt64,  UTMContentHash UInt64,  UTMTermHash UInt64,  FromHash UInt64,  WebVisorEnabled UInt8,  WebVisorActivity UInt32,  `ParsedParams.Key1` Array(String),  `ParsedParams.Key2` Array(String),  `ParsedParams.Key3` Array(String),  `ParsedParams.Key4` Array(String),  `ParsedParams.Key5` Array(String),  `ParsedParams.ValueDouble` Array(Float64),  `Market.Type` Array(UInt8),  `Market.GoalID` Array(UInt32),  `Market.OrderID` Array(String),  `Market.OrderPrice` Array(Int64),  `Market.PP` Array(UInt32),  `Market.DirectPlaceID` Array(UInt32),  `Market.DirectOrderID` Array(UInt32),  `Market.DirectBannerID` Array(UInt32),  `Market.GoodID` Array(String),  `Market.GoodName` Array(String),  `Market.GoodQuantity` Array(Int32),  `Market.GoodPrice` Array(Int64),  IslandID FixedString(16)) ENGINE = CollapsingMergeTree(Sign) PARTITION BY toYYYYMM(StartDate) SAMPLE BY intHash32(UserID) ORDER BY (CounterID, StartDate, intHash32(UserID), VisitID);
导入数据:
clickhouse-client --max_insert_block_size 100000 --query "INSERT INTO test.hits FORMAT TSV" < hits_v1.tsv
clickhouse-client --max_insert_block_size 100000 --query "INSERT INTO test.visits FORMAT TSV" < visits_v1.tsv
最后修改于 2026年6月10日