Merge branch 'master' into decimal

This commit is contained in:
chertus 2018-07-27 20:56:13 +03:00
commit f793fb553a
17 changed files with 383 additions and 51 deletions

View File

@ -89,6 +89,94 @@ namespace ErrorCodes
}
/// Checks expected server and client error codes in testmode.
/// To enable it add special comment after the query: "-- { serverError 60 }" or "-- { clientError 20 }".
class TestHint
{
public:
TestHint(bool enabled_, const String & query)
: enabled(enabled_),
server_error(0),
client_error(0)
{
if (!enabled_)
return;
size_t pos = query.find("--");
if (pos != String::npos && query.find("--", pos + 2) != String::npos)
return; /// It's not last comment. Hint belongs to commented query.
if (pos != String::npos)
{
pos = query.find('{', pos + 2);
if (pos != String::npos)
{
String hint = query.substr(pos + 1);
pos = hint.find('}');
hint.resize(pos);
parse(hint);
}
}
}
void checkActual(int actual_server_error, int actual_client_error,
bool & got_exception, std::unique_ptr<Exception> & last_exception) const
{
if (!enabled)
return;
if (allErrorsExpected(actual_server_error, actual_client_error))
{
got_exception = false;
last_exception.reset();
}
if (lostExpectedError(actual_server_error, actual_client_error))
{
std::cerr << "Success when error expected. It expects server error "
<< server_error << ", client error " << client_error << "." << std::endl;
got_exception = true;
}
}
int serverError() const { return server_error; }
int clientError() const { return client_error; }
private:
bool enabled;
int server_error;
int client_error;
void parse(const String & hint)
{
std::stringstream ss;
ss << hint;
while (!ss.eof())
{
String item;
ss >> item;
if (item.empty())
break;
if (item == "serverError")
ss >> server_error;
else if (item == "clientError")
ss >> client_error;
}
}
bool allErrorsExpected(int actual_server_error, int actual_client_error) const
{
return (server_error == actual_server_error) && (client_error == actual_client_error);
}
bool lostExpectedError(int actual_server_error, int actual_client_error) const
{
return (server_error && !actual_server_error) || (client_error && !actual_client_error);
}
};
class Client : public Poco::Util::Application
{
public:
@ -157,6 +245,10 @@ private:
/// If the last query resulted in exception.
bool got_exception = false;
int expected_server_error = 0;
int expected_client_error = 0;
int actual_server_error = 0;
int actual_client_error = 0;
String server_version;
String server_display_name;
@ -617,10 +709,14 @@ private:
}
catch (const Exception & e)
{
std::cerr << std::endl
<< "Exception on client:" << std::endl
<< "Code: " << e.code() << ". " << e.displayText() << std::endl
<< std::endl;
actual_client_error = e.code();
if (!actual_client_error || actual_client_error != expected_client_error)
{
std::cerr << std::endl
<< "Exception on client:" << std::endl
<< "Code: " << e.code() << ". " << e.displayText() << std::endl
<< std::endl;
}
/// Client-side exception during query execution can result in the loss of
/// sync in the connection protocol.
@ -659,6 +755,7 @@ private:
bool process(const String & text)
{
const auto ignore_error = config().getBool("ignore-error", false);
const bool test_mode = config().has("testmode");
if (config().has("multiquery"))
{
/// Several queries separated by ';'.
@ -702,6 +799,10 @@ private:
while (isWhitespaceASCII(*begin) || *begin == ';')
++begin;
TestHint test_hint(test_mode, query);
expected_client_error = test_hint.clientError();
expected_server_error = test_hint.serverError();
try
{
if (!processSingleQuery(query, ast) && !ignore_error)
@ -709,10 +810,13 @@ private:
}
catch (...)
{
actual_client_error = getCurrentExceptionCode();
std::cerr << "Error on processing query: " << query << std::endl << getCurrentExceptionMessage(true);
got_exception = true;
}
test_hint.checkActual(actual_server_error, actual_client_error, got_exception, last_exception);
if (got_exception && !ignore_error)
{
if (is_interactive)
@ -1286,6 +1390,14 @@ private:
resetOutput();
got_exception = true;
actual_server_error = e.code();
if (expected_server_error)
{
if (actual_server_error == expected_server_error)
return;
std::cerr << "Expected error code: " << expected_server_error << " but got: " << actual_server_error << "." << std::endl;
}
std::string text = e.displayText();
auto embedded_stack_trace_pos = text.find("Stack trace");
@ -1411,7 +1523,8 @@ public:
("pager", boost::program_options::value<std::string>(), "pager")
("multiline,m", "multiline")
("multiquery,n", "multiquery")
("ignore-error", "Do not stop processing in multiquery mode")
("testmode,T", "enable test hints in comments")
("ignore-error", "do not stop processing in multiquery mode")
("format,f", boost::program_options::value<std::string>(), "default output format")
("vertical,E", "vertical output format, same as --format=Vertical or FORMAT Vertical or \\G at end of command")
("time,t", "print query execution time to stderr in non-interactive mode (for benchmarks)")
@ -1517,6 +1630,8 @@ public:
config().setBool("multiline", true);
if (options.count("multiquery"))
config().setBool("multiquery", true);
if (options.count("testmode"))
config().setBool("testmode", true);
if (options.count("ignore-error"))
config().setBool("ignore-error", true);
if (options.count("format"))

View File

@ -195,7 +195,7 @@ def main(args):
stderr_file = os.path.join(suite_tmp_dir, name) + '.stderr'
if ext == '.sql':
command = "{0} --multiquery < {1} > {2} 2> {3}".format(args.client, case_file, stdout_file, stderr_file)
command = "{0} --testmode --multiquery < {1} > {2} 2> {3}".format(args.client, case_file, stdout_file, stderr_file)
else:
command = "{0} > {1} 2> {2}".format(case_file, stdout_file, stderr_file)

View File

@ -19,7 +19,7 @@ class Client:
command = self.command[:]
if stdin is None:
command += ['--multiquery']
command += ['--multiquery', '--testmode']
stdin = sql
else:
command += ['--query', sql]

View File

@ -14,7 +14,7 @@ def _fill_nodes(nodes, shard):
ENGINE = ReplicatedMergeTree('/clickhouse/tables/test{shard}/replicated', '{replica}', date, id, 8192);
'''.format(shard=shard, replica=node.name))
cluster = ClickHouseCluster(__file__, server_bin_path="/home/alesap/ClickHouse/dbms/programs/clickhouse-server")
cluster = ClickHouseCluster(__file__)
node1 = cluster.add_instance('node1', main_configs=['configs/remote_servers.xml', 'configs/credentials1.xml'], with_zookeeper=True)
node2 = cluster.add_instance('node2', main_configs=['configs/remote_servers.xml', 'configs/credentials1.xml'], with_zookeeper=True)

View File

@ -1 +1,12 @@
SELECT * FROM system.numbers LIMIT 10
SELECT * FROM system.numbers LIMIT 3;
SELECT sys_num.number FROM system.numbers AS sys_num WHERE number > 2 LIMIT 2;
SELECT number FROM system.numbers WHERE number >= 5 LIMIT 2;
SELECT * FROM system.numbers WHERE number == 7 LIMIT 1;
SELECT number AS n FROM system.numbers WHERE number IN(8, 9) LIMIT 2;
select number from system.numbers limit 0;
select x from system.numbers limit 1; -- { clientError 0 serverError 47 }
SELECT x, number FROM system.numbers LIMIT 1; -- { serverError 47 }
SELECT * FROM system.number LIMIT 1; -- { serverError 60 }
SELECT * FROM system LIMIT 1; -- { serverError 60 }
SELECT * FROM numbers LIMIT 1; -- { serverError 60 }
SELECT sys.number FROM system.numbers AS sys_num LIMIT 1; -- { serverError 47 }

View File

@ -1 +1,3 @@
['Hello','Goodbye']
['Hello'] ['Goodbye']
[]

View File

@ -1 +1,3 @@
SELECT ['Hello', 'Goodbye']
SELECT ['Hello', 'Goodbye'];
SELECT ['Hello'], ['Goodbye'];
SELECT [];

View File

@ -2,27 +2,27 @@
## True column-oriented DBMS
In a true column-oriented DBMS, there isn't any "garbage" stored with the values. Among other things, this means that constant-length values must be supported, to avoid storing their length "number" next to the values. As an example, a billion UInt8-type values should actually consume around 1 GB uncompressed, or this will strongly affect the CPU use. It is very important to store data compactly (without any "garbage") even when uncompressed, since the speed of decompression (CPU usage) depends mainly on the volume of uncompressed data.
In a true column-oriented DBMS, there is no excessive data stored with the values. For example, this means that constant-length values must be supported, to avoid storing their length as additional integer next to the values. In this case, a billion UInt8 values should actually consume around 1 GB uncompressed, or this will strongly affect the CPU use. It is very important to store data compactly even when uncompressed, since the speed of decompression (CPU usage) depends mainly on the volume of uncompressed data.
This is worth noting because there are systems that can store values of separate columns separately, but that can't effectively process analytical queries due to their optimization for other scenarios. Examples are HBase, BigTable, Cassandra, and HyperTable. In these systems, you will get throughput around a hundred thousand rows per second, but not hundreds of millions of rows per second.
This is worth noting because there are systems that can store values of different columns separately, but that can't effectively process analytical queries due to their optimization for other scenarios. Examples are HBase, BigTable, Cassandra, and HyperTable. In these systems, you will get throughput around a hundred thousand rows per second, but not hundreds of millions of rows per second.
Also note that ClickHouse is a DBMS, not a single database. ClickHouse allows creating tables and databases in runtime, loading data, and running queries without reconfiguring and restarting the server.
Also note that ClickHouse is a database management system, not a single database. ClickHouse allows creating tables and databases in runtime, loading data, and running queries without reconfiguring and restarting the server.
## Data compression
Some column-oriented DBMSs (InfiniDB CE and MonetDB) do not use data compression. However, data compression really improves performance.
Some column-oriented DBMSs (InfiniDB CE and MonetDB) do not use data compression. However, data compression is crucial to achieve excellent performance.
## Disk storage of data
Many column-oriented DBMSs (such as SAP HANA and Google PowerDrill) can only work in RAM. But even on thousands of servers, the RAM is too small for storing all the pageviews and sessions in Yandex.Metrica.
Many column-oriented DBMSs (such as SAP HANA and Google PowerDrill) can only work in RAM. This approach stimulates the allocation of a larger hardware budget than is actually necessary for real-time analysis. ClickHouse is designed to work on regular hard drives, which ensures low cost of ownership per gigabyte of data, but SSD and additional RAM are also utilized fully if available.
## Parallel processing on multiple cores
Large queries are parallelized in a natural way.
Large queries are parallelized in a natural way, utilizing all necessary resources that are available on the current server.
## Distributed processing on multiple servers
Almost none of the columnar DBMSs listed above have support for distributed processing.
Almost none of the columnar DBMSs mentioned above have support for distributed query processing.
In ClickHouse, data can reside on different shards. Each shard can be a group of replicas that are used for fault tolerance. The query is processed on all the shards in parallel. This is transparent for the user.
## SQL support
@ -33,30 +33,37 @@ However, this is a declarative query language based on SQL that can't be differe
JOINs are supported. Subqueries are supported in FROM, IN, and JOIN clauses, as well as scalar subqueries.
Dependent subqueries are not supported.
ClickHouse supports declarative query language that is based on SQL and complies to SQL standard in many cases.
GROUP BY, ORDER BY, scalar subqueries and subqueries in FROM, IN and JOIN clauses are supported.
Correlated subqueries and window functions are not supported.
## Vector engine
Data is not only stored by columns, but is processed by vectors (parts of columns). This allows us to achieve high CPU performance.
Data is not only stored by columns, but is also processed by vectors (parts of columns). This allows to achieve high CPU efficiency.
## Real-time data updates
ClickHouse supports primary key tables. In order to quickly perform queries on the range of the primary key, the data is sorted incrementally using the merge tree. Due to this, data can continually be added to the table. There is no locking when adding data.
ClickHouse supports tables with a primary key. In order to quickly perform queries on the range of the primary key, the data is sorted incrementally using the merge tree. Due to this, data can continually be added to the table. No locks are taken when new data is ingested.
## Indexes
## Index
Having a primary key makes it possible to extract data for specific clients (for instance, Yandex.Metrica tracking tags) for a specific time range, with low latency less than several dozen milliseconds.
Having a data physically sorted by primary key makes it possible to extract data for it's specific values or value ranges with low latency, less than few dozen milliseconds.
## Suitable for online queries
This lets us use the system as the back-end for a web interface. Low latency means queries can be processed without delay, while the Yandex.Metrica interface page is loading. In other words, in online mode.
Low latency means that queries can be processed without delay and without trying to prepare answer in advance, right at the same moment while user interface page is loading. In other words, online.
## Support for approximated calculations
1. The system contains aggregate functions for approximated calculation of the number of various values, medians, and quantiles.
2. Supports running a query based on a part (sample) of data and getting an approximated result. In this case, proportionally less data is retrieved from the disk.
3. Supports running an aggregation for a limited number of random keys, instead of for all keys. Under certain conditions for key distribution in the data, this provides a reasonably accurate result while using fewer resources.
ClickHouse provides various ways to trade accuracy for performance:
## Data replication and support for data integrity on replicas
1. Aggregate functions for approximated calculation of the number of distinct values, medians, and quantiles.
2. Running a query based on a part (sample) of data and getting an approximated result. In this case, proportionally less data is retrieved from the disk.
3. Running an aggregation for a limited number of random keys, instead of for all keys. Under certain conditions for key distribution in the data, this provides a reasonably accurate result while using fewer resources.
Uses asynchronous multimaster replication. After being written to any available replica, data is distributed to all the remaining replicas. The system maintains identical data on different replicas. Data is restored automatically after a failure, or using a "button" for complex cases.
For more information, see the section [Data replication](../operations/table_engines/replication.md#table_engines-replication).
## Data replication and integrity
ClickHouse uses asynchronous multimaster replication. After being written to any available replica, data is distributed to all the other replicas in background. The system maintains identical data on different replicas. Data is restored automatically after most failures, or semiautomatically in complicated cases.
For more information, see the [Data replication](../operations/table_engines/replication.md#table_engines-replication) section.

View File

@ -1,6 +1,6 @@
# ClickHouse features that can be considered disadvantages
1. No transactions.
2. For aggregation, query results must fit in the RAM on a single server. However, the volume of source data for a query may be indefinitely large.
3. Lack of full-fledged UPDATE/DELETE implementation.
1. No full-fledged transactions.
2. Lack of ability to modify or delete already inserted data with high rate and low latency. There are batch deletes available to clean up data that is not needed anymore or to comply with [GDPR](https://gdpr-info.eu). Batch updates are in development as of July 2018.
3. Sparse index makes ClickHouse not really suitable for point queries retrieving single rows by their keys.

View File

@ -0,0 +1,77 @@
<a name="table_engines-url"></a>
# URL(URL, Format)
This data source operates with data on remote HTTP/HTTPS server. The engine is
similar to [`File`](./file.md#).
## Usage in ClickHouse server
```
URL(URL, Format)
```
`Format` should be supported for `SELECT` and/or `INSERT`. For the full list of
supported formats see [Formats](../../interfaces/formats.md#formats).
`URL` must match the format of Uniform Resource Locator. The specified
URL must address a server working with HTTP or HTTPS. The server shouldn't
require any additional HTTP-headers.
`INSERT` and `SELECT` queries are transformed into `POST` and `GET` requests
respectively. For correct `POST`-requests handling the remote server should support
[Chunked transfer encoding](https://ru.wikipedia.org/wiki/Chunked_transfer_encoding).
**Example:**
**1.** Create the `url_engine_table` table:
```sql
CREATE TABLE url_engine_table (word String, value UInt64)
ENGINE=URL('http://127.0.0.1:12345/', CSV)
```
**2.** Implement simple http-server using python3:
```python3
from http.server import BaseHTTPRequestHandler, HTTPServer
class CSVHTTPServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/csv')
self.end_headers()
self.wfile.write(bytes('Hello,1\nWorld,2\n', "utf-8"))
if __name__ == "__main__":
server_address = ('127.0.0.1', 12345)
HTTPServer(server_address, CSVHTTPServer).serve_forever()
```
```bash
python3 server.py
```
**3.** Query the data:
```sql
SELECT * FROM url_engine_table
```
```text
┌─word──┬─value─┐
│ Hello │ 1 │
│ World │ 2 │
└───────┴───────┘
```
## Details of implementation
- Reads and writes can be parallel
- Not supported:
- `ALTER`
- `SELECT ... SAMPLE`
- Indices
- Replication

View File

@ -0,0 +1,19 @@
<a name="table_functions-url"></a>
# url
`url(URL, format, structure)` - returns a table created from the `URL` with given
`format` and `structure`.
URL - HTTP or HTTPS server address, which can accept `GET` and/or `POST` requests.
format - [format](../../interfaces/formats.md#formats) of the data.
structure - table structure in `'UserID UInt64, Name String'` format. Determines column names and types.
**Example**
```sql
-- getting the first 3 lines of a table that contains columns of String and UInt32 type from HTTP-server which answers in CSV format.
SELECT * FROM url('http://127.0.0.1:12345/', CSV, 'column1 String, column2 UInt32') LIMIT 3
```

View File

@ -2,23 +2,23 @@
## По-настоящему столбцовая СУБД
В по-настоящему столбцовой СУБД рядом со значениями не хранится никакого "мусора". Например, должны поддерживаться значения постоянной длины, чтобы не хранить рядом со значениями типа "число" их длины. Для примера, миллиард значений типа UInt8 должен действительно занимать в несжатом виде около 1GB, иначе это сильно ударит по эффективности использования CPU. Очень важно хранить данные компактно (без "мусора") в том числе в несжатом виде, так как скорость разжатия (использование CPU) зависит, в основном, от объёма несжатых данных.
В по-настоящему столбцовой СУБД рядом со значениями не хранится никаких лишних данных. Например, должны поддерживаться значения постоянной длины, чтобы не хранить рядом со значениями типа "число" их длины. Для примера, миллиард значений типа UInt8 должен действительно занимать в несжатом виде около 1GB, иначе это сильно ударит по эффективности использования CPU. Очень важно хранить данные компактно (без "мусора") в том числе в несжатом виде, так как скорость разжатия (использование CPU) зависит, в основном, от объёма несжатых данных.
Этот пункт пришлось выделить, так как существуют системы, которые могут хранить значения отдельных столбцов по отдельности, но не могут эффективно выполнять аналитические запросы в силу оптимизации под другой сценарий работы. Примеры: HBase, BigTable, Cassandra, HyperTable. В этих системах вы получите throughput в районе сотен тысяч строк в секунду, но не сотен миллионов строк в секунду.
Этот пункт пришлось выделить, так как существуют системы, которые могут хранить значения отдельных столбцов по отдельности, но не могут эффективно выполнять аналитические запросы в силу оптимизации под другой сценарий работы. Примеры: HBase, BigTable, Cassandra, HyperTable. В этих системах вы получите пропускную способность в районе сотен тысяч строк в секунду, но не сотен миллионов строк в секунду.
Также стоит заметить, что ClickHouse является СУБД, а не одной базой данных. То есть, ClickHouse позволяет создавать таблицы и базы данных в runtime, загружать данные и выполнять запросы без переконфигурирования и перезапуска сервера.
Также стоит заметить, что ClickHouse является системой управления базами данных, а не одной базой данных. То есть, ClickHouse позволяет создавать таблицы и базы данных в runtime, загружать данные и выполнять запросы без переконфигурирования и перезапуска сервера.
## Сжатие данных
Некоторые столбцовые СУБД (InfiniDB CE, MonetDB) не используют сжатие данных. Но сжатие данных действительно серьёзно увеличивает производительность.
Некоторые столбцовые СУБД (InfiniDB CE, MonetDB) не используют сжатие данных. Однако сжатие данных действительно играет одну из ключевых ролей в демонстрации отличной производительности.
## Хранение данных на диске
Многие столбцовые СУБД (SAP HANA, Google PowerDrill) могут работать только в оперативке. Но оперативки (даже на тысячах серверах) слишком мало для хранения всех хитов и визитов в Яндекс.Метрике.
Многие столбцовые СУБД (SAP HANA, Google PowerDrill) могут работать только в оперативной памяти. Такой подход стимулирует выделять больший бюджет на оборудование, чем фактически требуется для анализа в реальном времени. ClickHouse спроектирован для работы на обычных жестких дисках, что обеспечивает низкую стоимость хранения на гигабайт данных, но SSD b дополнительная оперативная память тоже полноценно используются, если доступны.
## Параллельная обработка запроса на многих процессорных ядрах
Большие запросы естественным образом распараллеливаются.
Большие запросы естественным образом распараллеливаются, используя все необходимые ресурсы из доступных на сервере.
## Распределённая обработка запроса на многих серверах
@ -27,11 +27,9 @@
## Поддержка SQL
Если вы знаете, что такое стандартный SQL, то говорить о поддержке SQL всё-таки нельзя.
Все функции названы по-другому.
Тем не менее, это - декларативный язык запросов на основе SQL и во многих случаях не отличимый от SQL.
Поддерживаются JOIN-ы. Поддерживаются подзапросы в секциях FROM, IN, JOIN, а также скалярные подзапросы.
Зависимые подзапросы не поддерживаются.
ClickHouse поддерживает декларативный язык запросов на основе SQL и во многих случаях совпадающий с SQL стандартом.
Поддерживаются GROUP BY, ORDER BY, подзапросы в секциях FROM, IN, JOIN, а также скалярные подзапросы.
Зависимые подзапросы и оконные функции не поддерживаются.
## Векторный движок
@ -41,21 +39,24 @@
ClickHouse поддерживает таблицы с первичным ключом. Для того, чтобы можно было быстро выполнять запросы по диапазону первичного ключа, данные инкрементально сортируются с помощью merge дерева. За счёт этого, поддерживается постоянное добавление данных в таблицу. Блокировки при добавлении данных отсутствуют.
## Наличие индексов
## Наличие индекса
Наличие первичного ключа позволяет, например, вынимать данные для конкретных клиентов (счётчиков Метрики), для заданного диапазона времени, с низкими задержками - менее десятков миллисекунд.
Физическая сортировка данных по первичному ключу позволяет получать данные для конкретных его значений или их диапазонов с низкими задержками - менее десятков миллисекунд.
## Подходит для онлайн запросов
Это позволяет использовать систему в качестве бэкенда для веб-интерфейса. Низкие задержки позволяют не откладывать выполнение запроса, а выполнять его в момент загрузки страницы интерфейса Яндекс.Метрики. То есть, в режиме онлайн.
Низкие задержки позволяют не откладывать выполнение запроса и не подготавливать ответ заранее, а выполнять его именно в момент загрузки страницы пользовательского интерфейса. То есть, в режиме онлайн.
## Поддержка приближённых вычислений
ClickHouse предоставляет различные способы разменять точность вычислений на производительность:
1. Система содержит агрегатные функции для приближённого вычисления количества различных значений, медианы и квантилей.
2. Поддерживается возможность выполнить запрос на основе части (выборки) данных и получить приближённый результат. При этом, с диска будет считано пропорционально меньше данных.
3. Поддерживается возможность выполнить агрегацию не для всех ключей, а для ограниченного количества первых попавшихся ключей. При выполнении некоторых условий на распределение ключей в данных, это позволяет получить достаточно точный результат с использованием меньшего количества ресурсов.
## Репликация данных, поддержка целостности данных на репликах
## Репликация данных и поддержка целостности
Используется асинхронная multimaster репликация. После записи на любую доступную реплику, данные распространяются на все остальные реплики в фоне. Система поддерживает полную идентичность данных на разных репликах. Восстановление после большинства сбоев осуществляется автоматически, а в сложных случаях — полуавтоматически.
Используется асинхронная multimaster репликация. После записи на любую доступную реплику, данные распространяются на все остальные реплики. Система поддерживает полную идентичность данных на разных репликах. Восстановление после сбоя осуществляется автоматически, а в сложных случаях - "по кнопке".
Подробнее смотрите раздел [Репликация данных](../operations/table_engines/replication.md#table_engines-replication).

View File

@ -1,6 +1,6 @@
# Особенности ClickHouse, которые могут считаться недостатками
1. Отсутствие транзакций.
2. Необходимо, чтобы результат выполнения запроса, в случае агрегации, помещался в оперативку на одном сервере. Объём исходных данных для запроса, при этом, может быть сколь угодно большим.
3. Отсутствие полноценной реализации UPDATE/DELETE.
1. Отсутствие полноценных транзакций.
2. Возможность изменять или удалять ранее записанные данные с низкими задержками и высокой частотой запросов не предоставляется. Есть массовое удаление данных для очистки более не нужного или соответствия [GDPR](https://gdpr-info.eu). Массовое изменение данных находится в разработке (на момент июля 2018).
3. Разреженный индекс делает ClickHouse плохо пригодным для точечных чтений одиночных строк по своим
ключам.

View File

@ -0,0 +1,74 @@
<a name="table_engines-url"></a>
# URL(URL, Format)
Управляет данными на удаленном HTTP/HTTPS сервере. Данный движок похож
на движок [`File`](./file.md#).
## Использование движка в сервере ClickHouse
`Format` должен быть таким, который ClickHouse может использовать в запросах
`SELECT` и, если есть необходимость, `INSERT`. Полный список поддерживаемых форматов смотрите в
разделе [Форматы](../../interfaces/formats.md#formats).
`URL` должен соответствовать структуре Uniform Resource Locator. По указанному URL должен находится сервер
работающий по протоколу HTTP или HTTPS. При этом не должно требоваться никаких
дополнительных заголовков для получения ответа от сервера.
Запросы `INSERT` и `SELECT` транслируются в `POST` и `GET` запросы
соответственно. Для обработки `POST`-запросов удаленный сервер должен поддерживать
[Chunked transfer encoding](https://ru.wikipedia.org/wiki/Chunked_transfer_encoding).
**Пример:**
**1.** Создадим на сервере таблицу `url_engine_table`:
```sql
CREATE TABLE url_engine_table (word String, value UInt64)
ENGINE=URL('http://127.0.0.1:12345/', CSV)
```
**2.** Создадим простейший http-сервер стандартными средствами языка python3 и
запустим его:
```python3
from http.server import BaseHTTPRequestHandler, HTTPServer
class CSVHTTPServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/csv')
self.end_headers()
self.wfile.write(bytes('Hello,1\nWorld,2\n', "utf-8"))
if __name__ == "__main__":
server_address = ('127.0.0.1', 12345)
HTTPServer(server_address, CSVHTTPServer).serve_forever()
```
```bash
python3 server.py
```
**3.** Запросим данные:
```sql
SELECT * FROM url_engine_table
```
```text
┌─word──┬─value─┐
│ Hello │ 1 │
│ World │ 2 │
└───────┴───────┘
```
## Особенности использования
- Поддерживается многопоточное чтение и запись.
- Не поддерживается:
- использование операций `ALTER` и `SELECT...SAMPLE`;
- индексы;
- репликация.

View File

@ -0,0 +1,20 @@
<a name="table_functions-url"></a>
# url
`url(URL, format, structure)` - возвращает таблицу со столбцами, указанными в
`structure`, созданную из данных находящихся по `URL` в формате `format`.
URL - адрес, по которому сервер принимает `GET` и/или `POST` запросы по
протоколу HTTP или HTTPS.
format - [формат](../../interfaces/formats.md#formats) данных.
structure - структура таблицы в форме `'UserID UInt64, Name String'`. Определяет имена и типы столбцов.
**Пример**
```sql
-- получение 3-х строк таблицы, состоящей из двух колонк типа String и UInt32 от сервера, отдающего данные в формате CSV
SELECT * FROM url('http://127.0.0.1:12345/', CSV, 'column1 String, column2 UInt32') LIMIT 3
```

View File

@ -94,6 +94,7 @@ pages:
- 'merge': 'query_language/table_functions/merge.md'
- 'numbers': 'query_language/table_functions/numbers.md'
- 'remote': 'query_language/table_functions/remote.md'
- 'url': 'query_language/table_functions/url.md'
- 'Dictionaries':
- 'Introduction': 'query_language/dicts/index.md'
- 'External dictionaries':
@ -134,6 +135,7 @@ pages:
- 'Null': 'operations/table_engines/null.md'
- 'Set': 'operations/table_engines/set.md'
- 'Join': 'operations/table_engines/join.md'
- 'URL': 'operations/table_engines/url.md'
- 'View': 'operations/table_engines/view.md'
- 'MaterializedView': 'operations/table_engines/materializedview.md'
- 'Integrations':

View File

@ -97,6 +97,7 @@ pages:
- 'merge': 'query_language/table_functions/merge.md'
- 'numbers': 'query_language/table_functions/numbers.md'
- 'remote': 'query_language/table_functions/remote.md'
- 'url': 'query_language/table_functions/url.md'
- 'Словари':
- 'Введение': 'query_language/dicts/index.md'
- 'Внешние словари':
@ -138,6 +139,7 @@ pages:
- 'Null': 'operations/table_engines/null.md'
- 'Set': 'operations/table_engines/set.md'
- 'Join': 'operations/table_engines/join.md'
- 'URL': 'operations/table_engines/url.md'
- 'View': 'operations/table_engines/view.md'
- 'MaterializedView': 'operations/table_engines/materializedview.md'
- 'Интеграции':