blob: f2657a11df5ed9a0bd7eaf52db86f6f299de1761 [file] [log] [blame]
<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><link rel=canonical type=text/html href=https://horaedb.apache.org/docs/user-guide/><link rel=alternate type=application/rss+xml href=https://horaedb.apache.org/docs/user-guide/index.xml><meta name=robots content="noindex, nofollow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>User Guide | Apache HoraeDB</title>
<meta name=description content="A high-performance, distributed, cloud native time-series database."><meta property="og:url" content="https://horaedb.apache.org/docs/user-guide/"><meta property="og:site_name" content="Apache HoraeDB"><meta property="og:title" content="User Guide"><meta property="og:description" content="A high-performance, distributed, cloud native time-series database."><meta property="og:locale" content="en"><meta property="og:type" content="website"><meta itemprop=name content="User Guide"><meta itemprop=description content="A high-performance, distributed, cloud native time-series database."><meta itemprop=dateModified content="2024-08-21T10:34:40+08:00"><meta name=twitter:card content="summary"><meta name=twitter:title content="User Guide"><meta name=twitter:description content="A high-performance, distributed, cloud native time-series database."><link rel=preload href=/scss/main.min.5e43f8574351718e9b44966c9f3a571202ed048c082f457fb574c10b1a1bc56c.css as=style integrity="sha256-XkP4V0NRcY6bRJZsnzpXEgLtBIwIL0V/tXTBCxobxWw=" crossorigin=anonymous><link href=/scss/main.min.5e43f8574351718e9b44966c9f3a571202ed048c082f457fb574c10b1a1bc56c.css rel=stylesheet integrity="sha256-XkP4V0NRcY6bRJZsnzpXEgLtBIwIL0V/tXTBCxobxWw=" crossorigin=anonymous><script src=https://code.jquery.com/jquery-3.7.1.min.js integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin=anonymous></script><script defer src=https://unpkg.com/lunr@2.3.9/lunr.min.js integrity=sha384-203J0SNzyqHby3iU6hzvzltrWi/M41wOP5Gu+BiJMz5nwKykbkUx8Kp7iti0Lpli crossorigin=anonymous></script></head><body class=td-section><header><nav class="td-navbar js-navbar-scroll" data-bs-theme=dark><div class="container-fluid flex-column flex-md-row"><a class=navbar-brand href=/><span class="navbar-brand__logo navbar-logo"></span><span class=navbar-brand__name>Apache HoraeDB</span></a><div class="td-navbar-nav-scroll ms-md-auto" id=main_navbar><ul class=navbar-nav><li class=nav-item><a class="nav-link active" href=/docs/><i class='fa-solid fa-book'></i><span>Docs</span></a></li><li class=nav-item><a class=nav-link href=/blog/><i class='fa-brands fa-blogger'></i><span>Blog</span></a></li><li class=nav-item><a class=nav-link href=/downloads/><i class='fa-solid fa-download'></i><span>Downloads</span></a></li><li class=nav-item><a class=nav-link href=/community/><span>Community</span></a></li><li class="nav-item dropdown d-none d-lg-block"><div class=dropdown><a class="nav-link dropdown-toggle" href=# role=button data-bs-toggle=dropdown aria-haspopup=true aria-expanded=false>English</a><ul class=dropdown-menu><li><a class=dropdown-item href=/cn/docs/user-guide/>中文</a></li></ul></div></li><li class="td-light-dark-menu nav-item dropdown"><svg class="d-none"><symbol id="check2" viewBox="0 0 16 16"><path d="M13.854 3.646a.5.5.0 010 .708l-7 7a.5.5.0 01-.708.0l-3.5-3.5a.5.5.0 11.708-.708L6.5 10.293l6.646-6.647a.5.5.0 01.708.0z"/></symbol><symbol id="circle-half" viewBox="0 0 16 16"><path d="M8 15A7 7 0 108 1v14zm0 1A8 8 0 118 0a8 8 0 010 16z"/></symbol><symbol id="moon-stars-fill" viewBox="0 0 16 16"><path d="M6 .278a.768.768.0 01.08.858 7.208 7.208.0 00-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527.0 1.04-.055 1.533-.16a.787.787.0 01.81.316.733.733.0 01-.031.893A8.349 8.349.0 018.344 16C3.734 16 0 12.286.0 7.71.0 4.266 2.114 1.312 5.124.06A.752.752.0 016 .278z"/><path d="M10.794 3.148a.217.217.0 01.412.0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217.0 010 .412l-1.162.387A1.734 1.734.0 0011.593 7.69l-.387 1.162a.217.217.0 01-.412.0l-.387-1.162A1.734 1.734.0 009.31 6.593l-1.162-.387a.217.217.0 010-.412l1.162-.387a1.734 1.734.0 001.097-1.097l.387-1.162zM13.863.099a.145.145.0 01.274.0l.258.774c.115.346.386.617.732.732l.774.258a.145.145.0 010 .274l-.774.258a1.156 1.156.0 00-.732.732l-.258.774a.145.145.0 01-.274.0l-.258-.774a1.156 1.156.0 00-.732-.732l-.774-.258a.145.145.0 010-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z"/></symbol><symbol id="sun-fill" viewBox="0 0 16 16"><path d="M8 12a4 4 0 100-8 4 4 0 000 8zM8 0a.5.5.0 01.5.5v2a.5.5.0 01-1 0v-2A.5.5.0 018 0zm0 13a.5.5.0 01.5.5v2a.5.5.0 01-1 0v-2A.5.5.0 018 13zm8-5a.5.5.0 01-.5.5h-2a.5.5.0 010-1h2a.5.5.0 01.5.5zM3 8a.5.5.0 01-.5.5h-2a.5.5.0 010-1h2A.5.5.0 013 8zm10.657-5.657a.5.5.0 010 .707l-1.414 1.415a.5.5.0 11-.707-.708l1.414-1.414a.5.5.0 01.707.0zm-9.193 9.193a.5.5.0 010 .707L3.05 13.657a.5.5.0 01-.707-.707l1.414-1.414a.5.5.0 01.707.0zm9.193 2.121a.5.5.0 01-.707.0l-1.414-1.414a.5.5.0 01.707-.707l1.414 1.414a.5.5.0 010 .707zM4.464 4.465a.5.5.0 01-.707.0L2.343 3.05a.5.5.0 11.707-.707l1.414 1.414a.5.5.0 010 .708z"/></symbol></svg>
<button class="btn btn-link nav-link dropdown-toggle d-flex align-items-center" id=bd-theme type=button aria-expanded=false data-bs-toggle=dropdown data-bs-display=static aria-label="Toggle theme (auto)"><svg class="bi my-1 theme-icon-active"><use href="#circle-half"/></svg></button><ul class="dropdown-menu dropdown-menu-end" aria-labelledby=bd-theme-text><li><button type=button class="dropdown-item d-flex align-items-center" data-bs-theme-value=light aria-pressed=false>
<svg class="bi me-2 opacity-50"><use href="#sun-fill"/></svg>
Light<svg class="bi ms-auto d-none"><use href="#check2"/></svg></button></li><li><button type=button class="dropdown-item d-flex align-items-center" data-bs-theme-value=dark aria-pressed=false>
<svg class="bi me-2 opacity-50"><use href="#moon-stars-fill"/></svg>
Dark<svg class="bi ms-auto d-none"><use href="#check2"/></svg></button></li><li><button type=button class="dropdown-item d-flex align-items-center active" data-bs-theme-value=auto aria-pressed=true>
<svg class="bi me-2 opacity-50"><use href="#circle-half"/></svg>
Auto<svg class="bi ms-auto d-none"><use href="#check2"/></svg></button></li></ul></li></ul></div><div class="d-none d-lg-block"><div class="td-search td-search--offline"><div class=td-search__icon></div><input type=search class="td-search__input form-control" placeholder="Search this site…" aria-label="Search this site…" autocomplete=off data-offline-search-index-json-src=/offline-search-index.50067a676aae922ae836785e3626a1aa.json data-offline-search-base-href=/ data-offline-search-max-results=10></div></div></div></nav></header><div class="container-fluid td-outer"><div class=td-main><div class="row flex-xl-nowrap"><main class="col-12 col-md-9 col-xl-8 ps-md-5" role=main><div class=td-content><div class="pageinfo pageinfo-primary d-print-none"><p>This is the multi-page printable view of this section.
<a href=# onclick="return print(),!1">Click here to print</a>.</p><p><a href=/docs/user-guide/>Return to the regular view of this page</a>.</p></div><h1 class=title>User Guide</h1><ul><li>1: <a href=#pg-4d4e596e6b7e203d272697ba3d050c05>SQL Syntax</a></li><ul><li>1.1: <a href=#pg-b44ac2bc6defc768462e155ee00151eb>Data Model</a></li><ul><li>1.1.1: <a href=#pg-74978ec47e9ec45be0829b82a6a1cad7>Data Types</a></li><li>1.1.2: <a href=#pg-84266c71d3220e01f99899ea692d4688>Special Columns</a></li></ul><li>1.2: <a href=#pg-7d861cbbbb946005aa361b47211951d3>Identifier</a></li><li>1.3: <a href=#pg-a56eddbde23fb9aec1ef2f67e7dfaec3>Data Definition Statements</a></li><ul><li>1.3.1: <a href=#pg-68dd845e51ad6e6c2c8d0e90d0386830>ALTER TABLE</a></li><li>1.3.2: <a href=#pg-6d8b07bab2bfacd40385ad0d54b7f17c>CREATE TABLE</a></li><li>1.3.3: <a href=#pg-5f7ab6b13fb6fbd5ae2e2ca6e05687fd>DROP TABLE</a></li></ul><li>1.4: <a href=#pg-bc38c5a475ad6316c41c4e31be03630d>Data Manipulation Statements</a></li><ul><li>1.4.1: <a href=#pg-55eb2b9d918713a31388dd5e355f569d>INSERT</a></li><li>1.4.2: <a href=#pg-ae9a3b5e9aba5151ee26972acc9f7e2e>SELECT</a></li></ul><li>1.5: <a href=#pg-b503efb26df2941b96a344484d6a91a2>Utility Statements</a></li><li>1.6: <a href=#pg-6eb5d8309a31ca1c8c3311aae4346b17>Options</a></li><li>1.7: <a href=#pg-0ef89f21a5acc9b299f40523cb5ab1f8>Scalar Functions</a></li><li>1.8: <a href=#pg-efa48a3298c70ae47edb1fd4b128cd3e>Aggregate Functions</a></li></ul><li>2: <a href=#pg-661cb4aa667b1fa4642a1ab0fdc6656c>Cluster Deployment</a></li><ul><li>2.1: <a href=#pg-b594c5402ac7944a3ffa540117ff40ad>NoMeta</a></li><li>2.2: <a href=#pg-f8177b6910dfd52c70228b40053918c4>WithMeta</a></li></ul><li>3: <a href=#pg-09534b543d63f00c41f30de2514d312b>SDK</a></li><ul><li>3.1: <a href=#pg-c736df40c4147174f6f2d1eaeb49bdca>Go</a></li><li>3.2: <a href=#pg-66074b15694ea31d990c645c25042bca>Java</a></li><li>3.3: <a href=#pg-d8c6cac92b3914596fc657a1fa438885>Python</a></li><li>3.4: <a href=#pg-8b17bc3ecdfd6226bf296cc8d8c38345>Rust</a></li></ul><li>4: <a href=#pg-3c025d4e044df01b41b46653bf151f0b>Operation and Maintenance</a></li><ul><li>4.1: <a href=#pg-738a2f3b8314089a64b49e9b83ab85e7>Block List</a></li><li>4.2: <a href=#pg-5ee6dffed65012da62e99d132c3d88a0>Cluster Operation</a></li><li>4.3: <a href=#pg-8075e68e25cc23e412d57385899cca86>Observability</a></li><li>4.4: <a href=#pg-a415e58936001e7befe959b3318dac0e>Table Operation</a></li><li>4.5: <a href=#pg-5a18a99c1e89b2e34e598ab36e5b8980>Table Operation</a></li></ul><li>5: <a href=#pg-c93dd709b75734feb3f3eb452bb3638a>Ecosystem</a></li><ul><li>5.1: <a href=#pg-12941b77e52512197bc3e2eabb976682>InfluxDB</a></li><li>5.2: <a href=#pg-1fb5a05253c98bdbe5c288caa145feda>OpenTSDB</a></li><li>5.3: <a href=#pg-136053bf48d308f01c84dea97b7eed0c>Prometheus</a></li></ul></ul><div class=content></div></div><div class=td-content><h1 id=pg-4d4e596e6b7e203d272697ba3d050c05>1 - SQL Syntax</h1></div><div class=td-content><h1 id=pg-b44ac2bc6defc768462e155ee00151eb>1.1 - Data Model</h1><p>This chapter introduces the data model of HoraeDB.</p></div><div class=td-content><h1 id=pg-74978ec47e9ec45be0829b82a6a1cad7>1.1.1 - Data Types</h1><p>HoraeDB implements table model, and the supported data types are similar to MySQL.
The following table lists the mapping relationship between MySQL and HoraeDB.</p><h2 id=support-data-typecase-insensitive>Support Data Type(case-insensitive)</h2><table><thead><tr><th>SQL</th><th>HoraeDB</th></tr></thead><tbody><tr><td>null</td><td>Null</td></tr><tr><td>timestamp</td><td>Timestamp</td></tr><tr><td>double</td><td>Double</td></tr><tr><td>float</td><td>Float</td></tr><tr><td>string</td><td>String</td></tr><tr><td>Varbinary</td><td>Varbinary</td></tr><tr><td>uint64</td><td>UInt64</td></tr><tr><td>uint32</td><td>UInt32</td></tr><tr><td>uint16</td><td>UInt16</td></tr><tr><td>uint8</td><td>UInt8</td></tr><tr><td>int64/bigint</td><td>Int64</td></tr><tr><td>int32/int</td><td>Int32</td></tr><tr><td>int16/smallint</td><td>Int16</td></tr><tr><td>int8/tinyint</td><td>Int8</td></tr><tr><td>boolean</td><td>Boolean</td></tr><tr><td>date</td><td>Date</td></tr><tr><td>time</td><td>Time</td></tr></tbody></table></div><div class=td-content style=page-break-before:always><h1 id=pg-84266c71d3220e01f99899ea692d4688>1.1.2 - Special Columns</h1><p>Tables in HoraeDB have the following constraints:</p><ul><li>Primary key is required</li><li>The primary key must contain a time column, and can only contain one time column</li><li>The primary key must be non-null, so all columns in primary key must be non-null.</li></ul><h2 id=timestamp-column>Timestamp Column</h2><p>Tables in HoraeDB must have one timestamp column maps to timestamp in timeseries data, such as timestamp in OpenTSDB/Prometheus.
The timestamp column can be set with <code>timestamp key</code> keyword, like <code>TIMESTAMP KEY(ts)</code>.</p><h2 id=tag-column>Tag Column</h2><p><code>Tag</code> is use to defined column as tag column, similar to tag in timeseries data, such as tag in OpenTSDB and label in Prometheus.</p><h2 id=primary-key>Primary Key</h2><p>The primary key is used for data deduplication and sorting. The primary key is composed of some columns and one time column.
The primary key can be set in the following some ways:</p><ul><li>use <code>primary key</code> keyword</li><li>use <code>tag</code> to auto generate TSID, HoraeDB will use <code>(TSID,timestamp)</code> as primary key</li><li>only set Timestamp column, HoraeDB will use <code>(timestamp)</code> as primary key</li></ul><p>Notice: If the primary key and tag are specified at the same time, then the tag column is just an additional information identification and will not affect the logic.</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">31
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span>with_primary_key(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>ts<span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c1<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c2<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c4<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c5<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(ts),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>PRIMARY</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(c1,<span style=color:#bbb> </span>ts)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>)<span style=color:#bbb> </span>ENGINE<span style=color:#666>=</span>Analytic<span style=color:#bbb> </span><span style=color:green;font-weight:700>WITH</span><span style=color:#bbb> </span>(ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;7d&#39;</span>);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span>with_tag(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>ts<span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c1<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span>TAG<span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c2<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span>TAG<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c3<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span>TAG<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c4<span style=color:#bbb> </span>DOUBLE<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c5<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c6<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(ts)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>)<span style=color:#bbb> </span>ENGINE<span style=color:#666>=</span>Analytic<span style=color:#bbb> </span><span style=color:green;font-weight:700>WITH</span><span style=color:#bbb> </span>(ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;7d&#39;</span>);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span>with_timestamp(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>ts<span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c1<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c2<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c3<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c4<span style=color:#bbb> </span>DOUBLE<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c5<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>c6<span style=color:#bbb> </span>STRING<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(ts)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>)<span style=color:#bbb> </span>ENGINE<span style=color:#666>=</span>Analytic<span style=color:#bbb> </span><span style=color:green;font-weight:700>WITH</span><span style=color:#bbb> </span>(ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;7d&#39;</span>);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=tsid>TSID</h2><p>If <code>primary key</code>is not set, and tag columns is provided, TSID will auto generated from hash of tag columns.
In essence, this is also a mechanism for automatically generating id.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-7d861cbbbb946005aa361b47211951d3>1.2 - Identifier</h1><p>Identifier in HoraeDB can be used as table name, column name etc. It cannot be preserved keywords or start with number and punctuation symbols. HoraeDB allows to quote identifiers with back quotes (`). In this case it can be any string like <code>00_table</code> or <code>select</code>.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-a56eddbde23fb9aec1ef2f67e7dfaec3>1.3 - Data Definition Statements</h1><p>This chapter introduces the data definition statements.</p></div><div class=td-content><h1 id=pg-68dd845e51ad6e6c2c8d0e90d0386830>1.3.1 - ALTER TABLE</h1><p><code>ALTER TABLE</code> can change the schema or options of a table.</p><h2 id=alter-table-schema>ALTER TABLE SCHEMA</h2><p>HoraeDB current supports <code>ADD COLUMN</code> to alter table schema.</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:#408080;font-style:italic>-- create a table and add a column to it
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span>(a<span style=color:#bbb> </span><span style=color:green>int</span>,<span style=color:#bbb> </span>t<span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(t))<span style=color:#bbb> </span>ENGINE<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>Analytic;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>ALTER</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>ADD</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>COLUMN</span><span style=color:#bbb> </span>(b<span style=color:#bbb> </span>string);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>It now becomes:</p><pre tabindex=0><code>-- DESCRIBE TABLE `t`;
name type is_primary is_nullable is_tag
t timestamp true false false
tsid uint64 true false false
a int false true false
b string false true false
</code></pre><h2 id=alter-table-options>ALTER TABLE OPTIONS</h2><p>HoraeDB current supports <code>MODIFY SETTING</code> to alter table schema.</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:#408080;font-style:italic>-- create a table and add a column to it
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span>(a<span style=color:#bbb> </span><span style=color:green>int</span>,<span style=color:#bbb> </span>t<span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(t))<span style=color:#bbb> </span>ENGINE<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>Analytic;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>ALTER</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>MODIFY</span><span style=color:#bbb> </span>SETTING<span style=color:#bbb> </span>write_buffer_size<span style=color:#666>=</span><span style=color:#ba2121>&#39;300M&#39;</span>;<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>The SQL above tries to modify the <code>write_buffer_size</code> of the table, and the table&rsquo;s option becomes:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span>(<span style=color:#666>`</span>tsid<span style=color:#666>`</span><span style=color:#bbb> </span>uint64<span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb> </span><span style=color:#666>`</span>a<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green>int</span>,<span style=color:#bbb> </span><span style=color:green;font-weight:700>PRIMARY</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(tsid,t),<span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(t))<span style=color:#bbb> </span>ENGINE<span style=color:#666>=</span>Analytic<span style=color:#bbb> </span><span style=color:green;font-weight:700>WITH</span>(arena_block_size<span style=color:#666>=</span><span style=color:#ba2121>&#39;2097152&#39;</span>,<span style=color:#bbb> </span>compaction_strategy<span style=color:#666>=</span><span style=color:#ba2121>&#39;default&#39;</span>,<span style=color:#bbb> </span>compression<span style=color:#666>=</span><span style=color:#ba2121>&#39;ZSTD&#39;</span>,<span style=color:#bbb> </span>enable_ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;true&#39;</span>,<span style=color:#bbb> </span>num_rows_per_row_group<span style=color:#666>=</span><span style=color:#ba2121>&#39;8192&#39;</span>,<span style=color:#bbb> </span>segment_duration<span style=color:#666>=</span><span style=color:#ba2121>&#39;&#39;</span>,<span style=color:#bbb> </span>storage_format<span style=color:#666>=</span><span style=color:#ba2121>&#39;AUTO&#39;</span>,<span style=color:#bbb> </span>ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;7d&#39;</span>,<span style=color:#bbb> </span>update_mode<span style=color:#666>=</span><span style=color:#ba2121>&#39;OVERWRITE&#39;</span>,<span style=color:#bbb> </span>write_buffer_size<span style=color:#666>=</span><span style=color:#ba2121>&#39;314572800&#39;</span>)<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>Besides, the <code>ttl</code> can be altered from 7 days to 10 days by such SQL:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>ALTER</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>MODIFY</span><span style=color:#bbb> </span>SETTING<span style=color:#bbb> </span>ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;10d&#39;</span>;<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div></div><div class=td-content style=page-break-before:always><h1 id=pg-6d8b07bab2bfacd40385ad0d54b7f17c>1.3.2 - CREATE TABLE</h1><h2 id=basic-syntax>Basic syntax</h2><p>Basic syntax:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>IF</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>EXISTS</span>]<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>table_name</span><span style=color:#bbb> </span>(<span style=color:#bbb> </span>column_definitions<span style=color:#bbb> </span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>[partition_options]<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>ENGINE<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>engine_type<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>WITH</span><span style=color:#bbb> </span>(<span style=color:#bbb> </span>table_options<span style=color:#bbb> </span>)];<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>Column definition syntax:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>column_name</span><span style=color:#bbb> </span>column_type<span style=color:#bbb> </span>[[<span style=color:green;font-weight:700>NOT</span>]<span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>]<span style=color:#bbb> </span>[TAG<span style=color:#bbb> </span><span style=color:#666>|</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span><span style=color:#bbb> </span><span style=color:#666>|</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>PRIMARY</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>]<span style=color:#bbb> </span>[<span style=color:green;font-weight:700>DICTIONARY</span>]<span style=color:#bbb> </span>[<span style=color:green;font-weight:700>COMMENT</span><span style=color:#bbb> </span><span style=color:#ba2121>&#39;&#39;</span>]<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>Partition options syntax:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span>PARTITION<span style=color:#bbb> </span><span style=color:green;font-weight:700>BY</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span><span style=color:#bbb> </span>(column_list)<span style=color:#bbb> </span>[PARTITIONS<span style=color:#bbb> </span>num]<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>Table options syntax are key-value pairs. Value should be quoted with quotation marks (<code>'</code>). E.g.:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span>...<span style=color:#bbb> </span><span style=color:green;font-weight:700>WITH</span><span style=color:#bbb> </span>(<span style=color:#bbb> </span>enable_ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;false&#39;</span><span style=color:#bbb> </span>)<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=if-not-exists>IF NOT EXISTS</h2><p>Add <code>IF NOT EXISTS</code> to tell HoraeDB to ignore errors if the table name already exists.</p><h2 id=define-column>Define Column</h2><p>A column&rsquo;s definition should at least contains the name and type parts. All supported types are listed <a href=/docs/user-guide/sql/model/data_types/>here</a>.</p><p>Column is default be nullable. i.e. <code>NULL</code> keyword is implied. Adding <code>NOT NULL</code> constrains to make it required.</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:#408080;font-style:italic>-- this definition
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span>a_nullable<span style=color:#bbb> </span><span style=color:green>int</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>-- equals to
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span>a_nullable<span style=color:#bbb> </span><span style=color:green>int</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>-- add NOT NULL to make it required
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span>b_not_null<span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span><span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>A column can be marked as <a href=/docs/user-guide/sql/model/special_columns/>special column</a> with related keyword.</p><p>For string tag column, we recommend to define it as dictionary to reduce memory consumption:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:#666>`</span>tag1<span style=color:#666>`</span><span style=color:#bbb> </span>string<span style=color:#bbb> </span>TAG<span style=color:#bbb> </span><span style=color:green;font-weight:700>DICTIONARY</span><span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=engine>Engine</h2><p>Specifies which engine this table belongs to. HoraeDB current support <code>Analytic</code> engine type. This attribute is immutable.</p><h2 id=partition-options>Partition Options</h2><blockquote><p>Note: This feature is only supported in distributed version.</p></blockquote><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span>...<span style=color:#bbb> </span>PARTITION<span style=color:#bbb> </span><span style=color:green;font-weight:700>BY</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span><span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>Example below creates a table with 8 partitions, and partitioned by <code>name</code>:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>demo<span style=color:#666>`</span><span style=color:#bbb> </span>(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>name<span style=color:#666>`</span><span style=color:#bbb> </span>string<span style=color:#bbb> </span>TAG<span style=color:#bbb> </span><span style=color:green;font-weight:700>COMMENT</span><span style=color:#bbb> </span><span style=color:#ba2121>&#39;client username&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>value<span style=color:#666>`</span><span style=color:#bbb> </span>double<span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span><span style=color:#bbb> </span>(t)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>PARTITION<span style=color:#bbb> </span><span style=color:green;font-weight:700>BY</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(name)<span style=color:#bbb> </span>PARTITIONS<span style=color:#bbb> </span><span style=color:#666>8</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>ENGINE<span style=color:#666>=</span>Analytic<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>with</span><span style=color:#bbb> </span>(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>enable_ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;false&#39;</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>)<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div></div><div class=td-content style=page-break-before:always><h1 id=pg-5f7ab6b13fb6fbd5ae2e2ca6e05687fd>1.3.3 - DROP TABLE</h1><h2 id=basic-syntax>Basic syntax</h2><p>Basic syntax:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>DROP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>IF</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>EXISTS</span>]<span style=color:#bbb> </span><span style=color:green;font-weight:700>table_name</span><span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p><code>Drop Table</code> removes a specific table. This statement should be used with caution, because it removes both the table definition and table data, and this removal is not recoverable.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-bc38c5a475ad6316c41c4e31be03630d>1.4 - Data Manipulation Statements</h1><p>This chapter introduces the data manipulation statements.</p></div><div class=td-content><h1 id=pg-55eb2b9d918713a31388dd5e355f569d>1.4.1 - INSERT</h1><h2 id=basic-syntax>Basic syntax</h2><p>Basic syntax:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>INSERT</span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>INTO</span>]<span style=color:#bbb> </span>tbl_name<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>[(col_name<span style=color:#bbb> </span>[,<span style=color:#bbb> </span>col_name]<span style=color:#bbb> </span>...)]<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span>{</span><span style=color:#bbb> </span><span>{</span><span style=color:green;font-weight:700>VALUES</span><span style=color:#bbb> </span><span style=color:#666>|</span><span style=color:#bbb> </span>VALUE<span>}</span><span style=color:#bbb> </span>(value_list)<span style=color:#bbb> </span>[,<span style=color:#bbb> </span>(value_list)]<span style=color:#bbb> </span>...<span style=color:#bbb> </span><span>}</span><span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p><code>INSERT</code> inserts new rows into a HoraeDB table. Here is an example:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>INSERT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>INTO</span><span style=color:#bbb> </span>demo(<span style=color:#666>`</span>time_stammp<span style=color:#666>`</span>,<span style=color:#bbb> </span>tag1)<span style=color:#bbb> </span><span style=color:green;font-weight:700>VALUES</span>(<span style=color:#666>1667374200022</span>,<span style=color:#bbb> </span><span style=color:#ba2121>&#39;horaedb&#39;</span>)<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div></div><div class=td-content style=page-break-before:always><h1 id=pg-ae9a3b5e9aba5151ee26972acc9f7e2e>1.4.2 - SELECT</h1><h2 id=basic-syntax>Basic syntax</h2><p>Basic syntax (parts between <code>[]</code> are optional):</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>SELECT</span><span style=color:#bbb> </span>select_expr<span style=color:#bbb> </span>[,<span style=color:#bbb> </span>select_expr]<span style=color:#bbb> </span>...<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>FROM</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>table_name</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>WHERE</span><span style=color:#bbb> </span>where_condition]<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>GROUP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>BY</span><span style=color:#bbb> </span><span>{</span>col_name<span style=color:#bbb> </span><span style=color:#666>|</span><span style=color:#bbb> </span>expr<span>}</span><span style=color:#bbb> </span>...<span style=color:#bbb> </span>]<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>ORDER</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>BY</span><span style=color:#bbb> </span><span>{</span>col_name<span style=color:#bbb> </span><span style=color:#666>|</span><span style=color:#bbb> </span>expr<span>}</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>ASC</span><span style=color:#bbb> </span><span style=color:#666>|</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>DESC</span>]<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>LIMIT</span><span style=color:#bbb> </span>[<span style=color:green;font-weight:700>offset</span>,]<span style=color:#bbb> </span><span style=color:green;font-weight:700>row_count</span><span style=color:#bbb> </span>]<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p><code>Select</code> syntax in HoraeDB is similar to mysql, here is an example:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>SELECT</span><span style=color:#bbb> </span><span style=color:#666>*</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>FROM</span><span style=color:#bbb> </span><span style=color:#666>`</span>demo<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>WHERE</span><span style=color:#bbb> </span>time_stamp<span style=color:#bbb> </span><span style=color:#666>&gt;</span><span style=color:#bbb> </span><span style=color:#ba2121>&#39;2022-10-11 00:00:00&#39;</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>AND</span><span style=color:#bbb> </span>time_stamp<span style=color:#bbb> </span><span style=color:#666>&lt;</span><span style=color:#bbb> </span><span style=color:#ba2121>&#39;2022-10-12 00:00:00&#39;</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>LIMIT</span><span style=color:#bbb> </span><span style=color:#666>10</span><span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div></div><div class=td-content style=page-break-before:always><h1 id=pg-b503efb26df2941b96a344484d6a91a2>1.5 - Utility Statements</h1><p>There are serval utilities SQL in HoraeDB that can help in table manipulation or query inspection.</p><h2 id=show-create-table>SHOW CREATE TABLE</h2><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>SHOW</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>table_name</span>;<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p><code>SHOW CREATE TABLE</code> returns a <code>CREATE TABLE</code> DDL that will create a same table with the given one. Including columns, table engine and options. The schema and options shows in <code>CREATE TABLE</code> will based on the current version of the table. An example:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">28
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:#408080;font-style:italic>-- create one table
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span>(a<span style=color:#bbb> </span><span style=color:green>bigint</span>,<span style=color:#bbb> </span>b<span style=color:#bbb> </span><span style=color:green>int</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>default</span><span style=color:#bbb> </span><span style=color:#666>3</span>,<span style=color:#bbb> </span><span style=color:green;font-weight:700>c</span><span style=color:#bbb> </span>string<span style=color:#bbb> </span><span style=color:green;font-weight:700>default</span><span style=color:#bbb> </span><span style=color:#ba2121>&#39;x&#39;</span>,<span style=color:#bbb> </span>d<span style=color:#bbb> </span><span style=color:green>smallint</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>null</span>,<span style=color:#bbb> </span>t<span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(t))<span style=color:#bbb> </span>ENGINE<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>Analytic;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>-- Result: affected_rows: 0
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>-- show how one table should be created.
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span><span style=color:green;font-weight:700>SHOW</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span>;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>-- Result DDL:
</span></span></span><span style=display:flex><span><span style=color:#408080;font-style:italic></span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span>(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>tsid<span style=color:#666>`</span><span style=color:#bbb> </span>uint64<span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>a<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green>bigint</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>b<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green>int</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span><span style=color:green;font-weight:700>c</span><span style=color:#666>`</span><span style=color:#bbb> </span>string,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>d<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green>smallint</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>PRIMARY</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(t,tsid),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(t)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>)<span style=color:#bbb> </span>ENGINE<span style=color:#666>=</span>Analytic<span style=color:#bbb> </span><span style=color:green;font-weight:700>WITH</span><span style=color:#bbb> </span>(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>arena_block_size<span style=color:#666>=</span><span style=color:#ba2121>&#39;2097152&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>compaction_strategy<span style=color:#666>=</span><span style=color:#ba2121>&#39;default&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>compression<span style=color:#666>=</span><span style=color:#ba2121>&#39;ZSTD&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>enable_ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;true&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>num_rows_per_row_group<span style=color:#666>=</span><span style=color:#ba2121>&#39;8192&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>segment_duration<span style=color:#666>=</span><span style=color:#ba2121>&#39;&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>ttl<span style=color:#666>=</span><span style=color:#ba2121>&#39;7d&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>update_mode<span style=color:#666>=</span><span style=color:#ba2121>&#39;OVERWRITE&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>write_buffer_size<span style=color:#666>=</span><span style=color:#ba2121>&#39;33554432&#39;</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>)<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=describe>DESCRIBE</h2><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>DESCRIBE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>table_name</span>;<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p><code>DESCRIBE</code> will show a detailed schema of one table. The attributes include column name and type, whether it is tag and primary key (todo: ref) and whether it&rsquo;s nullable. The auto created column <code>tsid</code> will also be included (todo: ref).</p><p>Example:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span>(a<span style=color:#bbb> </span><span style=color:green>int</span>,<span style=color:#bbb> </span>b<span style=color:#bbb> </span>string,<span style=color:#bbb> </span>t<span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb> </span><span style=color:green;font-weight:700>TIMESTAMP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span>(t))<span style=color:#bbb> </span>ENGINE<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>Analytic;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>DESCRIBE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span>;<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>The result is:</p><pre tabindex=0><code>name type is_primary is_nullable is_tag
t timestamp true false false
tsid uint64 true false false
a int false true false
b string false true false
</code></pre><h2 id=explain>EXPLAIN</h2><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>EXPLAIN</span><span style=color:#bbb> </span>query;<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p><code>EXPLAIN</code> shows how a query will be executed. Add it to the beginning of a query like</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>EXPLAIN</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>SELECT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>max</span>(value)<span style=color:#bbb> </span><span style=color:green;font-weight:700>AS</span><span style=color:#bbb> </span>c1,<span style=color:#bbb> </span><span style=color:green;font-weight:700>avg</span>(value)<span style=color:#bbb> </span><span style=color:green;font-weight:700>AS</span><span style=color:#bbb> </span>c2<span style=color:#bbb> </span><span style=color:green;font-weight:700>FROM</span><span style=color:#bbb> </span><span style=color:#666>`</span>t<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>GROUP</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>BY</span><span style=color:#bbb> </span>name;<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>will give</p><pre tabindex=0><code>logical_plan
Projection: #MAX(07_optimizer_t.value) AS c1, #AVG(07_optimizer_t.value) AS c2
Aggregate: groupBy=[[#07_optimizer_t.name]], aggr=[[MAX(#07_optimizer_t.value), AVG(#07_optimizer_t.value)]]
TableScan: 07_optimizer_t projection=Some([name, value])
physical_plan
ProjectionExec: expr=[MAX(07_optimizer_t.value)@1 as c1, AVG(07_optimizer_t.value)@2 as c2]
AggregateExec: mode=FinalPartitioned, gby=[name@0 as name], aggr=[MAX(07_optimizer_t.value), AVG(07_optimizer_t.value)]
CoalesceBatchesExec: target_batch_size=4096
RepartitionExec: partitioning=Hash([Column { name: \&#34;name\&#34;, index: 0 }], 6)
AggregateExec: mode=Partial, gby=[name@0 as name], aggr=[MAX(07_optimizer_t.value), AVG(07_optimizer_t.value)]
ScanTable: table=07_optimizer_t, parallelism=8, order=None
</code></pre></div><div class=td-content style=page-break-before:always><h1 id=pg-6eb5d8309a31ca1c8c3311aae4346b17>1.6 - Options</h1><p>Options below can be used when create table for analytic engine</p><ul><li><p><code>enable_ttl</code>, <code>bool</code>. When enable TTL on a table, rows older than <code>ttl</code> will be deleted and can&rsquo;t be querid, default <code>true</code></p></li><li><p><code>ttl</code>, <code>duration</code>, lifetime of a row, only used when <code>enable_ttl</code> is <code>true</code>. default <code>7d</code>.</p></li><li><p><code>storage_format</code>, <code>string</code>. The underlying column&rsquo;s format. Availiable values:</p><ul><li><code>columnar</code>, default</li><li><code>hybrid</code>, Note: This feature is still in development, and it may change in the future.</li></ul><p>The meaning of those two values are in <a href=/docs/user-guide/sql/engine_options/#storage-format>Storage format</a> section.</p></li></ul><h2 id=storage-format>Storage Format</h2><p>There are mainly two formats supported in analytic engine. One is <code>columnar</code>, which is the traditional columnar format, with one table column in one physical column:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">9
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-plaintext data-lang=plaintext><span style=display:flex><span>| Timestamp | Device ID | Status Code | Tag 1 | Tag 2 |
</span></span><span style=display:flex><span>| --------- |---------- | ----------- | ----- | ----- |
</span></span><span style=display:flex><span>| 12:01 | A | 0 | v1 | v1 |
</span></span><span style=display:flex><span>| 12:01 | B | 0 | v2 | v2 |
</span></span><span style=display:flex><span>| 12:02 | A | 0 | v1 | v1 |
</span></span><span style=display:flex><span>| 12:02 | B | 1 | v2 | v2 |
</span></span><span style=display:flex><span>| 12:03 | A | 0 | v1 | v1 |
</span></span><span style=display:flex><span>| 12:03 | B | 0 | v2 | v2 |
</span></span><span style=display:flex><span>| ..... | | | | |
</span></span></code></pre></td></tr></table></div></div><p>The other one is <code>hybrid</code>, an experimental format used to simulate row-oriented storage in columnar storage to accelerate classic time-series query.</p><p>In classic time-series user cases like IoT or DevOps, queries will typically first group their result by series id(or device id), then by timestamp. In order to achieve good performance in those scenarios, the data physical layout should match this style, so the <code>hybrid</code> format is proposed like this:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-plaintext data-lang=plaintext><span style=display:flex><span> | Device ID | Timestamp | Status Code | Tag 1 | Tag 2 | minTime | maxTime |
</span></span><span style=display:flex><span> |-----------|---------------------|-------------|-------|-------|---------|---------|
</span></span><span style=display:flex><span> | A | [12:01,12:02,12:03] | [0,0,0] | v1 | v1 | 12:01 | 12:03 |
</span></span><span style=display:flex><span> | B | [12:01,12:02,12:03] | [0,1,0] | v2 | v2 | 12:01 | 12:03 |
</span></span><span style=display:flex><span> | ... | | | | | | |
</span></span></code></pre></td></tr></table></div></div><ul><li>Within one file, rows belonging to the same primary key(eg: series/device id) are collapsed into one row</li><li>The columns besides primary key are divided into two categories:<ul><li><code>collapsible</code>, those columns will be collapsed into a list. Used to encode <code>fields</code> in time-series table<ul><li>Note: only fixed-length type is supported now</li></ul></li><li><code>non-collapsible</code>, those columns should only contain one distinct value. Used to encode <code>tags</code> in time-series table<ul><li>Note: only string type is supported now</li></ul></li></ul></li><li>Two more columns are added, <code>minTime</code> and <code>maxTime</code>. Those are used to cut unnecessary rows out in query.<ul><li>Note: Not implemented yet.</li></ul></li></ul><h3 id=example>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>device<span style=color:#666>`</span><span style=color:#bbb> </span>(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>ts<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>tag1<span style=color:#666>`</span><span style=color:#bbb> </span>string<span style=color:#bbb> </span>tag,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>tag2<span style=color:#666>`</span><span style=color:#bbb> </span>string<span style=color:#bbb> </span>tag,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>value1<span style=color:#666>`</span><span style=color:#bbb> </span>double,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>value2<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green>int</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span><span style=color:#bbb> </span>(ts))<span style=color:#bbb> </span>ENGINE<span style=color:#666>=</span>Analytic<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>with</span><span style=color:#bbb> </span>(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>enable_ttl<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:#ba2121>&#39;false&#39;</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>storage_format<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:#ba2121>&#39;hybrid&#39;</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>This will create a table with hybrid format, users can inspect data format with <a href=https://formulae.brew.sh/formula/parquet-tools>parquet-tools</a>. The table above should have following parquet schema:</p><pre tabindex=0><code>message arrow_schema {
optional group ts (LIST) {
repeated group list {
optional int64 item (TIMESTAMP(MILLIS,false));
}
}
required int64 tsid (INTEGER(64,false));
optional binary tag1 (STRING);
optional binary tag2 (STRING);
optional group value1 (LIST) {
repeated group list {
optional double item;
}
}
optional group value2 (LIST) {
repeated group list {
optional int32 item;
}
}
}
</code></pre></div><div class=td-content style=page-break-before:always><h1 id=pg-0ef89f21a5acc9b299f40523cb5ab1f8>1.7 - Scalar Functions</h1><p>HoraeDB SQL is implemented with <a href=https://github.com/CeresDB/arrow-datafusion>DataFusion</a>, Here is the list of scalar functions. See more detail, Refer to <a href=https://github.com/CeresDB/arrow-datafusion/blob/master/docs/source/user-guide/sql/scalar_functions.md>Datafusion</a></p><h2 id=math-functions>Math Functions</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>abs(x)</td><td>absolute value</td></tr><tr><td>acos(x)</td><td>inverse cosine</td></tr><tr><td>asin(x)</td><td>inverse sine</td></tr><tr><td>atan(x)</td><td>inverse tangent</td></tr><tr><td>atan2(y, x)</td><td>inverse tangent of y / x</td></tr><tr><td>ceil(x)</td><td>nearest integer greater than or equal to argument</td></tr><tr><td>cos(x)</td><td>cosine</td></tr><tr><td>exp(x)</td><td>exponential</td></tr><tr><td>floor(x)</td><td>nearest integer less than or equal to argument</td></tr><tr><td>ln(x)</td><td>natural logarithm</td></tr><tr><td>log10(x)</td><td>base 10 logarithm</td></tr><tr><td>log2(x)</td><td>base 2 logarithm</td></tr><tr><td>power(base, exponent)</td><td>base raised to the power of exponent</td></tr><tr><td>round(x)</td><td>round to nearest integer</td></tr><tr><td>signum(x)</td><td>sign of the argument (-1, 0, +1)</td></tr><tr><td>sin(x)</td><td>sine</td></tr><tr><td>sqrt(x)</td><td>square root</td></tr><tr><td>tan(x)</td><td>tangent</td></tr><tr><td>trunc(x)</td><td>truncate toward zero</td></tr></tbody></table><h2 id=conditional-functions>Conditional Functions</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>coalesce</td><td>Returns the first of its arguments that is not null. Null is returned only if all arguments are null. It is often used to substitute a default value for null values when data is retrieved for display.</td></tr><tr><td>nullif</td><td>Returns a null value if value1 equals value2; otherwise it returns value1. This can be used to perform the inverse operation of the coalesce expression.</td></tr></tbody></table><h2 id=string-functions>String Functions</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>ascii</td><td>Returns the numeric code of the first character of the argument. In UTF8 encoding, returns the Unicode code point of the character. In other multibyte encodings, the argument must be an ASCII character.</td></tr><tr><td>bit_length</td><td>Returns the number of bits in a character string expression.</td></tr><tr><td>btrim</td><td>Removes the longest string containing any of the specified characters from the start and end of string.</td></tr><tr><td>char_length</td><td>Equivalent to length.</td></tr><tr><td>character_length</td><td>Equivalent to length.</td></tr><tr><td>concat</td><td>Concatenates two or more strings into one string.</td></tr><tr><td>concat_ws</td><td>Combines two values with a given separator.</td></tr><tr><td>chr</td><td>Returns the character based on the number code.</td></tr><tr><td>initcap</td><td>Capitalizes the first letter of each word in a string.</td></tr><tr><td>left</td><td>Returns the specified leftmost characters of a string.</td></tr><tr><td>length</td><td>Returns the number of characters in a string.</td></tr><tr><td>lower</td><td>Converts all characters in a string to their lower case equivalent.</td></tr><tr><td>lpad</td><td>Left-pads a string to a given length with a specific set of characters.</td></tr><tr><td>ltrim</td><td>Removes the longest string containing any of the characters in characters from the start of string.</td></tr><tr><td>md5</td><td>Calculates the MD5 hash of a given string.</td></tr><tr><td>octet_length</td><td>Equivalent to length.</td></tr><tr><td>repeat</td><td>Returns a string consisting of the input string repeated a specified number of times.</td></tr><tr><td>replace</td><td>Replaces all occurrences in a string of a substring with a new substring.</td></tr><tr><td>reverse</td><td>Reverses a string.</td></tr><tr><td>right</td><td>Returns the specified rightmost characters of a string.</td></tr><tr><td>rpad</td><td>Right-pads a string to a given length with a specific set of characters.</td></tr><tr><td>rtrim</td><td>Removes the longest string containing any of the characters in characters from the end of string.</td></tr><tr><td>digest</td><td>Calculates the hash of a given string.</td></tr><tr><td>split_part</td><td>Splits a string on a specified delimiter and returns the specified field from the resulting array.</td></tr><tr><td>starts_with</td><td>Checks whether a string starts with a particular substring.</td></tr><tr><td>strpos</td><td>Searches a string for a specific substring and returns its position.</td></tr><tr><td>substr</td><td>Extracts a substring of a string.</td></tr><tr><td>translate</td><td>Translates one set of characters into another.</td></tr><tr><td>trim</td><td>Removes the longest string containing any of the characters in characters from either the start or end of string.</td></tr><tr><td>upper</td><td>Converts all characters in a string to their upper case equivalent.</td></tr></tbody></table><h2 id=regular-expression-functions>Regular Expression Functions</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>regexp_match</td><td>Determines whether a string matches a regular expression pattern.</td></tr><tr><td>regexp_replace</td><td>Replaces all occurrences in a string of a substring that matches a regular expression pattern with a new substring.</td></tr></tbody></table><h2 id=temporal-functions>Temporal Functions</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>to_timestamp</td><td>Converts a string to type Timestamp(Nanoseconds, None).</td></tr><tr><td>to_timestamp_millis</td><td>Converts a string to type Timestamp(Milliseconds, None).</td></tr><tr><td>to_timestamp_micros</td><td>Converts a string to type Timestamp(Microseconds, None).</td></tr><tr><td>to_timestamp_seconds</td><td>Converts a string to type Timestamp(Seconds, None).</td></tr><tr><td>extract</td><td>Retrieves subfields such as year or hour from date/time values.</td></tr><tr><td>date_part</td><td>Retrieves subfield from date/time values.</td></tr><tr><td>date_trunc</td><td>Truncates date/time values to specified precision.</td></tr><tr><td>date_bin</td><td>Bin date/time values to specified precision.</td></tr><tr><td>from_unixtime</td><td>Converts Unix epoch to type Timestamp(Nanoseconds, None).</td></tr><tr><td>now</td><td>Returns current time as Timestamp(Nanoseconds, UTC).</td></tr></tbody></table><h2 id=other-functions>Other Functions</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>array</td><td>Create an array.</td></tr><tr><td>arrow_typeof</td><td>Returns underlying type.</td></tr><tr><td>in_list</td><td>Check if value in list.</td></tr><tr><td>random</td><td>Generate random value.</td></tr><tr><td>sha224</td><td>sha224</td></tr><tr><td>sha256</td><td>sha256</td></tr><tr><td>sha384</td><td>sha384</td></tr><tr><td>sha512</td><td>sha512</td></tr><tr><td>to_hex</td><td>Convert to hex.</td></tr></tbody></table></div><div class=td-content style=page-break-before:always><h1 id=pg-efa48a3298c70ae47edb1fd4b128cd3e>1.8 - Aggregate Functions</h1><p>HoraeDB SQL is implemented with <a href=https://github.com/apache/arrow-datafusion>DataFusion</a>, Here is the list of aggregate functions. See more detail, Refer to <a href=https://github.com/apache/arrow-datafusion/blob/master/docs/source/user-guide/sql/aggregate_functions.md>Datafusion</a></p><h2 id=general>General</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>min</td><td>Returns the minimum value in a numerical column</td></tr><tr><td>max</td><td>Returns the maximum value in a numerical column</td></tr><tr><td>count</td><td>Returns the number of rows</td></tr><tr><td>avg</td><td>Returns the average of a numerical column</td></tr><tr><td>sum</td><td>Sums a numerical column</td></tr><tr><td>array_agg</td><td>Puts values into an array</td></tr></tbody></table><h2 id=statistical>Statistical</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>var / var_samp</td><td>Returns the variance of a given column</td></tr><tr><td>var_pop</td><td>Returns the population variance of a given column</td></tr><tr><td>stddev / stddev_samp</td><td>Returns the standard deviation of a given column</td></tr><tr><td>stddev_pop</td><td>Returns the population standard deviation of a given column</td></tr><tr><td>covar / covar_samp</td><td>Returns the covariance of a given column</td></tr><tr><td>covar_pop</td><td>Returns the population covariance of a given column</td></tr><tr><td>corr</td><td>Returns the correlation coefficient of a given column</td></tr></tbody></table><h2 id=approximate>Approximate</h2><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>approx_distinct</td><td>Returns the approximate number (HyperLogLog) of distinct input values</td></tr><tr><td>approx_median</td><td>Returns the approximate median of input values. It is an alias of approx_percentile_cont(x, 0.5).</td></tr><tr><td>approx_percentile_cont</td><td>Returns the approximate percentile (TDigest) of input values, where p is a float64 between 0 and 1 (inclusive). It supports raw data as input and build Tdigest sketches during query time, and is approximately equal to approx_percentile_cont_with_weight(x, 1, p).</td></tr><tr><td>approx_percentile_cont_with_weight</td><td>Returns the approximate percentile (TDigest) of input values with weight, where w is weight column expression and p is a float64 between 0 and 1 (inclusive). It supports raw data as input or pre-aggregated TDigest sketches, then builds or merges Tdigest sketches during query time. TDigest sketches are a list of centroid (x, w), where x stands for mean and w stands for weight.</td></tr></tbody></table></div><div class=td-content style=page-break-before:always><h1 id=pg-661cb4aa667b1fa4642a1ab0fdc6656c>2 - Cluster Deployment</h1><p>In the <a href=https://horaedb.apache.org/docs/getting-started/>Getting Started</a> section, we have introduced the deployment of single HoraeDB instance.</p><p>Besides, as a distributed timeseries database, multiple HoraeDB instances can be deployed as a cluster to serve with high availability and scalability.</p><p>Currently, work about the integration with kubernetes is still in process, so HoraeDB cluster can only be deployed manually. And there are two modes of cluster deployment:</p></div><div class=td-content style=page-break-before:always><h1 id=pg-b594c5402ac7944a3ffa540117ff40ad>2.1 - NoMeta</h1><p><strong>Note: This feature is for testing use only, not recommended for production use, related features may change in the future.</strong></p><p>This guide shows how to deploy a HoraeDB cluster without HoraeMeta, but with static, rule-based routing.</p><p>The crucial point here is that HoraeDB server provides configurable routing function on table name so what we need is just a valid config containing routing rules which will be shipped to every HoraeDB instance in the cluster.</p><h2 id=target>Target</h2><p>First, let&rsquo;s assume that our target is to deploy a cluster consisting of two HoraeDB instances on the same machine. And a large cluster of more HoraeDB instances can be deployed according to the two-instance example.</p><h2 id=prepare-config>Prepare Config</h2><h3 id=basic>Basic</h3><p>Suppose the basic config of HoraeDB is:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[server]
</span></span><span style=display:flex><span>bind_addr = <span style=color:#ba2121>&#34;0.0.0.0&#34;</span>
</span></span><span style=display:flex><span>http_port = <span style=color:#666>5440</span>
</span></span><span style=display:flex><span>grpc_port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[logger]
</span></span><span style=display:flex><span>level = <span style=color:#ba2121>&#34;info&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[tracing]
</span></span><span style=display:flex><span>dir = <span style=color:#ba2121>&#34;/tmp/horaedb&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Local&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;RocksDB&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb&#34;</span>
</span></span></code></pre></td></tr></table></div></div><p>In order to deploy two HoraeDB instances on the same machine, the config should choose different ports to serve and data directories to store data.</p><p>Say the <code>HoraeDB_0</code>&rsquo;s config is:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[server]
</span></span><span style=display:flex><span>bind_addr = <span style=color:#ba2121>&#34;0.0.0.0&#34;</span>
</span></span><span style=display:flex><span>http_port = <span style=color:#666>5440</span>
</span></span><span style=display:flex><span>grpc_port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[logger]
</span></span><span style=display:flex><span>level = <span style=color:#ba2121>&#34;info&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[tracing]
</span></span><span style=display:flex><span>dir = <span style=color:#ba2121>&#34;/tmp/horaedb_0&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Local&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb_0&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;RocksDB&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb_0&#34;</span>
</span></span></code></pre></td></tr></table></div></div><p>Then the <code>HoraeDB_1</code>&rsquo;s config is:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[server]
</span></span><span style=display:flex><span>bind_addr = <span style=color:#ba2121>&#34;0.0.0.0&#34;</span>
</span></span><span style=display:flex><span>http_port = <span style=color:#666>15440</span>
</span></span><span style=display:flex><span>grpc_port = <span style=color:#666>18831</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[logger]
</span></span><span style=display:flex><span>level = <span style=color:#ba2121>&#34;info&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[tracing]
</span></span><span style=display:flex><span>dir = <span style=color:#ba2121>&#34;/tmp/horaedb_1&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Local&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb_1&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;RocksDB&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb_1&#34;</span>
</span></span></code></pre></td></tr></table></div></div><h3 id=schemashard-declaration>Schema&amp;Shard Declaration</h3><p>Then we should define the common part &ndash; schema&amp;shard declaration and routing rules.</p><p>Here is the config for schema&amp;shard declaration:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">28
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[cluster_deployment]
</span></span><span style=display:flex><span>mode = <span style=color:#ba2121>&#34;NoMeta&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards]]
</span></span><span style=display:flex><span>schema = <span style=color:#ba2121>&#39;public_0&#39;</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>0</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>1</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards]]
</span></span><span style=display:flex><span>schema = <span style=color:#ba2121>&#39;public_1&#39;</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>0</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>1</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>18831</span>
</span></span></code></pre></td></tr></table></div></div><p>In the config above, two schemas are declared:</p><ul><li><code>public_0</code> has two shards served by <code>HoraeDB_0</code>.</li><li><code>public_1</code> has two shards served by both <code>HoraeDB_0</code> and <code>HoraeDB_1</code>.</li></ul><h3 id=routing-rules>Routing Rules</h3><p>Provided with schema&amp;shard declaration, routing rules can be defined and here is an example of prefix rule:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[[cluster_deployment.route_rules.prefix_rules]]
</span></span><span style=display:flex><span>schema = <span style=color:#ba2121>&#39;public_0&#39;</span>
</span></span><span style=display:flex><span>prefix = <span style=color:#ba2121>&#39;prod_&#39;</span>
</span></span><span style=display:flex><span>shard = <span style=color:#666>0</span>
</span></span></code></pre></td></tr></table></div></div><p>This rule means that all the table with <code>prod_</code> prefix belonging to <code>public_0</code> should be routed to <code>shard_0</code> of <code>public_0</code>, that is to say, <code>HoraeDB_0</code>. As for the other tables whose names are not prefixed by <code>prod_</code> will be routed by hash to both <code>shard_0</code> and <code>shard_1</code> of <code>public_0</code>.</p><p>Besides prefix rule, we can also define a hash rule:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[[cluster_deployment.route_rules.hash_rules]]
</span></span><span style=display:flex><span>schema = <span style=color:#ba2121>&#39;public_1&#39;</span>
</span></span><span style=display:flex><span>shards = [<span style=color:#666>0</span>, <span style=color:#666>1</span>]
</span></span></code></pre></td></tr></table></div></div><p>This rule tells HoraeDB to route <code>public_1</code>&rsquo;s tables to both <code>shard_0</code> and <code>shard_1</code> of <code>public_1</code>, that is to say, <code>HoraeDB0</code> and <code>HoraeDB_1</code>. And actually this is default routing behavior if no such rule provided for schema <code>public_1</code>.</p><p>For now, we can provide the full example config for <code>HoraeDB_0</code> and <code>HoraeDB_1</code>:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">48
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[server]
</span></span><span style=display:flex><span>bind_addr = <span style=color:#ba2121>&#34;0.0.0.0&#34;</span>
</span></span><span style=display:flex><span>http_port = <span style=color:#666>5440</span>
</span></span><span style=display:flex><span>grpc_port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>mysql_port = <span style=color:#666>3307</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[logger]
</span></span><span style=display:flex><span>level = <span style=color:#ba2121>&#34;info&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[tracing]
</span></span><span style=display:flex><span>dir = <span style=color:#ba2121>&#34;/tmp/horaedb_0&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Local&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb_0&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;RocksDB&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb_0&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[cluster_deployment]
</span></span><span style=display:flex><span>mode = <span style=color:#ba2121>&#34;NoMeta&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards]]
</span></span><span style=display:flex><span>schema = <span style=color:#ba2121>&#39;public_0&#39;</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>0</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>1</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards]]
</span></span><span style=display:flex><span>schema = <span style=color:#ba2121>&#39;public_1&#39;</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>0</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>1</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>18831</span>
</span></span></code></pre></td></tr></table></div></div><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">48
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[server]
</span></span><span style=display:flex><span>bind_addr = <span style=color:#ba2121>&#34;0.0.0.0&#34;</span>
</span></span><span style=display:flex><span>http_port = <span style=color:#666>15440</span>
</span></span><span style=display:flex><span>grpc_port = <span style=color:#666>18831</span>
</span></span><span style=display:flex><span>mysql_port = <span style=color:#666>13307</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[logger]
</span></span><span style=display:flex><span>level = <span style=color:#ba2121>&#34;info&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[tracing]
</span></span><span style=display:flex><span>dir = <span style=color:#ba2121>&#34;/tmp/horaedb_1&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Local&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb_1&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;RocksDB&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/tmp/horaedb_1&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[cluster_deployment]
</span></span><span style=display:flex><span>mode = <span style=color:#ba2121>&#34;NoMeta&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards]]
</span></span><span style=display:flex><span>schema = <span style=color:#ba2121>&#39;public_0&#39;</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>0</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>1</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards]]
</span></span><span style=display:flex><span>schema = <span style=color:#ba2121>&#39;public_1&#39;</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>0</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>[[cluster_deployment.topology.schema_shards.shard_views]]
</span></span><span style=display:flex><span>shard_id = <span style=color:#666>1</span>
</span></span><span style=display:flex><span>[cluster_deployment.topology.schema_shards.shard_views.endpoint]
</span></span><span style=display:flex><span>addr = <span style=color:#ba2121>&#39;127.0.0.1&#39;</span>
</span></span><span style=display:flex><span>port = <span style=color:#666>18831</span>
</span></span></code></pre></td></tr></table></div></div><p>Let&rsquo;s name the two different config files as <code>config_0.toml</code> and <code>config_1.toml</code> but you should know in the real environment the different HoraeDB instances can be deployed across different machines, that is to say, there is no need to choose different ports and data directories for different HoraeDB instances so that all the HoraeDB instances can share one exactly <strong>same</strong> config file.</p><h2 id=start-horaedbs>Start HoraeDBs</h2><p>After the configs are prepared, what we should to do is to start HoraeDB container with the specific config.</p><p>Just run the commands below:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>sudo docker run -d -t --name horaedb_0 -p 5440:5440 -p 8831:8831 -v <span style=color:green;font-weight:700>$(</span><span style=color:green>pwd</span><span style=color:green;font-weight:700>)</span>/config_0.toml:/etc/horaedb/horaedb.toml horaedb/horaedb-server
</span></span><span style=display:flex><span>sudo docker run -d -t --name horaedb_1 -p 15440:15440 -p 18831:18831 -v <span style=color:green;font-weight:700>$(</span><span style=color:green>pwd</span><span style=color:green;font-weight:700>)</span>/config_1.toml:/etc/horaedb/horaedb.toml horaedb/horaedb-server
</span></span></code></pre></td></tr></table></div></div><p>After the two containers are created and starting running, read and write requests can be served by the two-instances HoraeDB cluster.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-f8177b6910dfd52c70228b40053918c4>2.2 - WithMeta</h1><p>This guide shows how to deploy a HoraeDB cluster with HoraeMeta. And with the HoraeMeta, the whole HoraeDB cluster will feature: high availability, load balancing and horizontal scalability if the underlying storage used by HoraeDB is separated service.</p><h2 id=deploy-horaemeta>Deploy HoraeMeta</h2><h3 id=introduce>Introduce</h3><p>HoraeMeta is one of the core services of HoraeDB distributed mode, it is used to manage and schedule the HoraeDB cluster. By the way, the high availability of HoraeMeta is ensured by embedding <a href=https://github.com/etcd-io/etcd>ETCD</a>. Also, the ETCD service is provided for HoraeDB servers to manage the distributed shard locks.</p><h3 id=build>Build</h3><ul><li>Golang version >= 1.19.</li><li>run <code>make build</code> in root path of <a href=https://github.com/apache/horaedb/tree/main/horaemeta>HoraeMeta</a>.</li></ul><h3 id=deploy>Deploy</h3><h4 id=config>Config</h4><p>At present, HoraeMeta supports specifying service startup configuration in two ways: configuration file and environment variable. We provide an example of configuration file startup. For details, please refer to <a href=https://github.com/apache/horaedb/tree/main/horaemeta/config>config</a>. The configuration priority of environment variables is higher than that of configuration files. When they exist at the same time, the environment variables shall prevail.</p><h4 id=dynamic-or-static>Dynamic or Static</h4><p>Even with the HoraeMeta, the HoraeDB cluster can be deployed with a static or a dynamic topology. With a static topology, the table distribution is static after the cluster is initialized while with the dynamic topology, the tables can migrate between different HoraeDB nodes to achieve load balance or failover. However, the dynamic topology can be enabled only if the storage used by the HoraeDB node is remote, otherwise the data may be corrupted when tables are transferred to a different HoraeDB node when the data of HoraeDB is persisted locally.</p><p>Currently, the dynamic scheduling over the cluster topology is disabled by default in HoraeMeta, and in this guide, we won&rsquo;t enable it because local storage is adopted here. If you want to enable the dynamic scheduling, the <code>TOPOLOGY_TYPE</code> can be set as <code>dynamic</code> (<code>static</code> by default), and after that, load balancing and failover will work. However, don&rsquo;t enable it if what the underlying storage is local disk.</p><p>With the static topology, the params <code>DEFAULT_CLUSTER_NODE_COUNT</code>, which denotes the number of the HoraeDB nodes in the deployed cluster and should be set to the real number of machines for HoraeDB server, matters a lot because after cluster initialization the HoraeDB nodes can&rsquo;t be changed any more.</p><h4 id=start-horaemeta-instances>Start HoraeMeta Instances</h4><p>HoraeMeta is based on etcd to achieve high availability. In product environment, we usually deploy multiple nodes, but in local environment and testing, we can directly deploy a single node to simplify the entire deployment process.</p><ul><li>Standalone</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>docker run -d --name horaemeta-server <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> -p 2379:2379 <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> ghcr.io/apache/horaemeta-server:nightly-20231225-ab067bf0
</span></span></code></pre></td></tr></table></div></div><ul><li>Cluster</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>wget https://horaedb.apache.org/config-horaemeta-cluster0.toml
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>docker run -d --network<span style=color:#666>=</span>host --name horaemeta-server0 <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> -v <span style=color:green;font-weight:700>$(</span><span style=color:green>pwd</span><span style=color:green;font-weight:700>)</span>/config-horaemeta-cluster0.toml:/etc/horaemeta/horaemeta.toml <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> ghcr.io/apache/horaemeta-server:nightly-20231225-ab067bf0
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>wget https://horaedb.apache.org/config-horaemeta-cluster1.toml
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>docker run -d --network<span style=color:#666>=</span>host --name horaemeta-server1 <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> -v <span style=color:green;font-weight:700>$(</span><span style=color:green>pwd</span><span style=color:green;font-weight:700>)</span>/config-horaemeta-cluster1.toml:/etc/horaemeta/horaemeta.toml <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> ghcr.io/apache/horaemeta-server:nightly-20231225-ab067bf0
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>wget https://horaedb.apache.org/config-horaemeta-cluster2.toml
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>docker run -d --network<span style=color:#666>=</span>host --name horaemeta-server2 <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> -v <span style=color:green;font-weight:700>$(</span><span style=color:green>pwd</span><span style=color:green;font-weight:700>)</span>/config-horaemeta-cluster2.toml:/etc/horaemeta/horaemeta.toml <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> ghcr.io/apache/horaemeta-server:nightly-20231225-ab067bf0
</span></span></code></pre></td></tr></table></div></div><p>And if the storage used by the HoraeDB is remote and you want to enable the dynamic schedule features of the HoraeDB cluster, the <code>-e TOPOLOGY_TYPE=dynamic</code> can be added to the docker run command.</p><h2 id=deploy-horaedb>Deploy HoraeDB</h2><p>In the <code>NoMeta</code> mode, HoraeDB only requires the local disk as the underlying storage because the topology of the HoraeDB cluster is static. However, with HoraeMeta, the cluster topology can be dynamic, that is to say, HoraeDB can be configured to use a non-local storage service for the features of a distributed system: HA, load balancing, scalability and so on. And HoraeDB can be still configured to use a local storage with HoraeMeta, which certainly leads to a static cluster topology.</p><p>The relevant storage configurations include two parts:</p><ul><li>Object Storage</li><li>WAL Storage</li></ul><p>Note: If you are deploying HoraeDB over multiple nodes in a production environment, please set the environment variable for the server address as follows:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span><span style=color:green>export</span> <span style=color:#19177c>HORAEDB_SERVER_ADDR</span><span style=color:#666>=</span><span style=color:#ba2121>&#34;{server_address}:8831&#34;</span>
</span></span></code></pre></td></tr></table></div></div><p>This address is used for communication between HoraeMeta and HoraeDB, please ensure it is valid.</p><h3 id=object-storage>Object Storage</h3><h4 id=local-storage>Local Storage</h4><p>Similarly, we can configure HoraeDB to use a local disk as the underlying storage:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Local&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/home/admin/data/horaedb&#34;</span>
</span></span></code></pre></td></tr></table></div></div><h4 id=oss>OSS</h4><p>Aliyun OSS can be also used as the underlying storage for HoraeDB, with which the data is replicated for disaster recovery. Here is a example config, and you have to replace the templates with the real OSS parameters:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Aliyun&#34;</span>
</span></span><span style=display:flex><span>key_id = <span style=color:#ba2121>&#34;{key_id}&#34;</span>
</span></span><span style=display:flex><span>key_secret = <span style=color:#ba2121>&#34;{key_secret}&#34;</span>
</span></span><span style=display:flex><span>endpoint = <span style=color:#ba2121>&#34;{endpoint}&#34;</span>
</span></span><span style=display:flex><span>bucket = <span style=color:#ba2121>&#34;{bucket}&#34;</span>
</span></span><span style=display:flex><span>prefix = <span style=color:#ba2121>&#34;{data_dir}&#34;</span>
</span></span></code></pre></td></tr></table></div></div><h4 id=s3>S3</h4><p>Amazon S3 can be also used as the underlying storage for HoraeDB. Here is a example config, and you have to replace the templates with the real S3 parameters:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">8
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;S3&#34;</span>
</span></span><span style=display:flex><span>region = <span style=color:#ba2121>&#34;{region}&#34;</span>
</span></span><span style=display:flex><span>key_id = <span style=color:#ba2121>&#34;{key_id}&#34;</span>
</span></span><span style=display:flex><span>key_secret = <span style=color:#ba2121>&#34;{key_secret}&#34;</span>
</span></span><span style=display:flex><span>endpoint = <span style=color:#ba2121>&#34;{endpoint}&#34;</span>
</span></span><span style=display:flex><span>bucket = <span style=color:#ba2121>&#34;{bucket}&#34;</span>
</span></span><span style=display:flex><span>prefix = <span style=color:#ba2121>&#34;{prefix}&#34;</span>
</span></span></code></pre></td></tr></table></div></div><h3 id=wal-storage>WAL Storage</h3><h4 id=rocksdb>RocksDB</h4><p>The WAL based on RocksDB is also a kind of local storage for HoraeDB, which is easy for a quick start:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;RocksDB&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/home/admin/data/horaedb&#34;</span>
</span></span></code></pre></td></tr></table></div></div><h4 id=oceanbase>OceanBase</h4><p>If you have deployed a OceanBase cluster, HoraeDB can use it as the WAL storage for data disaster recovery. Here is a example config for such WAL, and you have to replace the templates with real OceanBase parameters:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Obkv&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal.data_namespace]
</span></span><span style=display:flex><span>ttl = <span style=color:#ba2121>&#34;365d&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal.obkv]
</span></span><span style=display:flex><span>full_user_name = <span style=color:#ba2121>&#34;{full_user_name}&#34;</span>
</span></span><span style=display:flex><span>param_url = <span style=color:#ba2121>&#34;{param_url}&#34;</span>
</span></span><span style=display:flex><span>password = <span style=color:#ba2121>&#34;{password}&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal.obkv.client]
</span></span><span style=display:flex><span>sys_user_name = <span style=color:#ba2121>&#34;{sys_user_name}&#34;</span>
</span></span><span style=display:flex><span>sys_password = <span style=color:#ba2121>&#34;{sys_password}&#34;</span>
</span></span></code></pre></td></tr></table></div></div><h4 id=kafka>Kafka</h4><p>If you have deployed a Kafka cluster, HoraeDB can also use it as the WAL storage. Here is example config for it, and you have to replace the templates with real parameters of the Kafka cluster:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Kafka&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal.kafka.client]
</span></span><span style=display:flex><span>boost_brokers = [ <span style=color:#ba2121>&#34;{boost_broker1}&#34;</span>, <span style=color:#ba2121>&#34;{boost_broker2}&#34;</span> ]
</span></span></code></pre></td></tr></table></div></div><h3 id=meta-client-config>Meta Client Config</h3><p>Besides the storage configurations, HoraeDB must be configured to start in <code>WithMeta</code> mode and connect to the deployed HoraeMeta:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[cluster_deployment]
</span></span><span style=display:flex><span>mode = <span style=color:#ba2121>&#34;WithMeta&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[cluster_deployment.meta_client]
</span></span><span style=display:flex><span>cluster_name = <span style=color:#ba2121>&#39;defaultCluster&#39;</span>
</span></span><span style=display:flex><span>meta_addr = <span style=color:#ba2121>&#39;http://{HoraeMetaAddr}:2379&#39;</span>
</span></span><span style=display:flex><span>lease = <span style=color:#ba2121>&#34;10s&#34;</span>
</span></span><span style=display:flex><span>timeout = <span style=color:#ba2121>&#34;5s&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[cluster_deployment.etcd_client]
</span></span><span style=display:flex><span>server_addrs = [<span style=color:#ba2121>&#39;http://{HoraeMetaAddr}:2379&#39;</span>]
</span></span></code></pre></td></tr></table></div></div><h3 id=compaction-offload>Compaction Offload</h3><p>Compaction offload is also supported. To enable compaction offload, the corresponding compaction mode with node picker and endpoint should be configured.</p><ul><li><code>node_picker</code>: There are two types of node picker &ndash; <code>Local</code> and <code>Remote</code>(WIP).<ul><li>When the <code>Local</code> is setted, the local compaction task would be offloaded to the specific remote compaction server, which decided by <code>endpoint</code>.</li></ul></li><li><code>endpoint</code>: The endpoint, in the form <code>addr:port</code>, indicating the <em>grpc port</em> of the remote compaction server.</li></ul><p>Here is an example for it:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[analytic.compaction_mode]
</span></span><span style=display:flex><span>compaction_mode = <span style=color:#ba2121>&#34;Offload&#34;</span>
</span></span><span style=display:flex><span>node_picker = <span style=color:#ba2121>&#34;Local&#34;</span>
</span></span><span style=display:flex><span>endpoint = <span style=color:#ba2121>&#34;{RemoteCompactionServerAddr}:{RemoteCompactionServerGrpcPort}&#34;</span>
</span></span></code></pre></td></tr></table></div></div><p>A Compaction Server, responsible for executing the compaction task, is also needed. Currently <code>horaedb-server</code> will act as this role, in the future we can move it to an independent service.</p><h3 id=complete-config-of-horaedb>Complete Config of HoraeDB</h3><p>With all the parts of the configurations mentioned above, a runnable complete config for HoraeDB can be made. In order to make the HoraeDB cluster runnable, we can decide to adopt RocksDB-based WAL and local-disk-based Object Storage without compaction offload:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">48
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">49
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">50
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">51
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">52
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">53
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">54
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">55
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">56
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">57
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">58
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">59
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">60
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[server]
</span></span><span style=display:flex><span>bind_addr = <span style=color:#ba2121>&#34;0.0.0.0&#34;</span>
</span></span><span style=display:flex><span>http_port = <span style=color:#666>5440</span>
</span></span><span style=display:flex><span>grpc_port = <span style=color:#666>8831</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[logger]
</span></span><span style=display:flex><span>level = <span style=color:#ba2121>&#34;info&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[runtime]
</span></span><span style=display:flex><span>read_thread_num = <span style=color:#666>20</span>
</span></span><span style=display:flex><span>write_thread_num = <span style=color:#666>16</span>
</span></span><span style=display:flex><span>background_thread_num = <span style=color:#666>12</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[cluster_deployment]
</span></span><span style=display:flex><span>mode = <span style=color:#ba2121>&#34;WithMeta&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[cluster_deployment.meta_client]
</span></span><span style=display:flex><span>cluster_name = <span style=color:#ba2121>&#39;defaultCluster&#39;</span>
</span></span><span style=display:flex><span>meta_addr = <span style=color:#ba2121>&#39;http://127.0.0.1:2379&#39;</span>
</span></span><span style=display:flex><span>lease = <span style=color:#ba2121>&#34;10s&#34;</span>
</span></span><span style=display:flex><span>timeout = <span style=color:#ba2121>&#34;5s&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[cluster_deployment.etcd_client]
</span></span><span style=display:flex><span>server_addrs = [<span style=color:#ba2121>&#39;127.0.0.1:2379&#39;</span>]
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic]
</span></span><span style=display:flex><span>write_group_worker_num = <span style=color:#666>16</span>
</span></span><span style=display:flex><span>replay_batch_size = <span style=color:#666>100</span>
</span></span><span style=display:flex><span>max_replay_tables_per_batch = <span style=color:#666>128</span>
</span></span><span style=display:flex><span>write_group_command_channel_cap = <span style=color:#666>1024</span>
</span></span><span style=display:flex><span>sst_background_read_parallelism = <span style=color:#666>8</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.manifest]
</span></span><span style=display:flex><span>scan_batch_size = <span style=color:#666>100</span>
</span></span><span style=display:flex><span>snapshot_every_n_updates = <span style=color:#666>10000</span>
</span></span><span style=display:flex><span>scan_timeout = <span style=color:#ba2121>&#34;5s&#34;</span>
</span></span><span style=display:flex><span>store_timeout = <span style=color:#ba2121>&#34;5s&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.wal]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;RocksDB&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/home/admin/data/horaedb&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.storage]
</span></span><span style=display:flex><span>mem_cache_capacity = <span style=color:#ba2121>&#34;20GB&#34;</span>
</span></span><span style=display:flex><span><span style=color:#408080;font-style:italic># 1&lt;&lt;8=256</span>
</span></span><span style=display:flex><span>mem_cache_partition_bits = <span style=color:#666>8</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.storage.object_store]
</span></span><span style=display:flex><span>type = <span style=color:#ba2121>&#34;Local&#34;</span>
</span></span><span style=display:flex><span>data_dir = <span style=color:#ba2121>&#34;/home/admin/data/horaedb/&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.table_opts]
</span></span><span style=display:flex><span>arena_block_size = <span style=color:#666>2097152</span>
</span></span><span style=display:flex><span>write_buffer_size = <span style=color:#666>33554432</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>[analytic.compaction]
</span></span><span style=display:flex><span>schedule_channel_len = <span style=color:#666>16</span>
</span></span><span style=display:flex><span>schedule_interval = <span style=color:#ba2121>&#34;30m&#34;</span>
</span></span><span style=display:flex><span>max_ongoing_tasks = <span style=color:#666>8</span>
</span></span><span style=display:flex><span>memory_limit = <span style=color:#ba2121>&#34;4G&#34;</span>
</span></span></code></pre></td></tr></table></div></div><p>Let&rsquo;s name this config file as <code>config.toml</code>. And the example configs, in which the templates must be replaced with real parameters before use, for remote storages are also provided:</p><ul><li><a href=../../resources/config_local_oss.toml>RocksDB WAL + OSS</a></li><li><a href=../../resources/config_obkv_oss.toml>OceanBase WAL + OSS</a></li><li><a href=../../resources/config_kafka_oss.toml>Kafka WAL + OSS</a></li></ul><h2 id=run-horaedb-cluster-with-horaemeta>Run HoraeDB cluster with HoraeMeta</h2><p>Firstly, let&rsquo;s start the HoraeMeta:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>docker run -d --name horaemeta-server <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> -p 2379:2379 <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span> ghcr.io/apache/horaemeta-server:nightly-20231225-ab067bf0
</span></span></code></pre></td></tr></table></div></div><p>With the started HoraeMeta cluster, let&rsquo;s start the HoraeDB instance:
TODO: complete it later</p></div><div class=td-content style=page-break-before:always><h1 id=pg-09534b543d63f00c41f30de2514d312b>3 - SDK</h1></div><div class=td-content><h1 id=pg-c736df40c4147174f6f2d1eaeb49bdca>3.1 - Go</h1><h2 id=installation>Installation</h2><pre tabindex=0><code>go get github.com/apache/incubator-horaedb-client-go
</code></pre><p>You can get latest version <a href=https://github.com/apache/incubator-horaedb-client-go/tags>here</a>.</p><h2 id=how-to-use>How To Use</h2><h3 id=init-horaedb-client>Init HoraeDB Client</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span> client, err <span style=color:#666>:=</span> horaedb.<span style=color:#00f>NewClient</span>(endpoint, horaedb.Direct,
</span></span><span style=display:flex><span> horaedb.<span style=color:#00f>WithDefaultDatabase</span>(<span style=color:#ba2121>&#34;public&#34;</span>),
</span></span><span style=display:flex><span> )
</span></span></code></pre></td></tr></table></div></div><table><thead><tr><th>option name</th><th>description</th></tr></thead><tbody><tr><td>defaultDatabase</td><td>using database, database can be overwritten by ReqContext in single <code>Write</code> or <code>SQLRequest</code></td></tr><tr><td>RPCMaxRecvMsgSize</td><td>configration for grpc <code>MaxCallRecvMsgSize</code>, default 1024 _ 1024 _ 1024</td></tr><tr><td>RouteMaxCacheSize</td><td>If the maximum number of router cache size, router client whill evict oldest if exceeded, default is 10000</td></tr></tbody></table><p>Notice:</p><ul><li>HoraeDB currently only supports the default database <code>public</code> now, multiple databases will be supported in the future</li></ul><h3 id=manage-table>Manage Table</h3><p>HoraeDB uses SQL to manage tables, such as creating tables, deleting tables, or adding columns, etc., which is not much different from when you use SQL to manage other databases.</p><p>For ease of use, when using gRPC&rsquo;s write interface for writing, if a table does not exist, HoraeDB will automatically create a table based on the first write.</p><p>Of course, you can also use <code>create table</code> statement to manage the table more finely (such as adding indexes).</p><p><strong>Example for creating table</strong></p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span> createTableSQL <span style=color:#666>:=</span> <span style=color:#ba2121>`
</span></span></span><span style=display:flex><span><span style=color:#ba2121> CREATE TABLE IF NOT EXISTS demo (
</span></span></span><span style=display:flex><span><span style=color:#ba2121> name string TAG,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> value double,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> t timestamp NOT NULL,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> TIMESTAMP KEY(t)
</span></span></span><span style=display:flex><span><span style=color:#ba2121> ) ENGINE=Analytic with (enable_ttl=false)`</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> req <span style=color:#666>:=</span> horaedb.SQLQueryRequest{
</span></span><span style=display:flex><span> Tables: []<span style=color:#b00040>string</span>{<span style=color:#ba2121>&#34;demo&#34;</span>},
</span></span><span style=display:flex><span> SQL: createTableSQL,
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> resp, err <span style=color:#666>:=</span> client.<span style=color:#00f>SQLQuery</span>(context.<span style=color:#00f>Background</span>(), req)
</span></span></code></pre></td></tr></table></div></div><p><strong>Example for droping table</strong></p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span> dropTableSQL <span style=color:#666>:=</span> <span style=color:#ba2121>`DROP TABLE demo`</span>
</span></span><span style=display:flex><span> req <span style=color:#666>:=</span> horaedb.SQLQueryRequest{
</span></span><span style=display:flex><span> Tables: []<span style=color:#b00040>string</span>{<span style=color:#ba2121>&#34;demo&#34;</span>},
</span></span><span style=display:flex><span> SQL: dropTableSQL,
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> resp, err <span style=color:#666>:=</span> client.<span style=color:#00f>SQLQuery</span>(context.<span style=color:#00f>Background</span>(), req)
</span></span></code></pre></td></tr></table></div></div><h3 id=how-to-build-write-data>How To Build Write Data</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span> points <span style=color:#666>:=</span> <span style=color:green>make</span>([]horaedb.Point, <span style=color:#666>0</span>, <span style=color:#666>2</span>)
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>for</span> i <span style=color:#666>:=</span> <span style=color:#666>0</span>; i &lt; <span style=color:#666>2</span>; i<span style=color:#666>++</span> {
</span></span><span style=display:flex><span> point, err <span style=color:#666>:=</span> horaedb.<span style=color:#00f>NewPointBuilder</span>(<span style=color:#ba2121>&#34;demo&#34;</span>).
</span></span><span style=display:flex><span> <span style=color:#00f>SetTimestamp</span>(now).
</span></span><span style=display:flex><span> <span style=color:#00f>AddTag</span>(<span style=color:#ba2121>&#34;name&#34;</span>, horaedb.<span style=color:#00f>NewStringValue</span>(<span style=color:#ba2121>&#34;test_tag1&#34;</span>)).
</span></span><span style=display:flex><span> <span style=color:#00f>AddField</span>(<span style=color:#ba2121>&#34;value&#34;</span>, horaedb.<span style=color:#00f>NewDoubleValue</span>(<span style=color:#666>0.4242</span>)).
</span></span><span style=display:flex><span> <span style=color:#00f>Build</span>()
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>if</span> err <span style=color:#666>!=</span> <span style=color:green;font-weight:700>nil</span> {
</span></span><span style=display:flex><span> <span style=color:green>panic</span>(err)
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> points = <span style=color:green>append</span>(points, point)
</span></span><span style=display:flex><span> }
</span></span></code></pre></td></tr></table></div></div><h3 id=write-example>Write Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span> req <span style=color:#666>:=</span> horaedb.WriteRequest{
</span></span><span style=display:flex><span> Points: points,
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> resp, err <span style=color:#666>:=</span> client.<span style=color:#00f>Write</span>(context.<span style=color:#00f>Background</span>(), req)
</span></span></code></pre></td></tr></table></div></div><h3 id=query-example>Query Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span> querySQL <span style=color:#666>:=</span> <span style=color:#ba2121>`SELECT * FROM demo`</span>
</span></span><span style=display:flex><span> req <span style=color:#666>:=</span> horaedb.SQLQueryRequest{
</span></span><span style=display:flex><span> Tables: []<span style=color:#b00040>string</span>{<span style=color:#ba2121>&#34;demo&#34;</span>},
</span></span><span style=display:flex><span> SQL: querySQL,
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> resp, err <span style=color:#666>:=</span> client.<span style=color:#00f>SQLQuery</span>(context.<span style=color:#00f>Background</span>(), req)
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>if</span> err <span style=color:#666>!=</span> <span style=color:green;font-weight:700>nil</span> {
</span></span><span style=display:flex><span> <span style=color:green>panic</span>(err)
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> fmt.<span style=color:#00f>Printf</span>(<span style=color:#ba2121>&#34;query table success, rows:%+v\n&#34;</span>, resp.Rows)
</span></span></code></pre></td></tr></table></div></div><h2 id=example>Example</h2><p>You can find the complete example <a href=https://github.com/apache/incubator-horaedb-client-go/blob/main/examples/read_write.go>here</a>.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-66074b15694ea31d990c645c25042bca>3.2 - Java</h1><h2 id=introduction>Introduction</h2><p>HoraeDB Client is a high-performance Java client for HoraeDB.</p><h2 id=requirements>Requirements</h2><ul><li>Java 8 or later is required for compilation</li></ul><h2 id=dependency>Dependency</h2><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=display:flex><span><span style=color:green;font-weight:700>&lt;dependency&gt;</span>
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&lt;groupId&gt;</span>io.ceresdb<span style=color:green;font-weight:700>&lt;/groupId&gt;</span>
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&lt;artifactId&gt;</span>ceresdb-all<span style=color:green;font-weight:700>&lt;/artifactId&gt;</span>
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&lt;version&gt;</span>${CERESDB.VERSION}<span style=color:green;font-weight:700>&lt;/version&gt;</span>
</span></span><span style=display:flex><span><span style=color:green;font-weight:700>&lt;/dependency&gt;</span>
</span></span></code></pre></td></tr></table></div></div><p>You can get latest version <a href=https://github.com/apache/incubator-horaedb-client-java/blob/main/docs/CHANGELOG.md>here</a>.</p><h2 id=init-horaedb-client>Init HoraeDB Client</h2><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>CeresDBOptions<span style=color:#bbb> </span>opts<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>CeresDBOptions.<span style=color:#7d9029>newBuilder</span>(<span style=color:#ba2121>&#34;127.0.0.1&#34;</span>,<span style=color:#bbb> </span>8831,<span style=color:#bbb> </span>DIRECT)<span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// CeresDB default grpc port 8831,use DIRECT RouteMode</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>database</span>(<span style=color:#ba2121>&#34;public&#34;</span>)<span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// use database for client, can be overridden by the RequestContext in request</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// maximum retry times when write fails</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// (only some error codes will be retried, such as the routing table failure)</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>writeMaxRetries</span>(1)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// maximum retry times when read fails</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// (only some error codes will be retried, such as the routing table failure)</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>readMaxRetries</span>(1).<span style=color:#7d9029>build</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>CeresDBClient<span style=color:#bbb> </span>client<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>new</span><span style=color:#bbb> </span>CeresDBClient();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>if</span><span style=color:#bbb> </span>(<span style=color:#666>!</span>client.<span style=color:#7d9029>init</span>(opts))<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>throw</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>new</span><span style=color:#bbb> </span>IllegalStateException(<span style=color:#ba2121>&#34;Fail to start CeresDBClient&#34;</span>);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>}<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>The initialization requires at least three parameters:</p><ul><li><code>Endpoint</code>: 127.0.0.1</li><li><code>Port</code>: 8831</li><li><code>RouteMode</code>: DIRECT/PROXY</li></ul><p>Here is the explanation of <code>RouteMode</code>. There are two kinds of <code>RouteMode</code>,The <code>Direct</code> mode should be adopted to avoid forwarding overhead if all the servers are accessible to the client.
However, the <code>Proxy</code> mode is the only choice if the access to the servers from the client must go through a gateway.
For more configuration options, see <a href=https://github.com/apache/incubator-horaedb-client-java/tree/main/docs/configuration.md>configuration</a></p><p>Notice: HoraeDB currently only supports the default database <code>public</code> now, multiple databases will be supported in the future;</p><h2 id=create-table-example>Create Table Example</h2><p>For ease of use, when using gRPC&rsquo;s write interface for writing, if a table does not exist, HoraeDB will automatically create a table based on the first write.</p><p>Of course, you can also use <code>create table</code> statement to manage the table more finely (such as adding indexes).</p><p>The following table creation statement(using the SQL API included in SDK )shows all field types supported by HoraeDB:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#408080;font-style:italic>// Create table manually, creating table schema ahead of data ingestion is not required</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>String<span style=color:#bbb> </span>createTableSql<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;CREATE TABLE IF NOT EXISTS machine_table(&#34;</span><span style=color:#bbb> </span><span style=color:#666>+</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;ts TIMESTAMP NOT NULL,&#34;</span><span style=color:#bbb> </span><span style=color:#666>+</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;city STRING TAG NOT NULL,&#34;</span><span style=color:#bbb> </span><span style=color:#666>+</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;ip STRING TAG NOT NULL,&#34;</span><span style=color:#bbb> </span><span style=color:#666>+</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;cpu DOUBLE NULL,&#34;</span><span style=color:#bbb> </span><span style=color:#666>+</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;mem DOUBLE NULL,&#34;</span><span style=color:#bbb> </span><span style=color:#666>+</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;TIMESTAMP KEY(ts)&#34;</span><span style=color:#bbb> </span><span style=color:#666>+</span><span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// timestamp column must be specified</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;) ENGINE=Analytic&#34;</span>;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Result<span style=color:#666>&lt;</span>SqlQueryOk,<span style=color:#bbb> </span>Err<span style=color:#666>&gt;</span><span style=color:#bbb> </span>createResult<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client.<span style=color:#7d9029>sqlQuery</span>(<span style=color:green;font-weight:700>new</span><span style=color:#bbb> </span>SqlQueryRequest(createTableSql)).<span style=color:#7d9029>get</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>if</span><span style=color:#bbb> </span>(<span style=color:#666>!</span>createResult.<span style=color:#7d9029>isOk</span>())<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>throw</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>new</span><span style=color:#bbb> </span>IllegalStateException(<span style=color:#ba2121>&#34;Fail to create table&#34;</span>);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>}<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=drop-table-example>Drop Table Example</h2><p>Here is an example of dropping table:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span>String<span style=color:#bbb> </span>dropTableSql<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;DROP TABLE machine_table&#34;</span>;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Result<span style=color:#666>&lt;</span>SqlQueryOk,<span style=color:#bbb> </span>Err<span style=color:#666>&gt;</span><span style=color:#bbb> </span>dropResult<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client.<span style=color:#7d9029>sqlQuery</span>(<span style=color:green;font-weight:700>new</span><span style=color:#bbb> </span>SqlQueryRequest(dropTableSql)).<span style=color:#7d9029>get</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>if</span><span style=color:#bbb> </span>(<span style=color:#666>!</span>dropResult.<span style=color:#7d9029>isOk</span>())<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>throw</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>new</span><span style=color:#bbb> </span>IllegalStateException(<span style=color:#ba2121>&#34;Fail to drop table&#34;</span>);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>}<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=write-data-example>Write Data Example</h2><p>Firstly, you can use <code>PointBuilder</code> to build HoraeDB points:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span>List<span style=color:#666>&lt;</span>Point<span style=color:#666>&gt;</span><span style=color:#bbb> </span>pointList<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>new</span><span style=color:#bbb> </span>LinkedList<span style=color:#666>&lt;&gt;</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>for</span><span style=color:#bbb> </span>(<span style=color:#b00040>int</span><span style=color:#bbb> </span>i<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>0;<span style=color:#bbb> </span>i<span style=color:#bbb> </span><span style=color:#666>&lt;</span><span style=color:#bbb> </span>100;<span style=color:#bbb> </span>i<span style=color:#666>++</span>)<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// build one point</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>Point<span style=color:#bbb> </span>point<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>Point.<span style=color:#7d9029>newPointBuilder</span>(<span style=color:#ba2121>&#34;machine_table&#34;</span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>setTimestamp</span>(t0)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>addTag</span>(<span style=color:#ba2121>&#34;city&#34;</span>,<span style=color:#bbb> </span><span style=color:#ba2121>&#34;Singapore&#34;</span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>addTag</span>(<span style=color:#ba2121>&#34;ip&#34;</span>,<span style=color:#bbb> </span><span style=color:#ba2121>&#34;10.0.0.1&#34;</span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>addField</span>(<span style=color:#ba2121>&#34;cpu&#34;</span>,<span style=color:#bbb> </span>Value.<span style=color:#7d9029>withDouble</span>(0.<span style=color:#7d9029>23</span>))<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>addField</span>(<span style=color:#ba2121>&#34;mem&#34;</span>,<span style=color:#bbb> </span>Value.<span style=color:#7d9029>withDouble</span>(0.<span style=color:#7d9029>55</span>))<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>build</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>points.<span style=color:#7d9029>add</span>(point);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>}<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>Then, you can use <code>write</code> interface to write data:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">8
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>CompletableFuture<span style=color:#666>&lt;</span>Result<span style=color:#666>&lt;</span>WriteOk,<span style=color:#bbb> </span>Err<span style=color:#666>&gt;&gt;</span><span style=color:#bbb> </span>wf<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client.<span style=color:#7d9029>write</span>(<span style=color:green;font-weight:700>new</span><span style=color:#bbb> </span>WriteRequest(pointList));<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>Result<span style=color:#666>&lt;</span>WriteOk,<span style=color:#bbb> </span>Err<span style=color:#666>&gt;</span><span style=color:#bbb> </span>writeResult<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>wf.<span style=color:#7d9029>get</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>Assert.<span style=color:#7d9029>assertTrue</span>(writeResult.<span style=color:#7d9029>isOk</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// `Result` class referenced the Rust language practice, provides rich functions (such as mapXXX, andThen) transforming the result value to improve programming efficiency. You can refer to the API docs for detail usage.</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>Assert.<span style=color:#7d9029>assertEquals</span>(3,<span style=color:#bbb> </span>writeResult.<span style=color:#7d9029>getOk</span>().<span style=color:#7d9029>getSuccess</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>Assert.<span style=color:#7d9029>assertEquals</span>(3,<span style=color:#bbb> </span>writeResult.<span style=color:#7d9029>mapOr</span>(0,<span style=color:#bbb> </span>WriteOk::getSuccess).<span style=color:#7d9029>intValue</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>Assert.<span style=color:#7d9029>assertEquals</span>(0,<span style=color:#bbb> </span>writeResult.<span style=color:#7d9029>mapOr</span>(<span style=color:#666>-</span>1,<span style=color:#bbb> </span>WriteOk::getFailed).<span style=color:#7d9029>intValue</span>());<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>See <a href=https://github.com/apache/incubator-horaedb-client-java/tree/main/docs/write.md>write</a></p><h2 id=query-data-example>Query Data Example</h2><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">24
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>SqlQueryRequest<span style=color:#bbb> </span>queryRequest<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>SqlQueryRequest.<span style=color:#7d9029>newBuilder</span>()<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>forTables</span>(<span style=color:#ba2121>&#34;machine_table&#34;</span>)<span style=color:#bbb> </span><span style=color:#408080;font-style:italic>// table name is optional. If not provided, SQL parser will parse the `ssql` to get the table name and do the routing automaticly</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>sql</span>(<span style=color:#ba2121>&#34;select * from machine_table where ts = %d&#34;</span>,<span style=color:#bbb> </span>t0)<span style=color:#bbb> </span><span style=color:#408080;font-style:italic>//</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>build</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>CompletableFuture<span style=color:#666>&lt;</span>Result<span style=color:#666>&lt;</span>SqlQueryOk,<span style=color:#bbb> </span>Err<span style=color:#666>&gt;&gt;</span><span style=color:#bbb> </span>qf<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client.<span style=color:#7d9029>sqlQuery</span>(queryRequest);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>Result<span style=color:#666>&lt;</span>SqlQueryOk,<span style=color:#bbb> </span>Err<span style=color:#666>&gt;</span><span style=color:#bbb> </span>queryResult<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>qf.<span style=color:#7d9029>get</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertTrue</span>(queryResult.<span style=color:#7d9029>isOk</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>SqlQueryOk<span style=color:#bbb> </span>queryOk<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>queryResult.<span style=color:#7d9029>getOk</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertEquals</span>(1,<span style=color:#bbb> </span>queryOk.<span style=color:#7d9029>getRowCount</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>// get rows as list</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>List<span style=color:#666>&lt;</span>Row<span style=color:#666>&gt;</span><span style=color:#bbb> </span>rows<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>queryOk.<span style=color:#7d9029>getRowList</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertEquals</span>(t0,<span style=color:#bbb> </span>rows.<span style=color:#7d9029>get</span>(0).<span style=color:#7d9029>getColumn</span>(<span style=color:#ba2121>&#34;ts&#34;</span>).<span style=color:#7d9029>getValue</span>().<span style=color:#7d9029>getTimestamp</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertEquals</span>(<span style=color:#ba2121>&#34;Singapore&#34;</span>,<span style=color:#bbb> </span>rows.<span style=color:#7d9029>get</span>(0).<span style=color:#7d9029>getColumn</span>(<span style=color:#ba2121>&#34;city&#34;</span>).<span style=color:#7d9029>getValue</span>().<span style=color:#7d9029>getString</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertEquals</span>(<span style=color:#ba2121>&#34;10.0.0.1&#34;</span>,<span style=color:#bbb> </span>rows.<span style=color:#7d9029>get</span>(0).<span style=color:#7d9029>getColumn</span>(<span style=color:#ba2121>&#34;ip&#34;</span>).<span style=color:#7d9029>getValue</span>().<span style=color:#7d9029>getString</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertEquals</span>(0.<span style=color:#7d9029>23</span>,<span style=color:#bbb> </span>rows.<span style=color:#7d9029>get</span>(0).<span style=color:#7d9029>getColumn</span>(<span style=color:#ba2121>&#34;cpu&#34;</span>).<span style=color:#7d9029>getValue</span>().<span style=color:#7d9029>getDouble</span>(),<span style=color:#bbb> </span>0.<span style=color:#7d9029>0000001</span>);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertEquals</span>(0.<span style=color:#7d9029>55</span>,<span style=color:#bbb> </span>rows.<span style=color:#7d9029>get</span>(0).<span style=color:#7d9029>getColumn</span>(<span style=color:#ba2121>&#34;mem&#34;</span>).<span style=color:#7d9029>getValue</span>().<span style=color:#7d9029>getDouble</span>(),<span style=color:#bbb> </span>0.<span style=color:#7d9029>0000001</span>);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#408080;font-style:italic>// get rows as stream</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>Stream<span style=color:#666>&lt;</span>Row<span style=color:#666>&gt;</span><span style=color:#bbb> </span>rowStream<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>queryOk.<span style=color:#7d9029>stream</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>rowStream.<span style=color:#7d9029>forEach</span>(row<span style=color:#bbb> </span><span style=color:#666>-&gt;</span><span style=color:#bbb> </span>System.<span style=color:#7d9029>out</span>.<span style=color:#7d9029>println</span>(row.<span style=color:#7d9029>toString</span>()));<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>See <a href=https://github.com/apache/incubator-horaedb-client-java/tree/main/docs/read.md>read</a></p><h2 id=stream-writeread-example>Stream Write/Read Example</h2><p>HoraeDB support streaming writing and reading,suitable for large-scale data reading and writing。</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">22
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#b00040>long</span><span style=color:#bbb> </span>start<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>System.<span style=color:#7d9029>currentTimeMillis</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:#b00040>long</span><span style=color:#bbb> </span>t<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>start;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>StreamWriteBuf<span style=color:#666>&lt;</span>Point,<span style=color:#bbb> </span>WriteOk<span style=color:#666>&gt;</span><span style=color:#bbb> </span>writeBuf<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client.<span style=color:#7d9029>streamWrite</span>(<span style=color:#ba2121>&#34;machine_table&#34;</span>);<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>for</span><span style=color:#bbb> </span>(<span style=color:#b00040>int</span><span style=color:#bbb> </span>i<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>0;<span style=color:#bbb> </span>i<span style=color:#bbb> </span><span style=color:#666>&lt;</span><span style=color:#bbb> </span>1000;<span style=color:#bbb> </span>i<span style=color:#666>++</span>)<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>Point<span style=color:#bbb> </span>streamData<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>Point.<span style=color:#7d9029>newPointBuilder</span>(<span style=color:#ba2121>&#34;machine_table&#34;</span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>setTimestamp</span>(t)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>addTag</span>(<span style=color:#ba2121>&#34;city&#34;</span>,<span style=color:#bbb> </span><span style=color:#ba2121>&#34;Beijing&#34;</span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>addTag</span>(<span style=color:#ba2121>&#34;ip&#34;</span>,<span style=color:#bbb> </span><span style=color:#ba2121>&#34;10.0.0.3&#34;</span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>addField</span>(<span style=color:#ba2121>&#34;cpu&#34;</span>,<span style=color:#bbb> </span>Value.<span style=color:#7d9029>withDouble</span>(0.<span style=color:#7d9029>42</span>))<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>addField</span>(<span style=color:#ba2121>&#34;mem&#34;</span>,<span style=color:#bbb> </span>Value.<span style=color:#7d9029>withDouble</span>(0.<span style=color:#7d9029>67</span>))<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>build</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>writeBuf.<span style=color:#7d9029>writeAndFlush</span>(Collections.<span style=color:#7d9029>singletonList</span>(streamData));<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>t<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>t<span style=color:#666>+</span>1;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>}<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>CompletableFuture<span style=color:#666>&lt;</span>WriteOk<span style=color:#666>&gt;</span><span style=color:#bbb> </span>writeOk<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>writeBuf.<span style=color:#7d9029>completed</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertEquals</span>(1000,<span style=color:#bbb> </span>writeOk.<span style=color:#7d9029>join</span>().<span style=color:#7d9029>getSuccess</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>SqlQueryRequest<span style=color:#bbb> </span>streamQuerySql<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>SqlQueryRequest.<span style=color:#7d9029>newBuilder</span>()<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:#7d9029>sql</span>(<span style=color:#ba2121>&#34;select * from %s where city = &#39;%s&#39; and ts &gt;= %d and ts &lt; %d&#34;</span>,<span style=color:#bbb> </span><span style=color:#ba2121>&#34;machine_table&#34;</span>,<span style=color:#bbb> </span><span style=color:#ba2121>&#34;Beijing&#34;</span>,<span style=color:#bbb> </span>start,<span style=color:#bbb> </span>t).<span style=color:#7d9029>build</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>final</span><span style=color:#bbb> </span>Result<span style=color:#666>&lt;</span>SqlQueryOk,<span style=color:#bbb> </span>Err<span style=color:#666>&gt;</span><span style=color:#bbb> </span>streamQueryResult<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client.<span style=color:#7d9029>sqlQuery</span>(streamQuerySql).<span style=color:#7d9029>get</span>();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertTrue</span>(streamQueryResult.<span style=color:#7d9029>isOk</span>());<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>Assert.<span style=color:#7d9029>assertEquals</span>(1000,<span style=color:#bbb> </span>streamQueryResult.<span style=color:#7d9029>getOk</span>().<span style=color:#7d9029>getRowCount</span>());<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>See <a href=https://github.com/apache/incubator-horaedb-client-java/tree/main/docs/streaming.md>streaming</a></p></div><div class=td-content style=page-break-before:always><h1 id=pg-d8c6cac92b3914596fc657a1fa438885>3.3 - Python</h1><p><a href=https://pypi.org/project/horaedb-client><figure><img src=https://img.shields.io/pypi/v/horaedb-client.svg alt loading=lazy></figure></a><a href=https://github.com/apache/horaedb-client-py><figure><img src=https://img.shields.io/github/stars/apache/horaedb-client-py alt loading=lazy></figure></a></p><h2 id=introduction>Introduction</h2><p><a href=https://pypi.org/project/horaedb-client/>horaedb-client</a> is the python client for <a href=https://github.com/apache/horaedb>HoraeDB</a>.</p><p>Thanks to <a href=https://github.com/PyO3>PyO3</a>, the python client is actually a wrapper on the <a href=https://github.com/apache/horaedb-client-rs>rust client</a>.</p><p>The guide will give a basic introduction to the python client by <a href=https://github.com/apache/horaedb-client-py/blob/main/examples/read_write.py>example</a>.</p><h2 id=requirements>Requirements</h2><ul><li>Python >= 3.7</li></ul><h2 id=installation>Installation</h2><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>pip install horaedb-client
</span></span></code></pre></td></tr></table></div></div><p>You can get latest version <a href=https://github.com/apache/horaedb-client-py/tags>here</a>.</p><h2 id=init-horaedb-client>Init HoraeDB Client</h2><p>The client initialization comes first, here is a code snippet:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:green;font-weight:700>import</span> <span style=color:#00f;font-weight:700>asyncio</span>
</span></span><span style=display:flex><span><span style=color:green;font-weight:700>import</span> <span style=color:#00f;font-weight:700>datetime</span>
</span></span><span style=display:flex><span><span style=color:green;font-weight:700>from</span> <span style=color:#00f;font-weight:700>ceresdb_client</span> <span style=color:green;font-weight:700>import</span> Builder, RpcContext, PointBuilder, ValueBuilder, WriteRequest, SqlQueryRequest, Mode, RpcConfig
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>rpc_config <span style=color:#666>=</span> RpcConfig()
</span></span><span style=display:flex><span>rpc_config <span style=color:#666>=</span> RpcConfig()
</span></span><span style=display:flex><span>rpc_config<span style=color:#666>.</span>thread_num <span style=color:#666>=</span> <span style=color:#666>1</span>
</span></span><span style=display:flex><span>rpc_config<span style=color:#666>.</span>default_write_timeout_ms <span style=color:#666>=</span> <span style=color:#666>1000</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>builder <span style=color:#666>=</span> Builder(<span style=color:#ba2121>&#39;127.0.0.1:8831&#39;</span>, Mode<span style=color:#666>.</span>Direct)
</span></span><span style=display:flex><span>builder<span style=color:#666>.</span>set_rpc_config(rpc_config)
</span></span><span style=display:flex><span>builder<span style=color:#666>.</span>set_default_database(<span style=color:#ba2121>&#39;public&#39;</span>)
</span></span><span style=display:flex><span>client <span style=color:#666>=</span> builder<span style=color:#666>.</span>build()
</span></span></code></pre></td></tr></table></div></div><p>Firstly, it&rsquo;s worth noting that the imported packages are used across all the code snippets in this guide, and they will not be repeated in the following.</p><p>The initialization requires at least two parameters:</p><ul><li><code>Endpoint</code>: the server endpoint consisting of ip address and serving port, e.g. <code>127.0.0.1:8831</code>;</li><li><code>Mode</code>: The mode of the communication between client and server, and there are two kinds of <code>Mode</code>: <code>Direct</code> and <code>Proxy</code>.</li></ul><p><code>Endpoint</code> is simple, while <code>Mode</code> deserves more explanation. The <code>Direct</code> mode should be adopted to avoid forwarding overhead if all the servers are accessible to the client. However, the <code>Proxy</code> mode is the only choice if the access to the servers from the client must go through a gateway.</p><p>The <code>default_database</code> can be set and will be used if following rpc calling without setting the database in the <code>RpcContext</code>.</p><p>By configuring the <code>RpcConfig</code>, resource and performance of the client can be manipulated, and all of the configurations can be referred at <a href=https://github.com/apache/incubator-horaedb-client-py/blob/main/ceresdb_client.pyi>here</a>.</p><h2 id=create-table>Create Table</h2><p>For ease of use, when using gRPC&rsquo;s write interface for writing, if a table does not exist, HoraeDB will automatically create a table based on the first write.</p><p>Of course, you can also use <code>create table</code> statement to manage the table more finely (such as adding indexes).</p><p>Here is a example for creating table by the initialized client:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:green;font-weight:700>async</span> <span style=color:green;font-weight:700>def</span> <span style=color:#00f>async_query</span>(client, ctx, req):
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>await</span> client<span style=color:#666>.</span>sql_query(ctx, req)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>create_table_sql <span style=color:#666>=</span> <span style=color:#ba2121>&#39;CREATE TABLE IF NOT EXISTS demo ( </span><span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span><span style=color:#ba2121> name string TAG, </span><span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span><span style=color:#ba2121> value double, </span><span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span><span style=color:#ba2121> t timestamp NOT NULL, </span><span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span><span style=color:#ba2121> TIMESTAMP KEY(t)) ENGINE=Analytic with (enable_ttl=false)&#39;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>req <span style=color:#666>=</span> SqlQueryRequest([<span style=color:#ba2121>&#39;demo&#39;</span>], create_table_sql)
</span></span><span style=display:flex><span>rpc_ctx <span style=color:#666>=</span> RpcContext()
</span></span><span style=display:flex><span>rpc_ctx<span style=color:#666>.</span>database <span style=color:#666>=</span> <span style=color:#ba2121>&#39;public&#39;</span>
</span></span><span style=display:flex><span>rpc_ctx<span style=color:#666>.</span>timeout_ms <span style=color:#666>=</span> <span style=color:#666>100</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>event_loop <span style=color:#666>=</span> asyncio<span style=color:#666>.</span>get_event_loop()
</span></span><span style=display:flex><span>event_loop<span style=color:#666>.</span>run_until_complete(async_query(client, rpc_ctx, req))
</span></span></code></pre></td></tr></table></div></div><p><code>RpcContext</code> can be used to overwrite the default database and timeout defined in the initialization of the client.</p><h2 id=write-data>Write Data</h2><p><code>PointBuilder</code> can be used to construct a point, which is actually a row in data set. The write request consists of multiple points.</p><p>The example is simple:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:green;font-weight:700>async</span> <span style=color:green;font-weight:700>def</span> <span style=color:#00f>async_write</span>(client, ctx, req):
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>return</span> <span style=color:green;font-weight:700>await</span> client<span style=color:#666>.</span>write(ctx, req)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>point_builder <span style=color:#666>=</span> PointBuilder(<span style=color:#ba2121>&#39;demo&#39;</span>)
</span></span><span style=display:flex><span>point_builder<span style=color:#666>.</span>set_timestamp(<span style=color:#666>1000</span> <span style=color:#666>*</span> <span style=color:green>int</span>(<span style=color:green>round</span>(datetime<span style=color:#666>.</span>datetime<span style=color:#666>.</span>now()<span style=color:#666>.</span>timestamp())))
</span></span><span style=display:flex><span>point_builder<span style=color:#666>.</span>set_tag(<span style=color:#ba2121>&#34;name&#34;</span>, ValueBuilder()<span style=color:#666>.</span>string(<span style=color:#ba2121>&#34;test_tag1&#34;</span>))
</span></span><span style=display:flex><span>point_builder<span style=color:#666>.</span>set_field(<span style=color:#ba2121>&#34;value&#34;</span>, ValueBuilder()<span style=color:#666>.</span>double(<span style=color:#666>0.4242</span>))
</span></span><span style=display:flex><span>point <span style=color:#666>=</span> point_builder<span style=color:#666>.</span>build()
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>write_request <span style=color:#666>=</span> WriteRequest()
</span></span><span style=display:flex><span>write_request<span style=color:#666>.</span>add_point(point)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>event_loop <span style=color:#666>=</span> asyncio<span style=color:#666>.</span>get_event_loop()
</span></span><span style=display:flex><span>event_loop<span style=color:#666>.</span>run_until_complete(async_write(client, ctx, req))
</span></span></code></pre></td></tr></table></div></div><h2 id=query-data>Query Data</h2><p>By <code>sql_query</code> interface, it is easy to retrieve the data from the server:</p><pre tabindex=0><code>req = SqlQueryRequest([&#39;demo&#39;], &#39;select * from demo&#39;)
event_loop = asyncio.get_event_loop()
resp = event_loop.run_until_complete(async_query(client, ctx, req))
</code></pre><p>As the example shows, two parameters are needed to construct the <code>SqlQueryRequest</code>:</p><ul><li>The tables involved by this sql query;</li><li>The query sql.</li></ul><p>Currently, the first parameter is necessary for performance on routing.</p><p>With retrieved data, we can process it row by row and column by column:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#408080;font-style:italic># Access row by index in the resp.</span>
</span></span><span style=display:flex><span><span style=color:green;font-weight:700>for</span> row_idx <span style=color:#a2f;font-weight:700>in</span> <span style=color:green>range</span>(<span style=color:#666>0</span>, resp<span style=color:#666>.</span>num_rows()):
</span></span><span style=display:flex><span> row_tokens <span style=color:#666>=</span> []
</span></span><span style=display:flex><span> row <span style=color:#666>=</span> resp<span style=color:#666>.</span>row_by_idx(row_idx)
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>for</span> col_idx <span style=color:#a2f;font-weight:700>in</span> <span style=color:green>range</span>(<span style=color:#666>0</span>, row<span style=color:#666>.</span>num_cols()):
</span></span><span style=display:flex><span> col <span style=color:#666>=</span> row<span style=color:#666>.</span>column_by_idx(col_idx)
</span></span><span style=display:flex><span> row_tokens<span style=color:#666>.</span>append(<span style=color:#ba2121>f</span><span style=color:#ba2121>&#34;</span><span style=color:#b68;font-weight:700>{</span>col<span style=color:#666>.</span>name()<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>:</span><span style=color:#b68;font-weight:700>{</span>col<span style=color:#666>.</span>value()<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>#</span><span style=color:#b68;font-weight:700>{</span>col<span style=color:#666>.</span>data_type()<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>&#34;</span>)
</span></span><span style=display:flex><span> <span style=color:green>print</span>(<span style=color:#ba2121>f</span><span style=color:#ba2121>&#34;row#</span><span style=color:#b68;font-weight:700>{</span>row_idx<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>: </span><span style=color:#b68;font-weight:700>{</span><span style=color:#ba2121>&#39;,&#39;</span><span style=color:#666>.</span>join(row_tokens)<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>&#34;</span>)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#408080;font-style:italic># Access row by iter in the resp.</span>
</span></span><span style=display:flex><span><span style=color:green;font-weight:700>for</span> row <span style=color:#a2f;font-weight:700>in</span> resp<span style=color:#666>.</span>iter_rows():
</span></span><span style=display:flex><span> row_tokens <span style=color:#666>=</span> []
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>for</span> col <span style=color:#a2f;font-weight:700>in</span> row<span style=color:#666>.</span>iter_columns():
</span></span><span style=display:flex><span> row_tokens<span style=color:#666>.</span>append(<span style=color:#ba2121>f</span><span style=color:#ba2121>&#34;</span><span style=color:#b68;font-weight:700>{</span>col<span style=color:#666>.</span>name()<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>:</span><span style=color:#b68;font-weight:700>{</span>col<span style=color:#666>.</span>value()<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>#</span><span style=color:#b68;font-weight:700>{</span>col<span style=color:#666>.</span>data_type()<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>&#34;</span>)
</span></span><span style=display:flex><span> <span style=color:green>print</span>(<span style=color:#ba2121>f</span><span style=color:#ba2121>&#34;row: </span><span style=color:#b68;font-weight:700>{</span><span style=color:#ba2121>&#39;,&#39;</span><span style=color:#666>.</span>join(row_tokens)<span style=color:#b68;font-weight:700>}</span><span style=color:#ba2121>&#34;</span>)
</span></span></code></pre></td></tr></table></div></div><h2 id=drop-table>Drop Table</h2><p>Finally, we can drop the table by the sql api, which is similar to the table creation:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>drop_table_sql <span style=color:#666>=</span> <span style=color:#ba2121>&#39;DROP TABLE demo&#39;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>req <span style=color:#666>=</span> SqlQueryRequest([<span style=color:#ba2121>&#39;demo&#39;</span>], drop_table_sql)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>event_loop <span style=color:#666>=</span> asyncio<span style=color:#666>.</span>get_event_loop()
</span></span><span style=display:flex><span>event_loop<span style=color:#666>.</span>run_until_complete(async_query(client, rpc_ctx, req))
</span></span></code></pre></td></tr></table></div></div></div><div class=td-content style=page-break-before:always><h1 id=pg-8b17bc3ecdfd6226bf296cc8d8c38345>3.4 - Rust</h1><p><a href=https://crates.io/crates/horaedb-client><figure><img src=https://img.shields.io/crates/v/horaedb-client.svg alt loading=lazy></figure></a><a href=https://github.com/apache/horaedb-client-rs><figure><img src=https://img.shields.io/github/stars/apache/horaedb-client-rs alt loading=lazy></figure></a></p><h2 id=install>Install</h2><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>cargo add horaedb-client
</span></span></code></pre></td></tr></table></div></div><p>You can get latest version <a href=https://github.com/apache/horaedb-client-rs/tags>here</a>.</p><h2 id=init-client>Init Client</h2><p>At first, we need to init the client.</p><ul><li>New builder for the client, and you must set <code>endpoint</code> and <code>mode</code>:<ul><li><code>endpoint</code> is a string which is usually like &ldquo;ip/domain_name:port&rdquo;.</li><li><code>mode</code> is used to define the way to access horaedb server, <a href=https://github.com/apache/horaedb-client-rs/blob/main/src/db_client/builder.rs#L20>detail about mode</a>.</li></ul></li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>mut</span><span style=color:#bbb> </span>builder<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>Builder::new(<span style=color:#ba2121>&#34;ip/domain_name:port&#34;</span>,<span style=color:#bbb> </span>Mode::Direct<span style=color:#666>/</span>Mode::Proxy);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><ul><li>New and set <code>rpc_config</code>, it can be defined on demand or just use the default value, <a href=https://github.com/apache/horaedb-client-rs/blob/main/src/options.rs>detail about rpc config</a>:</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>rpc_config<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>RpcConfig<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>thread_num: <span style=color:green>Some</span>(<span style=color:#666>1</span>),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>default_write_timeout: <span style=color:#00f;font-weight:700>Duration</span>::from_millis(<span style=color:#666>1000</span>),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>..</span><span style=color:green>Default</span>::default()<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>};<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>builder<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>builder.rpc_config(rpc_config);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><ul><li>Set <code>default_database</code>, it will be used if following rpc calling without setting the database in the <code>RpcContext</code>(will be introduced in later):</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>builder<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>builder.default_database(<span style=color:#ba2121>&#34;public&#34;</span>);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><ul><li>Finally, we build client from builder:</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>client<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>builder.build();<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=manage-table>Manage Table</h2><p>For ease of use, when using gRPC&rsquo;s write interface for writing, if a table does not exist, HoraeDB will automatically create a table based on the first write.</p><p>Of course, you can also use <code>create table</code> statement to manage the table more finely (such as adding indexes).</p><p>You can use the sql query interface to create or drop table, related setting will be introduced in <code>sql query</code> section.</p><ul><li>Create table:</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>create_table_sql<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:#ba2121>r</span><span style=color:#ba2121>#&#34;CREATE TABLE IF NOT EXISTS horaedb (
</span></span></span><span style=display:flex><span><span style=color:#ba2121> str_tag string TAG,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> int_tag int32 TAG,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> var_tag varbinary TAG,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> str_field string,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> int_field int32,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> bin_field varbinary,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> t timestamp NOT NULL,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> TIMESTAMP KEY(t)) ENGINE=Analytic with
</span></span></span><span style=display:flex><span><span style=color:#ba2121> (enable_ttl=&#39;false&#39;)&#34;#</span>;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>req<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>SqlQueryRequest<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>tables: <span style=color:#00f;font-weight:700>vec</span><span style=color:#666>!</span>[<span style=color:#ba2121>&#34;horaedb&#34;</span>.to_string()],<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>sql: <span style=color:#00f;font-weight:700>create_table_sql</span>.to_string(),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>};<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>resp<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.sql_query(rpc_ctx,<span style=color:#bbb> </span><span style=color:#666>&amp;</span>req)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:green;font-weight:700>await</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.expect(<span style=color:#ba2121>&#34;Should succeed to create table&#34;</span>);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><ul><li>Drop table:</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>drop_table_sql<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;DROP TABLE horaedb&#34;</span>;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>req<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>SqlQueryRequest<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>tables: <span style=color:#00f;font-weight:700>vec</span><span style=color:#666>!</span>[<span style=color:#ba2121>&#34;horaedb&#34;</span>.to_string()],<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>sql: <span style=color:#00f;font-weight:700>drop_table_sql</span>.to_string(),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>};<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>resp<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.sql_query(rpc_ctx,<span style=color:#bbb> </span><span style=color:#666>&amp;</span>req)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.<span style=color:green;font-weight:700>await</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.expect(<span style=color:#ba2121>&#34;Should succeed to create table&#34;</span>);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=write>Write</h2><p>We support to write with the time series data model like <a href=https://awesome.influxdata.com/docs/part-2/influxdb-data-model/>InfluxDB</a>.</p><ul><li>Build the <code>point</code> first by <code>PointBuilder</code>, the related data structure of <code>tag value</code> and <code>field value</code> in it is defined as <code>Value</code>, <a href=https://github.com/apache/horaedb-client-rs/blob/main/src/model/value.rs>detail about Value</a>:</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">21
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>test_table<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;horaedb&#34;</span>;<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>ts<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>Local::now().timestamp_millis();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>point<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>PointBuilder::new(test_table.to_string())<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.timestamp(ts)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.tag(<span style=color:#ba2121>&#34;str_tag&#34;</span>.to_string(),<span style=color:#bbb> </span>Value::<span style=color:green>String</span>(<span style=color:#ba2121>&#34;tag_val&#34;</span>.to_string()))<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.tag(<span style=color:#ba2121>&#34;int_tag&#34;</span>.to_string(),<span style=color:#bbb> </span>Value::Int32(<span style=color:#666>42</span>))<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.tag(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;var_tag&#34;</span>.to_string(),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>Value::Varbinary(<span style=color:#ba2121>b</span><span style=color:#ba2121>&#34;tag_bin_val&#34;</span>.to_vec()),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.field(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;str_field&#34;</span>.to_string(),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>Value::<span style=color:green>String</span>(<span style=color:#ba2121>&#34;field_val&#34;</span>.to_string()),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.field(<span style=color:#ba2121>&#34;int_field&#34;</span>.to_string(),<span style=color:#bbb> </span>Value::Int32(<span style=color:#666>42</span>))<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.field(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#ba2121>&#34;bin_field&#34;</span>.to_string(),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>Value::Varbinary(<span style=color:#ba2121>b</span><span style=color:#ba2121>&#34;field_bin_val&#34;</span>.to_vec()),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>)<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.build()<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>.unwrap();<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><ul><li>Add the <code>point</code> to <code>write request</code>:</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>mut</span><span style=color:#bbb> </span>write_req<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>WriteRequest::default();<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>write_req.add_point(point);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><ul><li><p>New <code>rpc_ctx</code>, and it can also be defined on demand or just use the default value, <a href=https://github.com/apache/horaedb-client-rs/blob/a72e673103463c7962e01a097592fc7edbcc0b79/src/rpc_client/mod.rs#L29>detail about rpc ctx</a>:</p></li><li><p>Finally, write to server by client.</p></li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>rpc_ctx<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>RpcContext<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>database: <span style=color:green>Some</span>(<span style=color:#ba2121>&#34;public&#34;</span>.to_string()),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>..</span><span style=color:green>Default</span>::default()<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>};<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>resp<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client.write(rpc_ctx,<span style=color:#bbb> </span><span style=color:#666>&amp;</span>write_req).<span style=color:green;font-weight:700>await</span>.expect(<span style=color:#ba2121>&#34;Should success to write&#34;</span>);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=sql-query>Sql Query</h2><p>We support to query data with sql.</p><ul><li>Define related tables and sql in <code>sql query request</code>:</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>req<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>SqlQueryRequest<span style=color:#bbb> </span>{<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>tables: <span style=color:#00f;font-weight:700>vec</span><span style=color:#666>!</span>[table<span style=color:#bbb> </span>name<span style=color:#bbb> </span><span style=color:#666>1</span>,<span style=color:#666>..</span>.,table<span style=color:#bbb> </span>name<span style=color:#bbb> </span>n],<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>sql: <span style=color:#00f;font-weight:700>sql</span><span style=color:#bbb> </span>string<span style=color:#bbb> </span>(e.g.<span style=color:#bbb> </span>select<span style=color:#bbb> </span><span style=color:#666>*</span><span style=color:#bbb> </span>from<span style=color:#bbb> </span>xxx),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span>};<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><ul><li>Query by client:</li></ul><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:green;font-weight:700>let</span><span style=color:#bbb> </span>resp<span style=color:#bbb> </span><span style=color:#666>=</span><span style=color:#bbb> </span>client.sql_query(rpc_ctx,<span style=color:#bbb> </span><span style=color:#666>&amp;</span>req).<span style=color:green;font-weight:700>await</span>.expect(<span style=color:#ba2121>&#34;Should success to write&#34;</span>);<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=example>Example</h2><p>You can find the <a href=https://github.com/apache/horaedb-client-rs/blob/main/examples/read_write.rs>complete example</a> in the project.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-3c025d4e044df01b41b46653bf151f0b>4 - Operation and Maintenance</h1><p>This guide introduces the operation and maintenance of HoraeDB, including cluster installation, database&amp;table operations, fault tolerance, disaster recovery, data import and export, etc.</p></div><div class=td-content><h1 id=pg-738a2f3b8314089a64b49e9b83ab85e7>4.1 - Block List</h1><h2 id=add-block-list>Add block list</h2><p>If you want to reject query for a table, you can add table name to &lsquo;read_block_list&rsquo;.</p><h3 id=example>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://localhost:5000/admin/block&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;operation&#34;:&#34;Add&#34;,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;write_block_list&#34;:[],
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;read_block_list&#34;:[&#34;my_table&#34;]
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h3 id=response>Response</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span>{
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;write_block_list&#34;</span>: [],
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;read_block_list&#34;</span>: [<span style=color:#ba2121>&#34;my_table&#34;</span>]
</span></span><span style=display:flex><span>}
</span></span></code></pre></td></tr></table></div></div><h2 id=set-block-list>Set block list</h2><p>You can use set operation to clear exist tables and set new tables to &lsquo;read_block_list&rsquo; like following example.</p><h3 id=example-1>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://localhost:5000/admin/block&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;operation&#34;:&#34;Set&#34;,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;write_block_list&#34;:[],
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;read_block_list&#34;:[&#34;my_table1&#34;,&#34;my_table2&#34;]
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h3 id=response-1>Response</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span>{
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;write_block_list&#34;</span>: [],
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;read_block_list&#34;</span>: [<span style=color:#ba2121>&#34;my_table1&#34;</span>, <span style=color:#ba2121>&#34;my_table2&#34;</span>]
</span></span><span style=display:flex><span>}
</span></span></code></pre></td></tr></table></div></div><h2 id=remove-block-list>Remove block list</h2><p>You can remove tables from &lsquo;read_block_list&rsquo; like following example.</p><h3 id=example-2>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://localhost:5000/admin/block&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;operation&#34;:&#34;Remove&#34;,
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;write_block_list&#34;:[],
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;read_block_list&#34;:[&#34;my_table1&#34;]
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h3 id=response-2>Response</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span>{
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;write_block_list&#34;</span>: [],
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;read_block_list&#34;</span>: [<span style=color:#ba2121>&#34;my_table2&#34;</span>]
</span></span><span style=display:flex><span>}
</span></span></code></pre></td></tr></table></div></div></div><div class=td-content style=page-break-before:always><h1 id=pg-5ee6dffed65012da62e99d132c3d88a0>4.2 - Cluster Operation</h1><p>The Operations for HoraeDB cluster mode, it can only be used when HoraeMeta is deployed.</p><h2 id=operation-interface>Operation Interface</h2><p>You need to replace 127.0.0.1 with the actual project path.</p><ul><li>Query table
When tableNames is not empty, use tableNames for query.
When tableNames is empty, ids are used for query. When querying with ids, schemaName is useless.</li></ul><pre tabindex=0><code>curl --location &#39;http://127.0.0.1:8080/api/v1/table/query&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;{
&#34;clusterName&#34;:&#34;defaultCluster&#34;,
&#34;schemaName&#34;:&#34;public&#34;,
&#34;names&#34;:[&#34;demo1&#34;, &#34;__demo1_0&#34;],
}&#39;
curl --location &#39;http://127.0.0.1:8080/api/v1/table/query&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;{
&#34;clusterName&#34;:&#34;defaultCluster&#34;,
&#34;ids&#34;:[0, 1]
}&#39;
</code></pre><ul><li>Query the route of table</li></ul><pre tabindex=0><code>curl --location --request POST &#39;http://127.0.0.1:8080/api/v1/route&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;{
&#34;clusterName&#34;:&#34;defaultCluster&#34;,
&#34;schemaName&#34;:&#34;public&#34;,
&#34;table&#34;:[&#34;demo&#34;]
}&#39;
</code></pre><ul><li>Query the mapping of shard and node</li></ul><pre tabindex=0><code>curl --location --request POST &#39;http://127.0.0.1:8080/api/v1/getNodeShards&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;{
&#34;ClusterName&#34;:&#34;defaultCluster&#34;
}&#39;
</code></pre><ul><li>Query the mapping of table and shard
If ShardIDs in the request is empty, query with all shardIDs in the cluster.</li></ul><pre tabindex=0><code>curl --location --request POST &#39;http://127.0.0.1:8080/api/v1/getShardTables&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;{
&#34;clusterName&#34;:&#34;defaultCluster&#34;,
&#34;shardIDs&#34;: [1,2]
}&#39;
</code></pre><ul><li>Drop table</li></ul><pre tabindex=0><code>curl --location --request POST &#39;http://127.0.0.1:8080/api/v1/dropTable&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;{
&#34;clusterName&#34;: &#34;defaultCluster&#34;,
&#34;schemaName&#34;: &#34;public&#34;,
&#34;table&#34;: &#34;demo&#34;
}&#39;
</code></pre><ul><li>Transfer leader shard</li></ul><pre tabindex=0><code>curl --location --request POST &#39;http://127.0.0.1:8080/api/v1/transferLeader&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;{
&#34;clusterName&#34;:&#34;defaultCluster&#34;,
&#34;shardID&#34;: 1,
&#34;oldLeaderNodeName&#34;: &#34;127.0.0.1:8831&#34;,
&#34;newLeaderNodeName&#34;: &#34;127.0.0.1:18831&#34;
}&#39;
</code></pre><ul><li>Split shard</li></ul><pre tabindex=0><code>curl --location --request POST &#39;http://127.0.0.1:8080/api/v1/split&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;{
&#34;clusterName&#34; : &#34;defaultCluster&#34;,
&#34;schemaName&#34; :&#34;public&#34;,
&#34;nodeName&#34; :&#34;127.0.0.1:8831&#34;,
&#34;shardID&#34; : 0,
&#34;splitTables&#34;:[&#34;demo&#34;]
}&#39;
</code></pre><ul><li>Create cluster</li></ul><pre tabindex=0><code>curl --location &#39;http://127.0.0.1:8080/api/v1/clusters&#39; \
--header &#39;Content-Type: application/json&#39; \
--data &#39;{
&#34;name&#34;:&#34;testCluster&#34;,
&#34;nodeCount&#34;:3,
&#34;shardTotal&#34;:9,
&#34;topologyType&#34;:&#34;static&#34;
}&#39;
</code></pre><ul><li>Update cluster</li></ul><pre tabindex=0><code>curl --location --request PUT &#39;http://127.0.0.1:8080/api/v1/clusters/{NewClusterName}&#39; \
--header &#39;Content-Type: application/json&#39; \
--data &#39;{
&#34;nodeCount&#34;:28,
&#34;shardTotal&#34;:128,
&#34;topologyType&#34;:&#34;dynamic&#34;
}&#39;
</code></pre><ul><li>List clusters</li></ul><pre tabindex=0><code>curl --location &#39;http://127.0.0.1:8080/api/v1/clusters&#39;
</code></pre><ul><li>Update <code>enableSchedule</code></li></ul><pre tabindex=0><code>curl --location --request PUT &#39;http://127.0.0.1:8080/api/v1/clusters/{ClusterName}/enableSchedule&#39; \
--header &#39;Content-Type: application/json&#39; \
--data &#39;{
&#34;enable&#34;:true
}&#39;
</code></pre><ul><li>Query <code>enableSchedule</code></li></ul><pre tabindex=0><code>curl --location &#39;http://127.0.0.1:8080/api/v1/clusters/{ClusterName}/enableSchedule&#39;
</code></pre><ul><li>Update flow limiter</li></ul><pre tabindex=0><code>curl --location --request PUT &#39;http://127.0.0.1:8080/api/v1/flowLimiter&#39; \
--header &#39;Content-Type: application/json&#39; \
--data &#39;{
&#34;limit&#34;:1000,
&#34;burst&#34;:10000,
&#34;enable&#34;:true
}&#39;
</code></pre><ul><li>Query information of flow limiter</li></ul><pre tabindex=0><code>curl --location &#39;http://127.0.0.1:8080/api/v1/flowLimiter&#39;
</code></pre><ul><li>List nodes of HoraeMeta cluster</li></ul><pre tabindex=0><code>curl --location &#39;http://127.0.0.1:8080/api/v1/etcd/member&#39;
</code></pre><ul><li>Move leader of HoraeMeta cluster</li></ul><pre tabindex=0><code>curl --location &#39;http://127.0.0.1:8080/api/v1/etcd/moveLeader&#39; \
--header &#39;Content-Type: application/json&#39; \
--data &#39;{
&#34;memberName&#34;:&#34;meta1&#34;
}&#39;
</code></pre><ul><li>Add node of HoraeMeta cluster</li></ul><pre tabindex=0><code>curl --location --request PUT &#39;http://127.0.0.1:8080/api/v1/etcd/member&#39; \
--header &#39;Content-Type: application/json&#39; \
--data &#39;{
&#34;memberAddrs&#34;:[&#34;http://127.0.0.1:42380&#34;]
}&#39;
</code></pre><ul><li>Replace node of HoraeMeta cluster</li></ul><pre tabindex=0><code>curl --location &#39;http://127.0.0.1:8080/api/v1/etcd/member&#39; \
--header &#39;Content-Type: application/json&#39; \
--data &#39;{
&#34;oldMemberName&#34;:&#34;meta0&#34;,
&#34;newMemberAddr&#34;:[&#34;http://127.0.0.1:42380&#34;]
}&#39;
</code></pre></div><div class=td-content style=page-break-before:always><h1 id=pg-8075e68e25cc23e412d57385899cca86>4.3 - Observability</h1><p>HoraeDB is observable with Prometheus and Grafana.</p><h2 id=prometheus>Prometheus</h2><p><a href=https://github.com/prometheus/prometheus>Prometheus</a> is a systems and service monitoring system.</p><h3 id=configuration>Configuration</h3><p>Save the following configuration into the <code>prometheus.yml</code> file. For example, in the <code>tmp</code> directory, <code>/tmp/prometheus.yml</code>.</p><p>Two HoraeDB http service are started on localhost:5440 and localhost:5441.</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">8
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-yaml data-lang=yaml><span style=display:flex><span><span style=color:green;font-weight:700>global</span>:<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>scrape_interval</span>:<span style=color:#bbb> </span>30s<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>scrape_configs</span>:<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>- <span style=color:green;font-weight:700>job_name</span>:<span style=color:#bbb> </span>horaedb-server<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>static_configs</span>:<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>- <span style=color:green;font-weight:700>targets</span>:<span style=color:#bbb> </span>[your_ip:5440, your_ip:5441]<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>labels</span>:<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>env</span>:<span style=color:#bbb> </span>horaedbcluster<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>See details about configuration <a href=https://prometheus.io/docs/prometheus/latest/configuration/configuration/>here</a>.</p><h3 id=run>Run</h3><p>You can use docker to start Prometheus. The docker image information is <a href=https://hub.docker.com/r/prom/prometheus>here</a>.</p><pre tabindex=0><code>docker run \
-d --name=prometheus \
-p 9090:9090 \
-v /tmp/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus:v2.41.0
</code></pre><p>For more detailed installation methods, refer to <a href=https://prometheus.io/docs/prometheus/latest/installation/>here</a>.</p><h2 id=grafana>Grafana</h2><p><a href=https://github.com/grafana/grafana>Grafana</a> is an open and composable observability and data visualization platform.</p><h3 id=run-1>Run</h3><p>You can use docker to start grafana. The docker image information is <a href=https://hub.docker.com/r/grafana/grafana>here</a>.</p><pre tabindex=0><code>docker run -d --name=grafana -p 3000:3000 grafana/grafana:9.3.6
</code></pre><p>Default admin user credentials are admin/admin.</p><p>Grafana is available on http://127.0.0.1:3000.</p><p>For more detailed installation methods, refer to <a href=https://grafana.com/docs/grafana/latest/setup-grafana/installation/>here</a>.</p><h3 id=configure-data-source>Configure data source</h3><ol><li>Hover the cursor over the Configuration (gear) icon.</li><li>Select Data Sources.</li><li>Select the Prometheus data source.</li></ol><p>Note: The url of Prometheus is <code>http://your_ip:9090</code>.</p><img src=/images/grafana-datasource.png height=400 width=200><p>See more details <a href=https://grafana.com/docs/grafana/latest/datasources/prometheus/>here</a>.</p><h3 id=import-grafana-dashboard>Import grafana dashboard</h3><p><a href=/grafana-dashboard.json>dashboard json</a></p><img src=/images/grafana-dashboard.png height=400 width=200><h2 id=horaedb-metrics>HoraeDB Metrics</h2><p>After importing the dashboard, you will see the following page:</p><img src=/images/grafana-horaedb-dashboard.png height=400 width=600><h3 id=panels>Panels</h3><ul><li>tps: Number of cluster write requests.</li><li>qps: Number of cluster query requests.</li><li>99th query/write duration: 99th quantile of write and query duration.</li><li>table query: Query group by table.</li><li>99th write duration details by instance: 99th quantile of write duration group by instance.</li><li>99th query duration details by instance: 99th quantile of query duration group by instance.</li><li>99th write partition table duration: 99th quantile of write duration of partition table.</li><li>table rows: The rows of data written.</li><li>table rows by instance: The written rows by instance.</li><li>total tables to write: Number of tables with data written.</li><li>flush count: Number of HoraeDB flush.</li><li>99th flush duration details by instance: 99th quantile of flush duration group by instance.</li><li>99th write stall duration details by instance: 99th quantile of write stall duration group by instance.</li></ul></div><div class=td-content style=page-break-before:always><h1 id=pg-a415e58936001e7befe959b3318dac0e>4.4 - Table Operation</h1><h2 id=query-table-information>Query Table Information</h2><p>Like Mysql&rsquo;s <code>information_schema.tables</code>, HoraeDB provides <code>system.public.tables</code> to save tables information.
Columns:</p><ul><li>timestamp([TimeStamp])</li><li>catalog([String])</li><li>schema([String])</li><li>table_name([String])</li><li>table_id([Uint64])</li><li>engine([String])</li></ul><h3 id=example>Example</h3><p>Query table information via table_name like this:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://localhost:5000/sql&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;query&#34;: &#34;select * from system.public.tables where `table_name`=\&#34;my_table\&#34;&#34;
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h3 id=response>Response</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span>{
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;rows&#34;</span>:[
</span></span><span style=display:flex><span> {
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;timestamp&#34;</span>:<span style=color:#666>0</span>,
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;catalog&#34;</span>:<span style=color:#ba2121>&#34;horaedb&#34;</span>,
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;schema&#34;</span>:<span style=color:#ba2121>&#34;public&#34;</span>,
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;table_name&#34;</span>:<span style=color:#ba2121>&#34;my_table&#34;</span>,
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;table_id&#34;</span>:<span style=color:#666>3298534886446</span>,
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;engine&#34;</span>:<span style=color:#ba2121>&#34;Analytic&#34;</span>
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span><span>}</span>
</span></span></code></pre></td></tr></table></div></div></div><div class=td-content style=page-break-before:always><h1 id=pg-5a18a99c1e89b2e34e598ab36e5b8980>4.5 - Table Operation</h1><p>HoraeDB supports standard SQL protocols and allows you to create tables and read/write data via http requests. More <a href=../sql/README.md>SQL</a></p><h2 id=create-table>Create Table</h2><h3 id=example>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://127.0.0.1:5000/sql&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;query&#34;: &#34;CREATE TABLE `demo` (`name` string TAG, `value` double NOT NULL, `t` timestamp NOT NULL, TIMESTAMP KEY(t)) ENGINE=Analytic with (enable_ttl=&#39;</span><span style=color:#b62;font-weight:700>\&#39;</span><span style=color:#ba2121>&#39;false&#39;</span><span style=color:#b62;font-weight:700>\&#39;</span><span style=color:#ba2121>&#39;)&#34;
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h2 id=write-data>Write Data</h2><h3 id=example-1>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://127.0.0.1:5000/sql&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;query&#34;: &#34;INSERT INTO demo(t, name, value) VALUES(1651737067000, &#39;</span><span style=color:#b62;font-weight:700>\&#39;</span><span style=color:#ba2121>&#39;horaedb&#39;</span><span style=color:#b62;font-weight:700>\&#39;</span><span style=color:#ba2121>&#39;, 100)&#34;
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h2 id=read-data>Read Data</h2><h3 id=example-2>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://127.0.0.1:5000/sql&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;query&#34;: &#34;select * from demo&#34;
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h2 id=query-table-info>Query Table Info</h2><h3 id=example-3>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://127.0.0.1:5000/sql&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;query&#34;: &#34;show create table demo&#34;
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h3 id=drop-table>Drop Table</h3><h3 id=example-4>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request POST <span style=color:#ba2121>&#39;http://127.0.0.1:5000/sql&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>--header <span style=color:#ba2121>&#39;Content-Type: application/json&#39;</span> <span style=color:#b62;font-weight:700>\
</span></span></span><span style=display:flex><span><span style=color:#b62;font-weight:700></span>-d <span style=color:#ba2121>&#39;{
</span></span></span><span style=display:flex><span><span style=color:#ba2121> &#34;query&#34;: &#34;DROP TABLE demo&#34;
</span></span></span><span style=display:flex><span><span style=color:#ba2121>}&#39;</span>
</span></span></code></pre></td></tr></table></div></div><h2 id=route-table>Route Table</h2><h3 id=example-5>Example</h3><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl --location --request GET <span style=color:#ba2121>&#39;http://127.0.0.1:5000/route/{table_name}&#39;</span>
</span></span></code></pre></td></tr></table></div></div></div><div class=td-content style=page-break-before:always><h1 id=pg-c93dd709b75734feb3f3eb452bb3638a>5 - Ecosystem</h1><p>HoraeDB has an open ecosystem that encourages collaboration and innovation, allowing developers to use what suits them best.</p></div><div class=td-content><h1 id=pg-12941b77e52512197bc3e2eabb976682>5.1 - InfluxDB</h1><p><a href=https://www.influxdata.com/products/influxdb-overview/>InfluxDB</a> is a time series database designed to handle high write and query loads. It is an integral component of the TICK stack. InfluxDB is meant to be used as a backing store for any use case involving large amounts of timestamped data, including DevOps monitoring, application metrics, IoT sensor data, and real-time analytics.</p><p>HoraeDB support <a href=https://docs.influxdata.com/influxdb/v1.8/tools/api/#influxdb-1x-http-endpoints>InfluxDB v1.8</a> write and query API.</p><blockquote><p>Warn: users need to add following config to server&rsquo;s config in order to try InfluxDB write/query.</p></blockquote><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-toml data-lang=toml><span style=display:flex><span>[server.default_schema_config]
</span></span><span style=display:flex><span>default_timestamp_column_name = <span style=color:#ba2121>&#34;time&#34;</span>
</span></span></code></pre></td></tr></table></div></div><h1 id=write>Write</h1><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>curl -i -XPOST <span style=color:#ba2121>&#34;http://localhost:5440/influxdb/v1/write&#34;</span> --data-binary <span style=color:#ba2121>&#39;
</span></span></span><span style=display:flex><span><span style=color:#ba2121>demo,tag1=t1,tag2=t2 field1=90,field2=100 1679994647000
</span></span></span><span style=display:flex><span><span style=color:#ba2121>demo,tag1=t1,tag2=t2 field1=91,field2=101 1679994648000
</span></span></span><span style=display:flex><span><span style=color:#ba2121>demo,tag1=t11,tag2=t22 field1=90,field2=100 1679994647000
</span></span></span><span style=display:flex><span><span style=color:#ba2121>demo,tag1=t11,tag2=t22 field1=91,field2=101 1679994648000
</span></span></span><span style=display:flex><span><span style=color:#ba2121>&#39;</span>
</span></span></code></pre></td></tr></table></div></div><p>Post payload is in <a href=https://docs.influxdata.com/influxdb/v1.8/write_protocols/line_protocol_reference/>InfluxDB line protocol</a> format.</p><p>Measurement will be mapped to table in HoraeDB, and it will be created automatically in first write(Note: The default TTL is 7d, and points written exceed TTL will be discarded directly).</p><p>For example, when inserting data above, table below will be automatically created in HoraeDB:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">9
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sql data-lang=sql><span style=display:flex><span><span style=color:green;font-weight:700>CREATE</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>TABLE</span><span style=color:#bbb> </span><span style=color:#666>`</span>demo<span style=color:#666>`</span><span style=color:#bbb> </span>(<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>tsid<span style=color:#666>`</span><span style=color:#bbb> </span>uint64<span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>time<span style=color:#666>`</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NOT</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>NULL</span>,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>field1<span style=color:#666>`</span><span style=color:#bbb> </span>double,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>field2<span style=color:#666>`</span><span style=color:#bbb> </span>double,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>tag1<span style=color:#666>`</span><span style=color:#bbb> </span>string<span style=color:#bbb> </span>TAG,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:#666>`</span>tag2<span style=color:#666>`</span><span style=color:#bbb> </span>string<span style=color:#bbb> </span>TAG,<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>PRIMARY</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span><span style=color:#bbb> </span>(tsid,<span style=color:#bbb> </span>time),<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span><span style=color:green;font-weight:700>timestamp</span><span style=color:#bbb> </span><span style=color:green;font-weight:700>KEY</span><span style=color:#bbb> </span>(time))<span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><h2 id=note>Note</h2><ul><li>When InfluxDB writes data, the timestamp precision is nanosecond by default, HoraeDB only supports millisecond timestamp, user can specify the data precision by <code>precision</code> parameter, HoraeDB will automatically convert to millisecond precision internally.</li><li>Query string parameters such as <code>db</code> aren&rsquo;t supported.</li></ul><h1 id=query>Query</h1><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span> curl -G <span style=color:#ba2121>&#39;http://localhost:5440/influxdb/v1/query&#39;</span> --data-urlencode <span style=color:#ba2121>&#39;q=SELECT * FROM &#34;demo&#34;&#39;</span>
</span></span></code></pre></td></tr></table></div></div><p>Query result is same with InfluxDB:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">19
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span>{
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;results&#34;</span>: [
</span></span><span style=display:flex><span> {
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;statement_id&#34;</span>: <span style=color:#666>0</span>,
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;series&#34;</span>: [
</span></span><span style=display:flex><span> {
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;name&#34;</span>: <span style=color:#ba2121>&#34;demo&#34;</span>,
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;columns&#34;</span>: [<span style=color:#ba2121>&#34;time&#34;</span>, <span style=color:#ba2121>&#34;field1&#34;</span>, <span style=color:#ba2121>&#34;field2&#34;</span>, <span style=color:#ba2121>&#34;tag1&#34;</span>, <span style=color:#ba2121>&#34;tag2&#34;</span>],
</span></span><span style=display:flex><span> <span style=color:green;font-weight:700>&#34;values&#34;</span>: [
</span></span><span style=display:flex><span> [<span style=color:#666>1679994647000</span>, <span style=color:#666>90.0</span>, <span style=color:#666>100.0</span>, <span style=color:#ba2121>&#34;t1&#34;</span>, <span style=color:#ba2121>&#34;t2&#34;</span>],
</span></span><span style=display:flex><span> [<span style=color:#666>1679994647000</span>, <span style=color:#666>90.0</span>, <span style=color:#666>100.0</span>, <span style=color:#ba2121>&#34;t11&#34;</span>, <span style=color:#ba2121>&#34;t22&#34;</span>],
</span></span><span style=display:flex><span> [<span style=color:#666>1679994648000</span>, <span style=color:#666>91.0</span>, <span style=color:#666>101.0</span>, <span style=color:#ba2121>&#34;t1&#34;</span>, <span style=color:#ba2121>&#34;t2&#34;</span>],
</span></span><span style=display:flex><span> [<span style=color:#666>1679994648000</span>, <span style=color:#666>91.0</span>, <span style=color:#666>101.0</span>, <span style=color:#ba2121>&#34;t11&#34;</span>, <span style=color:#ba2121>&#34;t22&#34;</span>]
</span></span><span style=display:flex><span> ]
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> ]
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> ]
</span></span><span style=display:flex><span>}
</span></span></code></pre></td></tr></table></div></div><h2 id=usage-in-grafana>Usage in Grafana</h2><p>HoraeDB can be used as InfluxDB data source in Grafana.</p><ul><li>Select InfluxDB type when add data source</li><li>Then input <code>http://{ip}:{5440}/influxdb/v1/</code> in HTTP URL. For local deployment, URL is http://localhost:5440/influxdb/v1/</li><li><code>Save & test</code></li></ul><h2 id=note-1>Note</h2><p>Query string parameters such as <code>epoch</code>, <code>db</code>, <code>pretty</code> aren&rsquo;t supported.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-1fb5a05253c98bdbe5c288caa145feda>5.2 - OpenTSDB</h1><p><a href=http://opentsdb.net/>OpenTSDB</a> is a distributed and scalable time series database based on HBase.</p><h1 id=write>Write</h1><p>HoraeDB follows the <a href=http://opentsdb.net/docs/build/html/api_http/put.html>OpenTSDB put</a> write protocol.</p><p><code>summary</code> and <code>detailed</code> are not yet supported.</p><pre tabindex=0><code>curl --location &#39;http://localhost:5440/opentsdb/api/put&#39; \
--header &#39;Content-Type: application/json&#39; \
-d &#39;[{
&#34;metric&#34;: &#34;sys.cpu.nice&#34;,
&#34;timestamp&#34;: 1692588459000,
&#34;value&#34;: 18,
&#34;tags&#34;: {
&#34;host&#34;: &#34;web01&#34;,
&#34;dc&#34;: &#34;lga&#34;
}
},
{
&#34;metric&#34;: &#34;sys.cpu.nice&#34;,
&#34;timestamp&#34;: 1692588459000,
&#34;value&#34;: 18,
&#34;tags&#34;: {
&#34;host&#34;: &#34;web01&#34;
}
}]&#39;
&#39;
</code></pre><p>Metric will be mapped to table in HoraeDB, and it will be created automatically in first write(Note: The default TTL is 7d, and points written exceed TTL will be discarded directly).</p><p>For example, when inserting data above, table below will be automatically created in HoraeDB:</p><pre tabindex=0><code>CREATE TABLE `sys.cpu.nice`(
`tsid` uint64 NOT NULL,
`timestamp` timestamp NOT NULL,
`dc` string TAG,
`host` string TAG,
`value` bigint,
PRIMARY KEY(tsid, timestamp),
TIMESTAMP KEY(timestamp))
ENGINE = Analytic
WITH(arena_block_size = &#39;2097152&#39;, compaction_strategy = &#39;default&#39;,
compression = &#39;ZSTD&#39;, enable_ttl = &#39;true&#39;, num_rows_per_row_group = &#39;8192&#39;,
segment_duration = &#39;2h&#39;, storage_format = &#39;AUTO&#39;, ttl = &#39;7d&#39;,
update_mode = &#39;OVERWRITE&#39;, write_buffer_size = &#39;33554432&#39;)
</code></pre><h1 id=query>Query</h1><p>OpenTSDB query protocol is not currently supported, <a href=https://github.com/apache/incubator-horaedb/issues/904>tracking issue</a>.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-136053bf48d308f01c84dea97b7eed0c>5.3 - Prometheus</h1><p><a href=https://prometheus.io/>Prometheus</a> is a popular cloud-native monitoring tool that is widely adopted by organizations due to its scalability, reliability, and scalability. It is used to scrape metrics from cloud-native services, such as Kubernetes and OpenShift, and stores it in a time-series database. Prometheus is also easily extensible, allowing users to extend its features and capabilities with other databases.</p><p>HoraeDB can be used as a long-term storage solution for Prometheus. Both remote read and remote write API are supported.</p><h2 id=config>Config</h2><p>You can configure Prometheus to use HoraeDB as a remote storage by adding following lines to <code>prometheus.yml</code>:</p><div class=highlight><div style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><table style=border-spacing:0;padding:0;margin:0;border:0><tr><td style=vertical-align:top;padding:0;margin:0;border:0><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f">4
</span></code></pre></td><td style=vertical-align:top;padding:0;margin:0;border:0;width:100%><pre tabindex=0 style=-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-yml data-lang=yml><span style=display:flex><span><span style=color:green;font-weight:700>remote_write</span>:<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>- <span style=color:green;font-weight:700>url</span>:<span style=color:#bbb> </span><span style=color:#ba2121>&#34;http://&lt;address&gt;:&lt;http_port&gt;/prom/v1/write&#34;</span><span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb></span><span style=color:green;font-weight:700>remote_read</span>:<span style=color:#bbb>
</span></span></span><span style=display:flex><span><span style=color:#bbb> </span>- <span style=color:green;font-weight:700>url</span>:<span style=color:#bbb> </span><span style=color:#ba2121>&#34;http://&lt;address&gt;:&lt;http_port&gt;/prom/v1/read&#34;</span><span style=color:#bbb>
</span></span></span></code></pre></td></tr></table></div></div><p>Each metric will be converted to one table in HoraeDB:</p><ul><li>labels are mapped to corresponding <code>string</code> tag column</li><li>timestamp of sample is mapped to a timestamp <code>timestmap</code> column</li><li>value of sample is mapped to a double <code>value</code> column</li></ul><p>For example, <code>up</code> metric below will be mapped to <code>up</code> table:</p><pre tabindex=0><code>up{env=&#34;dev&#34;, instance=&#34;127.0.0.1:9090&#34;, job=&#34;prometheus-server&#34;}
</code></pre><p>Its corresponding table in HoraeDB(Note: The TTL for creating a table is 7d, and points written exceed TTL will be discarded directly):</p><pre tabindex=0><code>CREATE TABLE `up` (
`timestamp` timestamp NOT NULL,
`tsid` uint64 NOT NULL,
`env` string TAG,
`instance` string TAG,
`job` string TAG,
`value` double,
PRIMARY KEY (tsid, timestamp),
timestamp KEY (timestamp)
);
SELECT * FROM up;
</code></pre><table><thead><tr><th style=text-align:center>tsid</th><th style=text-align:center>timestamp</th><th style=text-align:center>env</th><th style=text-align:center>instance</th><th style=text-align:center>job</th><th style=text-align:center>value</th></tr></thead><tbody><tr><td style=text-align:center>12683162471309663278</td><td style=text-align:center>1675824740880</td><td style=text-align:center>dev</td><td style=text-align:center>127.0.0.1:9090</td><td style=text-align:center>prometheus-server</td><td style=text-align:center>1</td></tr></tbody></table></div></main></div></div><footer class="td-footer row d-print-none"><div class=container-fluid><div class="row mx-md-2"><div class=td-footer__center>Apache HoraeDB is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.<hr><span class=td-footer__copyright>&copy;
2023&ndash;2024
<span class=td-footer__authors><p>The Apache Software Foundation, Licensed under the Apache License, Version 2.0.</p><p>Apache, the names of Apache projects, and the feather logo are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries.</p></span></span><span class=td-footer__all_rights_reserved>All Rights Reserved</span></div></div><hr><div class="row mx-md-2"><div class=td-footer__center><span class=td-footer__copyright>Found a bug in website? <a href=https://github.com/apache/horaedb-docs/issues/new>Open an issue</a> or <a href=https://github.com/apache/horaedb-docs/pulls>submit a pull request</a> on GitHub.</span></div></div><hr></div></footer></div><script src=/js/main.min.f72d00502781aaf278a14088eb2356b1ba2a05ad698a0c43fe86314d74ceab56.js integrity="sha256-9y0AUCeBqvJ4oUCI6yNWsboqBa1pigxD/oYxTXTOq1Y=" crossorigin=anonymous></script><script defer src=/js/click-to-copy.min.73478a7d4807698aed7e355eb23f9890ca18fea3158604c8471746d046702bad.js integrity="sha256-c0eKfUgHaYrtfjVesj+YkMoY/qMVhgTIRxdG0EZwK60=" crossorigin=anonymous></script><script src=/js/tabpane-persist.js></script></body></html>