小写文件夹名称

This commit is contained in:
YuCheng Hu 2021-07-19 16:53:42 -04:00
parent 517aae2d32
commit 9e96b69952
46 changed files with 60 additions and 60 deletions

View File

@ -6,12 +6,12 @@
|---|---| |---|---|
| 电子邮件 | [service@ossez.com](mailto:service@ossez.com) | | 电子邮件 | [service@ossez.com](mailto:service@ossez.com) |
| QQ 或微信 | 103899765 | | QQ 或微信 | 103899765 |
| QQ 交流群 Spring | 15186112 | | QQ 交流群 | 15186112 |
| 社区论坛 | [https://www.ossez.com/](https://www.ossez.com/) | | 社区论坛 | [https://www.ossez.com/](https://www.ossez.com/) |
## 公众平台 ## 公众平台
我们建议您通过社区论坛来和我们进行沟通,请关注我们公众平台上的账号 我们建议您通过社区论坛来和我们进行沟通,请关注我们公众平台上的账号
### 微信公众号 ### 微信公众号
![](https://cdn.ossez.com/img/cwikius/cwikius-qr-wechat-search-w400.png) ![](https://cdn.ossez.com/img/cwikius/cwikius-qr-wechat-search-w400.png)

View File

@ -59,7 +59,7 @@ jvm.config runtime.properties
在我们的所有进程中有四个需要配置的JVM参数 在我们的所有进程中有四个需要配置的JVM参数
1. `-Duser.timezone=UTC` 该参数将JVM的默认时区设置为UTC。我们总是这样设置不使用其他默认时区进行测试因此本地时区可能会工作但它们也可能会发现奇怪和有趣的错误。要在非UTC时区中发出查询请参阅 [查询粒度](../Querying/granularity.md) 1. `-Duser.timezone=UTC` 该参数将JVM的默认时区设置为UTC。我们总是这样设置不使用其他默认时区进行测试因此本地时区可能会工作但它们也可能会发现奇怪和有趣的错误。要在非UTC时区中发出查询请参阅 [查询粒度](../querying/granularity.md)
2. `-Dfile.encoding=UTF-8` 这类似于时区我们假设UTF-8进行测试。本地编码可能有效但也可能导致奇怪和有趣的错误。 2. `-Dfile.encoding=UTF-8` 这类似于时区我们假设UTF-8进行测试。本地编码可能有效但也可能导致奇怪和有趣的错误。
3. `-Djava.io.tmpdir=<a path>` 系统中与文件系统交互的各个部分都是通过临时文件完成的,这些文件可能会变得有些大。许多生产系统都被设置为具有小的(但是很快的)`/tmp`目录这对于Druid来说可能是个问题因此我们建议将JVM的tmp目录指向一些有更多内容的目录。此目录不应为volatile tmpfs。这个目录还应该具有良好的读写速度因此应该强烈避免NFS挂载。 3. `-Djava.io.tmpdir=<a path>` 系统中与文件系统交互的各个部分都是通过临时文件完成的,这些文件可能会变得有些大。许多生产系统都被设置为具有小的(但是很快的)`/tmp`目录这对于Druid来说可能是个问题因此我们建议将JVM的tmp目录指向一些有更多内容的目录。此目录不应为volatile tmpfs。这个目录还应该具有良好的读写速度因此应该强烈避免NFS挂载。
4. `-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager` 这允许log4j2处理使用标准java日志的非log4j2组件如jetty的日志。 4. `-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager` 这允许log4j2处理使用标准java日志的非log4j2组件如jetty的日志。

View File

@ -101,7 +101,7 @@ foo_2015-01-03/2015-01-04_v1_2
除非所有输入段具有相同的元数据,否则输出段可以具有与输入段不同的元数据。 除非所有输入段具有相同的元数据,否则输出段可以具有与输入段不同的元数据。
* Dimensions: 由于Apache Druid支持schema更改因此即使是同一个数据源的一部分各个段之间的维度也可能不同。如果输入段具有不同的维度则输出段基本上包括输入段的所有维度。但是即使输入段具有相同的维度集维度顺序或维度的数据类型也可能不同。例如某些维度的数据类型可以从 `字符串` 类型更改为基本类型,或者可以更改维度的顺序以获得更好的局部性。在这种情况下,在数据类型和排序方面,最近段的维度先于旧段的维度。这是因为最近的段更有可能具有所需的新顺序和数据类型。如果要使用自己的顺序和类型,可以在压缩任务规范中指定自定义 `dimensionsSpec` * Dimensions: 由于Apache Druid支持schema更改因此即使是同一个数据源的一部分各个段之间的维度也可能不同。如果输入段具有不同的维度则输出段基本上包括输入段的所有维度。但是即使输入段具有相同的维度集维度顺序或维度的数据类型也可能不同。例如某些维度的数据类型可以从 `字符串` 类型更改为基本类型,或者可以更改维度的顺序以获得更好的局部性。在这种情况下,在数据类型和排序方面,最近段的维度先于旧段的维度。这是因为最近的段更有可能具有所需的新顺序和数据类型。如果要使用自己的顺序和类型,可以在压缩任务规范中指定自定义 `dimensionsSpec`
* Roll-up: 仅当为所有输入段设置了 `rollup` 时,才会汇总输出段。有关详细信息,请参见 [rollup](ingestion.md#rollup)。您可以使用 [段元数据查询](../Querying/segmentMetadata.md) 检查段是否已被rollup。 * Roll-up: 仅当为所有输入段设置了 `rollup` 时,才会汇总输出段。有关详细信息,请参见 [rollup](ingestion.md#rollup)。您可以使用 [段元数据查询](../querying/segmentMetadata.md) 检查段是否已被rollup。
#### 压缩合并的IOConfig #### 压缩合并的IOConfig
压缩IOConfig需要指定 `inputSpec`,如下所示。 压缩IOConfig需要指定 `inputSpec`,如下所示。
@ -139,7 +139,7 @@ Druid不支持按主键更新单个记录。
#### 使用lookups #### 使用lookups
如果有需要经常更新值的维度,请首先尝试使用 [lookups](../Querying/lookups.md)。lookups的一个典型用例是在Druid段中存储一个ID维度并希望将ID维度映射到一个人类可读的字符串值该字符串值可能需要定期更新。 如果有需要经常更新值的维度,请首先尝试使用 [lookups](../querying/lookups.md)。lookups的一个典型用例是在Druid段中存储一个ID维度并希望将ID维度映射到一个人类可读的字符串值该字符串值可能需要定期更新。
#### 重新摄取数据 #### 重新摄取数据

View File

@ -62,7 +62,7 @@ Druid会拒绝时间窗口之外的事件 确认事件是否被拒绝了的
### 查询返回来了空结果 ### 查询返回来了空结果
您可以对为数据源创建的dimension和metric使用段 [元数据查询](../Querying/segmentMetadata.md)。确保您在查询中使用的聚合器的名称与这些metric之一匹配还要确保指定的查询间隔与存在数据的有效时间范围匹配。 您可以对为数据源创建的dimension和metric使用段 [元数据查询](../querying/segmentMetadata.md)。确保您在查询中使用的聚合器的名称与这些metric之一匹配还要确保指定的查询间隔与存在数据的有效时间范围匹配。
### schema变化时如何在Druid中重新索引现有数据 ### schema变化时如何在Druid中重新索引现有数据

View File

@ -203,7 +203,7 @@ s3n://billy-bucket/the/data/is/here/y=2012/m=06/d=01/H=23
| `dataSource` | String | Druid数据源名称从该数据源读取数据 | 是 | | `dataSource` | String | Druid数据源名称从该数据源读取数据 | 是 |
| `intervals` | List | ISO-8601时间间隔的字符串List | 是 | | `intervals` | List | ISO-8601时间间隔的字符串List | 是 |
| `segments` | List | 从中读取数据的段的列表默认情况下自动获取。您可以通过向Coordinator的接口 `/druid/Coordinator/v1/metadata/datasources/segments?full` 进行POST查询来获取要放在这里的段列表。例如["2012-01-01T00:00:00.000/2012-01-03T00:00:00.000""2012-01-05T00:00:00.000/2012-01-07T00:00:00.000"]. 您可能希望手动提供此列表,以确保读取的段与任务提交时的段完全相同,如果用户提供的列表与任务实际运行时的数据库状态不匹配,则任务将失败 | 否 | | `segments` | List | 从中读取数据的段的列表默认情况下自动获取。您可以通过向Coordinator的接口 `/druid/Coordinator/v1/metadata/datasources/segments?full` 进行POST查询来获取要放在这里的段列表。例如["2012-01-01T00:00:00.000/2012-01-03T00:00:00.000""2012-01-05T00:00:00.000/2012-01-07T00:00:00.000"]. 您可能希望手动提供此列表,以确保读取的段与任务提交时的段完全相同,如果用户提供的列表与任务实际运行时的数据库状态不匹配,则任务将失败 | 否 |
| `filter` | JSON | 查看 [Filter](../Querying/filters.md) | 否 | | `filter` | JSON | 查看 [Filter](../querying/filters.md) | 否 |
| `dimensions` | String数组 | 要加载的维度列的名称。默认情况下,列表将根据 `parseSpec` 构造。如果 `parseSpec` 没有维度的显式列表,则将读取存储数据中的所有维度列。 | 否 | | `dimensions` | String数组 | 要加载的维度列的名称。默认情况下,列表将根据 `parseSpec` 构造。如果 `parseSpec` 没有维度的显式列表,则将读取存储数据中的所有维度列。 | 否 |
| `metrics` | String数组 | 要加载的Metric列的名称。默认情况下列表将根据所有已配置聚合器的"name"构造。 | 否 | | `metrics` | String数组 | 要加载的Metric列的名称。默认情况下列表将根据所有已配置聚合器的"name"构造。 | 否 |
| `ignoreWhenNoSegments` | boolean | 如果找不到段,是否忽略此 `ingestionSpec`。默认行为是在找不到段时引发错误。| 否 | | `ignoreWhenNoSegments` | boolean | 如果找不到段,是否忽略此 `ingestionSpec`。默认行为是在找不到段时引发错误。| 否 |

View File

@ -102,7 +102,7 @@ Rollup由 `granularitySpec` 中的 `rollup` 配置项控制。 默认情况下
有关如何配置Rollup以及该特性将如何修改数据的示例请参阅[Rollup教程](../tutorials/chapter-5.md)。 有关如何配置Rollup以及该特性将如何修改数据的示例请参阅[Rollup教程](../tutorials/chapter-5.md)。
#### 最大化rollup比率 #### 最大化rollup比率
通过比较Druid中的行数和接收的事件数可以测量数据源的汇总率。这个数字越高从汇总中获得的好处就越多。一种方法是使用[Druid SQL](../Querying/druidsql.md)查询,比如: 通过比较Druid中的行数和接收的事件数可以测量数据源的汇总率。这个数字越高从汇总中获得的好处就越多。一种方法是使用[Druid SQL](../querying/druidsql.md)查询,比如:
```json ```json
SELECT SUM("cnt") / COUNT(*) * 1.0 FROM datasource SELECT SUM("cnt") / COUNT(*) * 1.0 FROM datasource
``` ```
@ -162,7 +162,7 @@ Druid数据源总是按时间划分为*时间块*,每个时间块包含一个
> >
> 注意,当然,划分数据的一种方法是将其加载到分开的数据源中。这是一种完全可行的方法,当数据源的数量不会导致每个数据源的开销过大时,它可以很好地工作。如果使用这种方法,那么可以忽略这一部分,因为这部分描述了如何在单个数据源中设置分区。 > 注意,当然,划分数据的一种方法是将其加载到分开的数据源中。这是一种完全可行的方法,当数据源的数量不会导致每个数据源的开销过大时,它可以很好地工作。如果使用这种方法,那么可以忽略这一部分,因为这部分描述了如何在单个数据源中设置分区。
> >
> 有关将数据拆分为单独数据源的详细信息以及潜在的操作注意事项,请参阅 [多租户注意事项](../Querying/multitenancy.md)。 > 有关将数据拆分为单独数据源的详细信息以及潜在的操作注意事项,请参阅 [多租户注意事项](../querying/multitenancy.md)。
### 摄入规范 ### 摄入规范
@ -347,7 +347,7 @@ Druid数据源总是按时间划分为*时间块*,每个时间块包含一个
|-|-|-| |-|-|-|
| dimensions | 维度名称或者对象的列表,在 `dimensions``dimensionExclusions` 中不能包含相同的列。 <br><br> 如果该配置为一个空数组Druid将会把所有未出现在 `dimensionExclusions` 中的非时间、非指标列当做字符串类型的维度列,参见[Inclusions and exclusions](#Inclusions-and-exclusions)。 | `[]` | | dimensions | 维度名称或者对象的列表,在 `dimensions``dimensionExclusions` 中不能包含相同的列。 <br><br> 如果该配置为一个空数组Druid将会把所有未出现在 `dimensionExclusions` 中的非时间、非指标列当做字符串类型的维度列,参见[Inclusions and exclusions](#Inclusions-and-exclusions)。 | `[]` |
| dimensionExclusions | 在摄取中需要排除的列名称,在该配置中只支持名称,不支持对象。在 `dimensions``dimensionExclusions` 中不能包含相同的列。 | `[]` | | dimensionExclusions | 在摄取中需要排除的列名称,在该配置中只支持名称,不支持对象。在 `dimensions``dimensionExclusions` 中不能包含相同的列。 | `[]` |
| spatialDimensions | 一个[空间维度](../Querying/spatialfilter.md)的数组 | `[]` | | spatialDimensions | 一个[空间维度](../querying/spatialfilter.md)的数组 | `[]` |
###### `Dimension objects` ###### `Dimension objects`
`dimensions` 列的每一个维度可以是一个名称,也可以是一个对象。 提供一个名称等价于提供了一个给定名称的 `string` 类型的维度对象。例如: `page` 等价于 `{"name": "page", "type": "string"}` `dimensions` 列的每一个维度可以是一个名称,也可以是一个对象。 提供一个名称等价于提供了一个给定名称的 `string` 类型的维度对象。例如: `page` 等价于 `{"name": "page", "type": "string"}`
@ -378,7 +378,7 @@ Druid以两种可能的方式来解释 `dimensionsSpec` : *normal* 和 *schemale
##### `metricsSpec` ##### `metricsSpec`
`metricsSpec` 位于 `dataSchema` -> `metricsSpec` 中,是一个在摄入阶段要应用的 [聚合器](../Querying/Aggregations.md) 列表。 在启用了 [rollup](#rollup) 时是很有用的,因为它将配置如何在摄入阶段进行聚合。 `metricsSpec` 位于 `dataSchema` -> `metricsSpec` 中,是一个在摄入阶段要应用的 [聚合器](../querying/Aggregations.md) 列表。 在启用了 [rollup](#rollup) 时是很有用的,因为它将配置如何在摄入阶段进行聚合。
一个 `metricsSpec` 实例如下: 一个 `metricsSpec` 实例如下:
```json ```json
@ -389,7 +389,7 @@ Druid以两种可能的方式来解释 `dimensionsSpec` : *normal* 和 *schemale
] ]
``` ```
> [!WARNING] > [!WARNING]
> 通常,当 [rollup](#rollup) 被禁用时,应该有一个空的 `metricsSpec`因为没有rollupDruid不会在摄取时进行任何的聚合所以没有理由包含摄取时聚合器。但是在某些情况下定义Metrics仍然是有意义的例如如果要创建一个复杂的列作为 [近似聚合](../Querying/Aggregations.md#近似聚合) 的预计算部分,则只能通过在 `metricsSpec` 中定义度量来实现 > 通常,当 [rollup](#rollup) 被禁用时,应该有一个空的 `metricsSpec`因为没有rollupDruid不会在摄取时进行任何的聚合所以没有理由包含摄取时聚合器。但是在某些情况下定义Metrics仍然是有意义的例如如果要创建一个复杂的列作为 [近似聚合](../querying/Aggregations.md#近似聚合) 的预计算部分,则只能通过在 `metricsSpec` 中定义度量来实现
##### `granularitySpec` ##### `granularitySpec`
@ -419,7 +419,7 @@ Druid以两种可能的方式来解释 `dimensionsSpec` : *normal* 和 *schemale
|-|-|-| |-|-|-|
| type | `uniform` 或者 `arbitrary` ,大多数时候使用 `uniform` | `uniform` | | type | `uniform` 或者 `arbitrary` ,大多数时候使用 `uniform` | `uniform` |
| segmentGranularity | 数据源的 [时间分块](../design/Design.md#数据源和段) 粒度。每个时间块可以创建多个段, 例如,当设置为 `day` 时,同一天的事件属于同一时间块,该时间块可以根据其他配置和输入大小进一步划分为多个段。这里可以提供任何粒度。请注意,同一时间块中的所有段应具有相同的段粒度。 <br><br> 如果 `type` 字段设置为 `arbitrary` 则忽略 | `day` | | segmentGranularity | 数据源的 [时间分块](../design/Design.md#数据源和段) 粒度。每个时间块可以创建多个段, 例如,当设置为 `day` 时,同一天的事件属于同一时间块,该时间块可以根据其他配置和输入大小进一步划分为多个段。这里可以提供任何粒度。请注意,同一时间块中的所有段应具有相同的段粒度。 <br><br> 如果 `type` 字段设置为 `arbitrary` 则忽略 | `day` |
| queryGranularity | 每个段内时间戳存储的分辨率, 必须等于或比 `segmentGranularity` 更细。这将是您可以查询的最细粒度,并且仍然可以查询到合理的结果。但是请注意,您仍然可以在比此粒度更粗的场景进行查询,例如 "`minute`"的值意味着记录将以分钟的粒度存储并且可以在分钟的任意倍数包括分钟、5分钟、小时等进行查询。<br><br> 这里可以提供任何 [粒度](../Querying/AggregationGranularity.md) 。使用 `none` 按原样存储时间戳,而不进行任何截断。请注意,即使将 `queryGranularity` 设置为 `none`,也将应用 `rollup`。 | `none` | | queryGranularity | 每个段内时间戳存储的分辨率, 必须等于或比 `segmentGranularity` 更细。这将是您可以查询的最细粒度,并且仍然可以查询到合理的结果。但是请注意,您仍然可以在比此粒度更粗的场景进行查询,例如 "`minute`"的值意味着记录将以分钟的粒度存储并且可以在分钟的任意倍数包括分钟、5分钟、小时等进行查询。<br><br> 这里可以提供任何 [粒度](../querying/AggregationGranularity.md) 。使用 `none` 按原样存储时间戳,而不进行任何截断。请注意,即使将 `queryGranularity` 设置为 `none`,也将应用 `rollup`。 | `none` |
| rollup | 是否在摄取时使用 [rollup](#rollup)。 注意:即使 `queryGranularity` 设置为 `none`rollup也仍然是有效的当数据具有相同的时间戳时数据将被汇总 | `true` | | rollup | 是否在摄取时使用 [rollup](#rollup)。 注意:即使 `queryGranularity` 设置为 `none`rollup也仍然是有效的当数据具有相同的时间戳时数据将被汇总 | `true` |
| interval | 描述应该创建段的时间块的间隔列表。如果 `type` 设置为`uniform`,则此列表将根据 `segmentGranularity` 进行拆分和舍入。如果 `type` 设置为 `arbitrary` ,则将按原样使用此列表。<br><br> 如果该值不提供或者为空值,则批处理摄取任务通常会根据在输入数据中找到的时间戳来确定要输出的时间块。<br><br> 如果指定,批处理摄取任务可以跳过确定分区阶段,这可能会导致更快的摄取。批量摄取任务也可以预先请求它们的所有锁,而不是逐个请求。批处理摄取任务将丢弃任何时间戳超出指定间隔的记录。<br><br> 在任何形式的流摄取中忽略该配置。 | `null` | | interval | 描述应该创建段的时间块的间隔列表。如果 `type` 设置为`uniform`,则此列表将根据 `segmentGranularity` 进行拆分和舍入。如果 `type` 设置为 `arbitrary` ,则将按原样使用此列表。<br><br> 如果该值不提供或者为空值,则批处理摄取任务通常会根据在输入数据中找到的时间戳来确定要输出的时间块。<br><br> 如果指定,批处理摄取任务可以跳过确定分区阶段,这可能会导致更快的摄取。批量摄取任务也可以预先请求它们的所有锁,而不是逐个请求。批处理摄取任务将丢弃任何时间戳超出指定间隔的记录。<br><br> 在任何形式的流摄取中忽略该配置。 | `null` |

View File

@ -1095,7 +1095,7 @@ Druid输入源支持直接从现有的Druid段读取数据可能使用新的
| `interval` | ISO-8601时间间隔的字符串它定义了获取数据的时间范围。 | 是 | | `interval` | ISO-8601时间间隔的字符串它定义了获取数据的时间范围。 | 是 |
| `dimensions` | 包含要从Druid数据源中选择的维度列名称的字符串列表。如果列表为空则不返回维度。如果为空则返回所有维度。 | 否 | | `dimensions` | 包含要从Druid数据源中选择的维度列名称的字符串列表。如果列表为空则不返回维度。如果为空则返回所有维度。 | 否 |
| `metrics` | 包含要选择的Metric列名称的字符串列表。如果列表为空则不返回任何度量。如果为空则返回所有Metric。 | 否 | | `metrics` | 包含要选择的Metric列名称的字符串列表。如果列表为空则不返回任何度量。如果为空则返回所有Metric。 | 否 |
| `filter` | 详情请查看 [filters](../Querying/filters.html) 如果指定,则只返回与筛选器匹配的行。 | 否 | | `filter` | 详情请查看 [filters](../querying/filters.html) 如果指定,则只返回与筛选器匹配的行。 | 否 |
DruidInputSource规范的最小示例如下所示 DruidInputSource规范的最小示例如下所示
```json ```json

View File

@ -22,23 +22,23 @@
* 除了timestamp列之外Druid数据源中的所有列都是dimensions或metrics。这遵循 [OLAP数据的标准命名约定](https://en.wikipedia.org/wiki/Online_analytical_processing#Overview_of_OLAP_systems)。 * 除了timestamp列之外Druid数据源中的所有列都是dimensions或metrics。这遵循 [OLAP数据的标准命名约定](https://en.wikipedia.org/wiki/Online_analytical_processing#Overview_of_OLAP_systems)。
* 典型的生产数据源有几十到几百列。 * 典型的生产数据源有几十到几百列。
* [dimension列](ingestion.md#维度) 按原样存储因此可以在查询时对其进行筛选、分组或聚合。它们总是单个字符串、字符串数组、单个long、单个double或单个float。 * [dimension列](ingestion.md#维度) 按原样存储因此可以在查询时对其进行筛选、分组或聚合。它们总是单个字符串、字符串数组、单个long、单个double或单个float。
* [Metrics列](ingestion.md#指标) 是 [预聚合](../Querying/Aggregations.md) 存储的,因此它们只能在查询时聚合(不能按筛选或分组)。它们通常存储为数字(整数或浮点数),但也可以存储为复杂对象,如[HyperLogLog草图或近似分位数草图](../Querying/Aggregations.md)。即使禁用了rollup也可以在接收时配置metrics但在启用汇总时最有用。 * [Metrics列](ingestion.md#指标) 是 [预聚合](../querying/Aggregations.md) 存储的,因此它们只能在查询时聚合(不能按筛选或分组)。它们通常存储为数字(整数或浮点数),但也可以存储为复杂对象,如[HyperLogLog草图或近似分位数草图](../querying/Aggregations.md)。即使禁用了rollup也可以在接收时配置metrics但在启用汇总时最有用。
### 与其他设计模式类比 ### 与其他设计模式类比
#### 关系模型 #### 关系模型
(如 Hive 或者 PostgreSQL (如 Hive 或者 PostgreSQL
Druid数据源通常相当于关系数据库中的表。Druid的 [lookups特性](../Querying/lookups.md) 可以类似于数据仓库样式的维度表,但是正如您将在下面看到的,如果您能够摆脱它,通常建议您进行非规范化。 Druid数据源通常相当于关系数据库中的表。Druid的 [lookups特性](../querying/lookups.md) 可以类似于数据仓库样式的维度表,但是正如您将在下面看到的,如果您能够摆脱它,通常建议您进行非规范化。
关系数据建模的常见实践涉及 [规范化](https://en.wikipedia.org/wiki/Database_normalization) 的思想:将数据拆分为多个表,从而减少或消除数据冗余。例如,在"sales"表中,最佳实践关系建模要求将"product id"列作为外键放入单独的"products"表中,该表依次具有"product id"、"product name"和"product category"列, 这可以防止产品名称和类别需要在"sales"表中引用同一产品的不同行上重复。 关系数据建模的常见实践涉及 [规范化](https://en.wikipedia.org/wiki/Database_normalization) 的思想:将数据拆分为多个表,从而减少或消除数据冗余。例如,在"sales"表中,最佳实践关系建模要求将"product id"列作为外键放入单独的"products"表中,该表依次具有"product id"、"product name"和"product category"列, 这可以防止产品名称和类别需要在"sales"表中引用同一产品的不同行上重复。
另一方面在Druid中通常使用在查询时不需要连接的完全平坦的数据源。在"sales"表的例子中在Druid中通常直接将"product_id"、"product_name"和"product_category"作为维度存储在Druid "sales"数据源中,而不使用单独的"products"表。完全平坦的模式大大提高了性能因为查询时不需要连接。作为一个额外的速度提升这也允许Druid的查询层直接操作压缩字典编码的数据。因为Druid使用字典编码来有效地为字符串列每行存储一个整数, 所以可能与直觉相反,这并*没有*显著增加相对于规范化模式的存储空间。 另一方面在Druid中通常使用在查询时不需要连接的完全平坦的数据源。在"sales"表的例子中在Druid中通常直接将"product_id"、"product_name"和"product_category"作为维度存储在Druid "sales"数据源中,而不使用单独的"products"表。完全平坦的模式大大提高了性能因为查询时不需要连接。作为一个额外的速度提升这也允许Druid的查询层直接操作压缩字典编码的数据。因为Druid使用字典编码来有效地为字符串列每行存储一个整数, 所以可能与直觉相反,这并*没有*显著增加相对于规范化模式的存储空间。
如果需要的话,可以通过使用 [lookups](../Querying/lookups.md) 规范化Druid数据源这大致相当于关系数据库中的维度表。在查询时您将使用Druid的SQL `LOOKUP` 查找函数或者原生 `lookup` 提取函数而不是像在关系数据库中那样使用JOIN关键字。由于lookup表会增加内存占用并在查询时产生更多的计算开销因此仅当需要更新lookup表并立即反映主表中已摄取行的更改时才建议执行此操作。 如果需要的话,可以通过使用 [lookups](../querying/lookups.md) 规范化Druid数据源这大致相当于关系数据库中的维度表。在查询时您将使用Druid的SQL `LOOKUP` 查找函数或者原生 `lookup` 提取函数而不是像在关系数据库中那样使用JOIN关键字。由于lookup表会增加内存占用并在查询时产生更多的计算开销因此仅当需要更新lookup表并立即反映主表中已摄取行的更改时才建议执行此操作。
在Druid中建模关系数据的技巧 在Druid中建模关系数据的技巧
* Druid数据源没有主键或唯一键所以跳过这些。 * Druid数据源没有主键或唯一键所以跳过这些。
* 如果可能的话去规格化。如果需要定期更新dimensions/lookup并将这些更改反映在已接收的数据中请考虑使用 [lookups](../Querying/lookups.md) 进行部分规范化。 * 如果可能的话去规格化。如果需要定期更新dimensions/lookup并将这些更改反映在已接收的数据中请考虑使用 [lookups](../querying/lookups.md) 进行部分规范化。
* 如果需要将两个大型的分布式表连接起来则必须在将数据加载到Druid之前执行此操作。Druid不支持两个数据源的查询时间连接。lookup在这里没有帮助因为每个lookup表的完整副本存储在每个Druid服务器上所以对于大型表来说它们不是一个好的选择。 * 如果需要将两个大型的分布式表连接起来则必须在将数据加载到Druid之前执行此操作。Druid不支持两个数据源的查询时间连接。lookup在这里没有帮助因为每个lookup表的完整副本存储在每个Druid服务器上所以对于大型表来说它们不是一个好的选择。
* 考虑是否要为预聚合启用[rollup](ingestion.md#rollup)或者是否要禁用rollup并按原样加载现有数据。Druid中的Rollup类似于在关系模型中创建摘要表。 * 考虑是否要为预聚合启用[rollup](ingestion.md#rollup)或者是否要禁用rollup并按原样加载现有数据。Druid中的Rollup类似于在关系模型中创建摘要表。
@ -53,7 +53,7 @@ Druid数据源通常相当于关系数据库中的表。Druid的 [lookups特性]
* Druid并不认为数据点是"时间序列"的一部分。相反Druid对每一点分别进行摄取和聚合 * Druid并不认为数据点是"时间序列"的一部分。相反Druid对每一点分别进行摄取和聚合
* 创建一个维度,该维度指示数据点所属系列的名称。这个维度通常被称为"metric"或"name"。不要将名为"metric"的维度与Druid Metrics的概念混淆。将它放在"dimensionsSpec"中维度列表的第一个位置,以获得最佳性能(这有助于提高局部性;有关详细信息,请参阅下面的 [分区和排序](ingestion.md#分区) * 创建一个维度,该维度指示数据点所属系列的名称。这个维度通常被称为"metric"或"name"。不要将名为"metric"的维度与Druid Metrics的概念混淆。将它放在"dimensionsSpec"中维度列表的第一个位置,以获得最佳性能(这有助于提高局部性;有关详细信息,请参阅下面的 [分区和排序](ingestion.md#分区)
* 为附着到数据点的属性创建其他维度。在时序数据库系统中,这些通常称为"标签" * 为附着到数据点的属性创建其他维度。在时序数据库系统中,这些通常称为"标签"
* 创建与您希望能够查询的聚合类型相对应的 [Druid Metrics](ingestion.md#指标)。通常这包括"sum"、"min"和"max"在long、float或double中的一种。如果你想计算百分位数或分位数可以使用Druid的 [近似聚合器](../Querying/Aggregations.md) * 创建与您希望能够查询的聚合类型相对应的 [Druid Metrics](ingestion.md#指标)。通常这包括"sum"、"min"和"max"在long、float或double中的一种。如果你想计算百分位数或分位数可以使用Druid的 [近似聚合器](../querying/Aggregations.md)
* 考虑启用 [rollup](ingestion.md#rollup)这将允许Druid潜在地将多个点合并到Druid数据源中的一行中。如果希望以不同于原始发出的时间粒度存储数据则这可能非常有用。如果要在同一个数据源中组合时序和非时序数据它也很有用 * 考虑启用 [rollup](ingestion.md#rollup)这将允许Druid潜在地将多个点合并到Druid数据源中的一行中。如果希望以不同于原始发出的时间粒度存储数据则这可能非常有用。如果要在同一个数据源中组合时序和非时序数据它也很有用
* 如果您提前不知道要摄取哪些列,请使用空的维度列表来触发 [维度列的自动检测](#无schema的维度列) * 如果您提前不知道要摄取哪些列,请使用空的维度列表来触发 [维度列的自动检测](#无schema的维度列)
@ -86,7 +86,7 @@ Druid可以在接收数据时将其汇总以最小化需要存储的原始数
草图(sketches)减少了查询时的内存占用因为它们限制了需要在服务器之间洗牌的数据量。例如在分位数计算中Druid不需要将所有数据点发送到中心位置以便对它们进行排序和计算分位数而只需要发送点的草图。这可以将数据传输需要减少到仅千字节。 草图(sketches)减少了查询时的内存占用因为它们限制了需要在服务器之间洗牌的数据量。例如在分位数计算中Druid不需要将所有数据点发送到中心位置以便对它们进行排序和计算分位数而只需要发送点的草图。这可以将数据传输需要减少到仅千字节。
有关Druid中可用的草图的详细信息请参阅 [近似聚合器页面](../Querying/Aggregations.md)。 有关Druid中可用的草图的详细信息请参阅 [近似聚合器页面](../querying/Aggregations.md)。
如果你更喜欢 [视频](https://www.youtube.com/watch?v=Hpd3f_MLdXo)那就看一看吧一个讨论Druid Sketches的会议。 如果你更喜欢 [视频](https://www.youtube.com/watch?v=Hpd3f_MLdXo)那就看一看吧一个讨论Druid Sketches的会议。
@ -104,7 +104,7 @@ Druid schema必须始终包含一个主时间戳, 主时间戳用于对数据进
如果数据有多个时间戳,则可以将其他时间戳作为辅助时间戳摄取。最好的方法是将它们作为 [毫秒格式的Long类型维度](ingestion.md#dimensionsspec) 摄取。如有必要,可以使用 [`transformSpec`](ingestion.md#transformspec) 和 `timestamp_parse` 等 [表达式](../misc/expression.md) 将它们转换成这种格式,后者返回毫秒时间戳。 如果数据有多个时间戳,则可以将其他时间戳作为辅助时间戳摄取。最好的方法是将它们作为 [毫秒格式的Long类型维度](ingestion.md#dimensionsspec) 摄取。如有必要,可以使用 [`transformSpec`](ingestion.md#transformspec) 和 `timestamp_parse` 等 [表达式](../misc/expression.md) 将它们转换成这种格式,后者返回毫秒时间戳。
在查询时,可以使用诸如 `MILLIS_TO_TIMESTAMP`、`TIME_FLOOR` 等 [SQL时间函数](../Querying/druidsql.md) 查询辅助时间戳。如果您使用的是原生Druid查询那么可以使用 [表达式](../misc/expression.md)。 在查询时,可以使用诸如 `MILLIS_TO_TIMESTAMP`、`TIME_FLOOR` 等 [SQL时间函数](../querying/druidsql.md) 查询辅助时间戳。如果您使用的是原生Druid查询那么可以使用 [表达式](../misc/expression.md)。
#### 嵌套维度 #### 嵌套维度

View File

@ -22,7 +22,7 @@
任务API主要在两个地方是可用的 任务API主要在两个地方是可用的
* [Overlord](../design/Overlord.md) 进程提供HTTP API接口来进行提交任务、取消任务、检查任务状态、查看任务日志与报告等。 查看 [任务API文档](../Operations/api.md) 可以看到完整列表 * [Overlord](../design/Overlord.md) 进程提供HTTP API接口来进行提交任务、取消任务、检查任务状态、查看任务日志与报告等。 查看 [任务API文档](../Operations/api.md) 可以看到完整列表
* Druid SQL包括了一个 [`sys.tasks`](../Querying/druidsql.md#系统Schema) ,保存了当前任务运行的信息。 此表是只读的并且可以通过Overlord API查询完整信息的有限制的子集。 * Druid SQL包括了一个 [`sys.tasks`](../querying/druidsql.md#系统Schema) ,保存了当前任务运行的信息。 此表是只读的并且可以通过Overlord API查询完整信息的有限制的子集。
### 任务报告 ### 任务报告

View File

@ -66,39 +66,39 @@
* [问题FAQ](DataIngestion/faq.md) * [问题FAQ](DataIngestion/faq.md)
* [数据查询]() * [数据查询]()
* [Druid SQL](Querying/druidsql.md) * [Druid SQL](querying/druidsql.md)
* [原生查询](Querying/makeNativeQueries.md) * [原生查询](querying/makeNativeQueries.md)
* [查询执行](Querying/queryexecution.md) * [查询执行](querying/queryexecution.md)
* [一些概念](Querying/datasource.md) * [一些概念](querying/datasource.md)
* [数据源](Querying/datasource.md) * [数据源](querying/datasource.md)
* [Joins](Querying/joins.md) * [Joins](querying/joins.md)
* [Lookups](Querying/lookups.md) * [Lookups](querying/lookups.md)
* [多值维度](Querying/multi-value-dimensions.md) * [多值维度](querying/multi-value-dimensions.md)
* [多租户](Querying/multitenancy.md) * [多租户](querying/multitenancy.md)
* [查询缓存](Querying/querycached.md) * [查询缓存](querying/querycached.md)
* [上下文参数](Querying/query-context.md) * [上下文参数](querying/query-context.md)
* [原生查询类型](Querying/timeseriesquery.md) * [原生查询类型](querying/timeseriesquery.md)
* [Timeseries](Querying/timeseriesquery.md) * [Timeseries](querying/timeseriesquery.md)
* [TopN](Querying/topn.md) * [TopN](querying/topn.md)
* [GroupBy](Querying/groupby.md) * [GroupBy](querying/groupby.md)
* [Scan](Querying/scan.md) * [Scan](querying/scan.md)
* [Search](Querying/searchquery.md) * [Search](querying/searchquery.md)
* [TimeBoundary](Querying/timeboundaryquery.md) * [TimeBoundary](querying/timeboundaryquery.md)
* [SegmentMetadata](Querying/segmentMetadata.md) * [SegmentMetadata](querying/segmentMetadata.md)
* [DatasourceMetadata](Querying/datasourcemetadataquery.md) * [DatasourceMetadata](querying/datasourcemetadataquery.md)
* [原生查询组件](Querying/filters.md) * [原生查询组件](querying/filters.md)
* [过滤](Querying/filters.md) * [过滤](querying/filters.md)
* [粒度](Querying/granularity.md) * [粒度](querying/granularity.md)
* [维度](Querying/dimensionspec.md) * [维度](querying/dimensionspec.md)
* [聚合](Querying/Aggregations.md) * [聚合](querying/Aggregations.md)
* [后聚合](Querying/postaggregation.md) * [后聚合](querying/postaggregation.md)
* [表达式](Querying/expression.md) * [表达式](querying/expression.md)
* [Having(GroupBy)](Querying/having.md) * [Having(GroupBy)](querying/having.md)
* [排序和Limit(GroupBy)](Querying/limitspec.md) * [排序和Limit(GroupBy)](querying/limitspec.md)
* [排序(TopN)](Querying/topnsorting.md) * [排序(TopN)](querying/topnsorting.md)
* [字符串比较器(String Comparators)](Querying/sorting-orders.md) * [字符串比较器(String Comparators)](querying/sorting-orders.md)
* [虚拟列(Virtual Columns)](Querying/virtual-columns.md) * [虚拟列(Virtual Columns)](querying/virtual-columns.md)
* [空间过滤器(Spatial Filter)](Querying/spatialfilter.md) * [空间过滤器(Spatial Filter)](querying/spatialfilter.md)
* [配置列表]() * [配置列表]()
* [配置列表](Configuration/configuration.md) * [配置列表](Configuration/configuration.md)

View File

@ -39,6 +39,6 @@ org.apache.druid.cli.Main server historical
### 查询段 ### 查询段
有关查询Historical的详细信息请参阅 [数据查询](../Querying/makeNativeQueries.md)。 有关查询Historical的详细信息请参阅 [数据查询](../querying/makeNativeQueries.md)。
Historical可以被配置记录和报告每个服务查询的指标。 Historical可以被配置记录和报告每个服务查询的指标。

View File

@ -132,7 +132,7 @@ Druid的体系结构需要一个主时间列内部存储为名为__time的列
![](img-2/tutorial-kafka-data-loader-12.png) ![](img-2/tutorial-kafka-data-loader-12.png)
查看[查询教程](../Querying/makeNativeQueries.md)以对新加载的数据运行一些示例查询。 查看[查询教程](../querying/makeNativeQueries.md)以对新加载的数据运行一些示例查询。
#### 通过控制台提交supervisor #### 通过控制台提交supervisor

View File

@ -284,5 +284,5 @@ curl -X 'POST' -H 'Content-Type:application/json' -d @quickstart/tutorial/wikipe
### 进一步阅读 ### 进一步阅读
[查询文档](../Querying/makeNativeQueries.md)有更多关于Druid原生JSON查询的信息 [查询文档](../querying/makeNativeQueries.md)有更多关于Druid原生JSON查询的信息
[Druid SQL文档](../Querying/druidsql.md)有更多关于Druid SQL查询的信息 [Druid SQL文档](../querying/druidsql.md)有更多关于Druid SQL查询的信息

View File

@ -91,7 +91,7 @@ Druid的体系结构需要一个主时间列内部存储为名为__time的列
运行 `SELECT * FROM wikipedia` 查询可以看到详细的结果。 运行 `SELECT * FROM wikipedia` 查询可以看到详细的结果。
查看[查询教程](../Querying/makeNativeQueries.md)以对新加载的数据运行一些示例查询。 查看[查询教程](../querying/makeNativeQueries.md)以对新加载的数据运行一些示例查询。
### 使用spec加载数据通过控制台 ### 使用spec加载数据通过控制台