转载自http://yangyangmyself.iteye.com/blog/2321759
1、Druid 查询概述
    上一节完成数据导入后,接下来讲讲Druid如何查询及统计分析导入的数据。
    Druid的查询是使用REST风格的HTTP请求查询服务节点(Broker、Historical、Realtime),这些服务节点暴露REST查询接口,客户端发送Json对象请求查询接口。一般情况下,查询服务接口发布在Broker节点,基于Linux 的POST请求查询如下所示: 
  1. /**
  2. * port: 查询请求接口对应Broker,默认8082端口
  3. * query_json_file: 查询Json对象文件(配置)
  4. */
  5. curl -X POST '<queryable_host>:<port>/druid/v2/?pretty' -H 'Content-Type:application/json' -d @<query_json_file>
2、Druid 查询类型
     Druid在不同场景下,有很多的查询类型。查询是由各种JSON属性和Druid有不同类型的不同场景下查询组成。对于各种类型的查询类型的配置可以json属性文件设置。Druid查询类型,概括一下为3大类:
     1. 聚合查询 - 时间序列查询(Timeseries)、排名查询(TopN)、分组查询(GroupBy)
     2. 元数据查询 - 时间范围(Time Boundary) 、段元数据(Segment Metadata)、数据源(Datasource)
     3. Search查询 - Search
     本节以聚合查询为主,其它查询类型比较简单,使用上相对比较少,暂不介绍。对聚合查询类型下的3种查询如何选择进行一下概述:
     在可能的情况下,我们建议使用的时间序列和TopN查询代替分组查询,分组查询是Druid最灵活的的查询,但是性能最差。时间序列查询是明显快于GROUPBY查询,因为聚合不需要分组尺寸。对于分组和排序在一个单一的维度,TopN查询更优于GROUPBY。
2.1 Json查询属性
在讲聚合查询下的3种查询类型之前,我们需要对3种查询类型共有的特别重要的Json属性理解与熟悉,常用属性如:queryType、dataSource、granularity、filter、aggregator等。
2.1.1 查询类型(queryType)
对应聚合查询下的3种类型值:timeseries、topN、groupBy
 
2.1.2 数据源(dataSource)
数据源,类似数据库中表的概念,对应数据导入时Json配置属性dataSource值
2.1.3 聚合粒度(granularity)
    粒度决定如何得到数据块在跨时间维度,或者如何得到按小时,天,分钟的汇总等。在配置查询聚合粒度里有三种配置方法:
    1. 简单聚合粒度 - 支持字符串值有:all、none、second、minute、fifteen_minute、thirty_minute、hour、day、week、month、quarter、year
       (1) all - 将所有块变成一块
       (2) none - 不使用块数据(它实际上是使用最小索引的粒度,none意味着为毫秒级的粒度);按时间序列化查询时不建议使用none,因为所有的毫秒不存在,系统也将尝试生成0值,这往往是很多。
    2. 时间段聚合粒度 - Druid指定一精确的持续时间(毫秒)和时间缀返回UTC(世界标准时间)。
    3. 常用时间段聚合粒度 - 与时间段聚合粒度差不多,但是常用时间指平时我们常用时间段,如年、月、周、小时等。
    下面对3种聚合粒度配置举例说明:

简单聚合粒度

        查询粒度比数据采集时配置的粒度小,则不合理,也无意义,因较小粒度(相比)者无索引数据;如
    查询粒度小于采集时配置的查询粒度时,则Druid的查询结果与采集数据配置的查询粒度结果一样。

假设我们存储在Druid的数据使用毫秒粒度获取,数据如下:

  1. {"timestamp": "2013-08-31T01:02:33Z", "page": "AAA", "language" : "en"}
  2. {"timestamp": "2013-09-01T01:02:33Z", "page": "BBB", "language" : "en"}
  3. {"timestamp": "2013-09-02T23:32:45Z", "page": "CCC", "language" : "en"}
  4. {"timestamp": "2013-09-03T03:32:45Z", "page": "DDD", "language" : "en"}

以"小时" 粒度提交一个groupby查询,查询配置如下:

  1. {
  2. "queryType":"groupBy",
  3. "dataSource":"dataSource",
  4. "granularity":"hour",
  5. "dimensions":[
  6. "language"
  7. ],
  8. "aggregations":[
  9. {
  10. "type":"count",
  11. "name":"count"
  12. }
  13. ],
  14. "intervals":[
  15. "2000-01-01T00:00Z/3000-01-01T00:00Z"
  16. ]
  17. }

按小时粒度进行的groupby查询结果中timestamp值精确到小时间,比小时粒度更小粒度值自动补填零,

以此类推按天查询,则小时及小粒度补零。timestamp值为UTC

  1. [ {
  2. "version" : "v1",
  3. "timestamp" : "2013-08-31T01:00:00.000Z",
  4. "event" : {
  5. "count" : 1,
  6. "language" : "en"
  7. }
  8. }, {
  9. "version" : "v1",
  10. "timestamp" : "2013-09-01T01:00:00.000Z",
  11. "event" : {
  12. "count" : 1,
  13. "language" : "en"
  14. }
  15. }, {
  16. "version" : "v1",
  17. "timestamp" : "2013-09-02T23:00:00.000Z",
  18. "event" : {
  19. "count" : 1,
  20. "language" : "en"
  21. }
  22. }, {
  23. "version" : "v1",
  24. "timestamp" : "2013-09-03T03:00:00.000Z",
  25. "event" : {
  26. "count" : 1,
  27. "language" : "en"
  28. }
  29. } ]

如果指定查询粒度为 none,则返回结果与数据导入时设置粒度(queryGranularity属性值)结果一样,
    此处的导入粒度为毫秒,结果如下:

  1. [ {
  2. "version" : "v1",
  3. "timestamp" : "2013-08-31T01:02:33.000Z",
  4. "event" : {
  5. "count" : 1,
  6. "language" : "en"
  7. }
  8. }, {
  9. "version" : "v1",
  10. "timestamp" : "2013-09-01T01:02:33.000Z",
  11. "event" : {
  12. "count" : 1,
  13. "language" : "en"
  14. }
  15. }, {
  16. "version" : "v1",
  17. "timestamp" : "2013-09-02T23:32:45.000Z",
  18. "event" : {
  19. "count" : 1,
  20. "language" : "en"
  21. }
  22. }, {
  23. "version" : "v1",
  24. "timestamp" : "2013-09-03T03:32:45.000Z",
  25. "event" : {
  26. "count" : 1,
  27. "language" : "en"
  28. }
  29. } ]

如果指定查询粒度为 all,返回数组长度结果为1,结果如下:

  1. [ {
  2. "version" : "v1",
  3. "timestamp" : "2000-01-01T00:00:00.000Z",
  4. "event" : {
  5. "count" : 4,
  6. "language" : "en"
  7. }
  8. } ]

时间段聚合粒度

指定一个精确时间持续时长(毫秒表示)及时间缀,返回UTC时间;支持可选项属性origin,不指定时 
     默认开始时间(1970-01-01T00:00:00Z)

  1. /**持续时间段2小时,从1970-01-01T00:00:00Z开始*/
  2. {"type": "duration", "duration": 7200000}
  1. /**持续时间1小时,从origin开始*/
  2. {"type": "duration", "duration": 3600000, "origin": "2012-01-01T00:30:00Z"}

以上简单聚合粒度的示例数据为例,提交groupby查询,持续时间段为24小时,查询配置如下:

  1. {
  2. "queryType":"groupBy",
  3. "dataSource":"dataSource",
  4. "granularity":{"type": "duration", "duration": "86400000"},
  5. "dimensions":[
  6. "language"
  7. ],
  8. "aggregations":[
  9. {
  10. "type":"count",
  11. "name":"count"
  12. }
  13. ],
  14. "intervals":[
  15. "2000-01-01T00:00Z/3000-01-01T00:00Z"
  16. ]
  17. }

查询结果:

  1. [ {
  2. "version" : "v1",
  3. "timestamp" : "2013-08-31T00:00:00.000Z",
  4. "event" : {
  5. "count" : 1,
  6. "language" : "en"
  7. }
  8. }, {
  9. "version" : "v1",
  10. "timestamp" : "2013-09-01T00:00:00.000Z",
  11. "event" : {
  12. "count" : 1,
  13. "language" : "en"
  14. }
  15. }, {
  16. "version" : "v1",
  17. "timestamp" : "2013-09-02T00:00:00.000Z",
  18. "event" : {
  19. "count" : 1,
  20. "language" : "en"
  21. }
  22. }, {
  23. "version" : "v1",
  24. "timestamp" : "2013-09-03T00:00:00.000Z",
  25. "event" : {
  26. "count" : 1,
  27. "language" : "en"
  28. }
  29. } ]

    常用时间段聚合粒度

         略...

2.1.4 过滤(Filters)
一个Filter就是一个Json对象,用于过滤数据行过滤,类似SQL中的Where子句。过滤器类型有如下:Selector filte、Regular expression filter(正则表达式过滤)、Logical expression filters(AND、OR、NOT)、In filter、Bound filter、Search filter、JavaScript filter、Extraction filter

示例简单查看使用方式:

   查询过滤(Selector filte)

等价于:WHERE <dimension_string> = '<dimension_value_string>'

  1. "filter": { "type": "selector", "dimension": <dimension_string>, "value": <dimension_value_string> }

    正则表达过滤(Regular expression filter)

与Selector filte差不多,只是这里使用正则表达式,表达式为标准的Java正则表达式规范

  1. "filter": { "type": "regex", "dimension": <dimension_string>, "pattern": <pattern_string> }

逻缉表达过滤(Logical expression filters)

AND

  1. "filter": { "type": "and", "fields": [<filter>, <filter>, ...] }

OR

  1. "filter": { "type": "or", "fields": [<filter>, <filter>, ...] }

NOT

  1. "filter": { "type": "not", "field": <filter> }

IN过滤(In filter)

SQL查询

  1. SELECT COUNT(*) AS 'Count' FROM `table` WHERE `outlaw` IN ('Good', 'Bad', 'Ugly')
    Druid IN 过滤表示

  1. {
  2. "type": "in",
  3. "dimension": "outlaw",
  4. "values": ["Good", "Bad", "Ugly"]
  5. }

 范围过滤(Bound filter)

Bound filter 过滤比较值大小或小于某值,默认按字符串比较,使用数据比较需要设置alphaNumeric 属
     性为true;默认 Bound filter为非严格性(类闭区间),如 inputString <= upper && inputSting >= lower

  1. {
  2. "type": "bound",
  3. "dimension": "age",
  4. "lower": "21",
  5. "upper": "31" ,
  6. "alphaNumeric": true
  7. }

上述表示等价如:21 <= age <= 31

Bound filter 严格性,需要设置lowerStrict or/and upperStrict 属性值为true如下:

  1. {
  2. "type": "bound",
  3. "dimension": "age",
  4. "lower": "21",
  5. "lowerStrict": true,
  6. "upper": "31" ,
  7. "upperStrict": true,
  8. "alphaNumeric": true
  9. }

等价如:21 < age < 31

2.1.5 聚合(Aggregations)
   聚合可以在采集时间时规格部分的一种方式,汇总数据进入Druid之前提供。聚合也可以被指定为在查询时多查询的部分,聚合类型如下:Count aggregator、Sum aggregators、Min / Max aggregators、Approximate Aggregations、Miscellaneous Aggregations 

Count aggregator

          

        查询返回匹配过滤条件的数据行数,需要注意的是:Druid进行Count查询的数据量并不一定等于数据采
    集时导入的数据量,因为Druid在采集数据并导入时已经对数据进行了聚合。

  1. { "type" : "count", "name" : <output_name> }

    Sum aggregator

longSum aggregator:计算值为有符号位64位整数

  1. { "type" : "longSum", "name" : <output_name>, "fieldName" : <metric_name> }

  doubleSum aggregator:与longSum类似,计算值为64位浮点型

  1. { "type" : "doubleSum", "name" : <output_name>, "fieldName" : <metric_name> }

Min / Max aggregators

          doubleMin aggregator

  1. { "type" : "doubleMin", "name" : <output_name>, "fieldName" : <metric_name> }

    

          doubleMax aggregator

  1. { "type" : "doubleMax", "name" : <output_name>, "fieldName" : <metric_name> }

 

          longMin aggregator

  1. { "type" : "longMin", "name" : <output_name>, "fieldName" : <metric_name> }

 

         longMax aggregator

  1. { "type" : "longMax", "name" : <output_name>, "fieldName" : <metric_name> }

类似聚合(Approximate Aggregations)

基数聚合(Cardinality aggregator)

计算Druid多种维度基数,Cardinality aggregator使用HyperLogLog评估基数,这种聚合比带有索引的
     hyperUnique聚合慢,运行在一个维度列,意味着不能从数据集中删除字符串维度来提高聚合;一般我们
     强力推荐使用hyperUnique aggregator而不是Cardinality aggregator,格式如下:

  1. {
  2. "type": "cardinality",
  3. "name": "<output_name>",
  4. "fieldNames": [ <dimension1>, <dimension2>, ... ],
  5. "byRow": <false | true> # (optional, defaults to false)
  6. }

维度值聚合-当设置属性byRow为false(默认值)时,通过合并所有给定的维度列来计算值集合。

对于单维度,等价如下:

  1. SELECT COUNT(DISTINCT(dimension)) FROM <datasource>

对于多维度,等价如下:

  1. SELECT COUNT(DISTINCT(value)) FROM (
  2. SELECT dim_1 as value FROM <datasource>
  3. UNION
  4. SELECT dim_2 as value FROM <datasource>
  5. UNION
  6. SELECT dim_3 as value FROM <datasource>
  7. )

行聚合-当设置属性byRow为true时,根所不同维度的值合并来计算行值,等价如下:

  1. SELECT COUNT(*) FROM ( SELECT DIM1, DIM2, DIM3 FROM <datasource> GROUP BY DIM1, DIM2, DIM3 )

许多不同国家的人出生地或来自哪里,用druid配置如下:

  1. {
  2. "type": "cardinality",
  3. "name": "distinct_countries",
  4. "fieldNames": [ "coutry_of_origin", "country_of_residence" ]
  5. }

HyperUnique aggregator

已经被“hyperunique”在创建索引时聚合的维度值使用HyperLogLog计算估计,更多资料请参考官网

  1. { "type" : "hyperUnique", "name" : <output_name>, "fieldName" : <metric_name> }
后聚合(post-aggregators)
后聚合是对Druid进行聚合后的值进行聚全,如果查询中包括一个后聚合,那么确保所有聚合满足后聚合要求;后聚合有以下几种类型:
1. Arithmetic post-aggregators
2. Field accessor post-aggregator
3. Constant post-aggregator
4. JavaScript post-aggregator
5. HyperUnique Cardinality post-aggregator

Arithmetic post-aggregators

算术后聚合应用已提供的函数从左到右获取字段,这些字段可聚合或后聚合;支持+-*/, and quotient。

算术后聚合可以指定ordering属性,用于聚合结果排序(对topN查询很有用 ):

(1) 如果无ordering属性(或null),使用默认的浮点排序。

(2) numericFirst 首先返回有限值,其次是NaN,最后返回无限值。

算术后聚合语法如下:

  1. postAggregation : {
  2. "type"  : "arithmetic",
  3. "name"  : <output_name>,
  4. "fn"    : <arithmetic_function>,
  5. "fields": [<post_aggregator>, <post_aggregator>, ...],
  6. "ordering" : <null (default), or "numericFirst">
  7. }

 Field accessor post-aggregator - fieldName引用aggregator定义的名称

  1. { "type" : "fieldAccess", "name": <output_name>, "fieldName" : <aggregator_name> }

Constant post-aggregator - 返回指定值

  1. { "type"  : "constant", "name"  : <output_name>, "value" : <numerical_value> }
2.2 时间序列查询(Timeseries)
      这些类型的查询以时间序列查询对象和返回一个JSON数组对象,每个对象表示时间序列查询的值,时间序列查询请求的Json的7个主要属性如下:

属性 描述 必填项
queryType 字符串类型,时间序列 "timeseries"    是
dataSource 字符串类型,数据源(类似数据库表)    是
descending 排序标志,默认为 "false"(升序)    否
intervals 查询时间范围跨度,JSON对象,ISO-8601区间    是
granularity 定义查询结果块粒度    是
filter 过滤条件    否
aggregations 聚合    是
postAggregations 后聚合    否
context 下文    否
  1. {
  2. "queryType": "timeseries",
  3. "dataSource": "sample_datasource",
  4. "granularity": "day",
  5. "descending": "true",
  6. "filter": {
  7. "type": "and",
  8. "fields": [
  9. { "type": "selector", "dimension": "sample_dimension1", "value": "sample_value1" },
  10. { "type": "or",
  11. "fields": [
  12. { "type": "selector", "dimension": "sample_dimension2", "value": "sample_value2" },
  13. { "type": "selector", "dimension": "sample_dimension3", "value": "sample_value3" }
  14. ]
  15. }
  16. ]
  17. },
  18. "aggregations": [
  19. { "type": "longSum", "name": "sample_name1", "fieldName": "sample_fieldName1" },
  20. { "type": "doubleSum", "name": "sample_name2", "fieldName": "sample_fieldName2" }
  21. ],
  22. "postAggregations": [
  23. { "type": "arithmetic",
  24. "name": "sample_divide",
  25. "fn": "/",
  26. "fields": [
  27. { "type": "fieldAccess", "name": "postAgg__sample_name1", "fieldName": "sample_name1" },
  28. { "type": "fieldAccess", "name": "postAgg__sample_name2", "fieldName": "sample_name2" }
  29. ]
  30. }
  31. ],
  32. "intervals": [ "2012-01-01T00:00:00.000/2012-01-03T00:00:00.000" ]
  33. }

上述配置了过滤条件,2个聚合,后聚合器将2个聚合结果进行相除。查询结果如下,查询结果存储在属性result,以键值对方式存储:

  1. [
  2. {
  3. "timestamp": "2012-01-01T00:00:00.000Z",
  4. "result": { "sample_name1": <some_value>, "sample_name2": <some_value>, "sample_divide": <some_value> }
  5. },
  6. {
  7. "timestamp": "2012-01-02T00:00:00.000Z",
  8. "result": { "sample_name1": <some_value>, "sample_name2": <some_value>, "sample_divide": <some_value> }
  9. }
  10. ]
2.3 排名查询(TopN query)
    TopN查询根据规范返回给定维度的有序的结果集,从概念上来讲,TopN查询被认为单维度、有序的类似分组查询。在某些情况下,TopN查询比分组查询(groupby query)快。TopN查询结果返回Json数组对象。
    TopN在每个节点将顶上K个结果排名,在Druid默认情况下最大值为1000。在实践中,如果你要求前1000个项顺序排名,那么从第1-999个项的顺序正确性是100%,其后项的结果顺序没有保证。你可以通过增加threshold值来保证顺序准确。

属性 描述 必填项
queryType 字符串类型,时间序列 "topN"    是
dataSource 字符串类型,数据源(类似数据库表)    是
intervals 查询时间范围跨度,JSON对象,ISO-8601区间    是
granularity 定义查询结果块粒度    是
filter 过滤条件    否
aggregations 聚合    是
postAggregations 后聚合    否
dimension 查询的维度(列)    是
threshold 返回Top N个结果    是
metric 字符串或Json对象指定度量对Top N个结果排序    是
context 上下文    否

Metric
属性 描述 必填项
type 数字排序    是
metric 排序字段    是

数据排序(Numeric TopNMetricSpec - 最简单的规范指定一个字符串值指示排序TopN结果的度量

  1. "metric": "<metric_name>"

metric属性通常配置为Json对象,上述等价于:

  1. "metric": {
  2. "type": "numeric",
  3. "metric": "<metric_name>"
  4. }

topN query 配置示例如下:

  1. {
  2. "queryType": "topN",
  3. "dataSource": "sample_data",
  4. "dimension": "sample_dim",
  5. "threshold": 5,
  6. "metric": "count",
  7. "granularity": "all",
  8. "filter": {
  9. "type": "and",
  10. "fields": [
  11. {
  12. "type": "selector",
  13. "dimension": "dim1",
  14. "value": "some_value"
  15. },
  16. {
  17. "type": "selector",
  18. "dimension": "dim2",
  19. "value": "some_other_val"
  20. }
  21. ]
  22. },
  23. "aggregations": [
  24. {
  25. "type": "longSum",
  26. "name": "count",
  27. "fieldName": "count"
  28. },
  29. {
  30. "type": "doubleSum",
  31. "name": "some_metric",
  32. "fieldName": "some_metric"
  33. }
  34. ],
  35. "postAggregations": [
  36. {
  37. "type": "arithmetic",
  38. "name": "sample_divide",
  39. "fn": "/",
  40. "fields": [
  41. {
  42. "type": "fieldAccess",
  43. "name": "some_metric",
  44. "fieldName": "some_metric"
  45. },
  46. {
  47. "type": "fieldAccess",
  48. "name": "count",
  49. "fieldName": "count"
  50. }
  51. ]
  52. }
  53. ],
  54. "intervals": [
  55. "2013-08-31T00:00:00.000/2013-09-03T00:00:00.000"
  56. ]
  57. }

查询前Top 5个结果,按count排序:

  1. [
  2. {
  3. "timestamp": "2013-08-31T00:00:00.000Z",
  4. "result": [
  5. {
  6. "dim1": "dim1_val",
  7. "count": 111,
  8. "some_metrics": 10669,
  9. "average": 96.11711711711712
  10. },
  11. {
  12. "dim1": "another_dim1_val",
  13. "count": 88,
  14. "some_metrics": 28344,
  15. "average": 322.09090909090907
  16. },
  17. {
  18. "dim1": "dim1_val3",
  19. "count": 70,
  20. "some_metrics": 871,
  21. "average": 12.442857142857143
  22. },
  23. {
  24. "dim1": "dim1_val4",
  25. "count": 62,
  26. "some_metrics": 815,
  27. "average": 13.14516129032258
  28. },
  29. {
  30. "dim1": "dim1_val5",
  31. "count": 60,
  32. "some_metrics": 2787,
  33. "average": 46.45
  34. }
  35. ]
  36. }
  37. ]

【转载】DRuid 大数据分析之查询的更多相关文章

  1. Impala:新一代开源大数据分析引擎--转载

    原文地址:http://www.parallellabs.com/2013/08/25/impala-big-data-analytics/ 文 / 耿益锋 陈冠诚 大数据处理是云计算中非常重要的问题 ...

  2. Druid:一个用于大数据实时处理的开源分布式系统——大数据实时查询和分析的高容错、高性能开源分布式系统

    转自:http://www.36dsj.com/archives/28590 Druid 是一个用于大数据实时查询和分析的高容错.高性能开源分布式系统,旨在快速处理大规模的数据,并能够实现快速查询和分 ...

  3. [druid]大数据挑战——如何使用Druid实现数据聚合

    -- 知道你为什么惧组件很多的一些开源软件? 因为缺乏阅读能力. 最近我接手了druid+kafka+elk一套等日志系统. 但是我对druid很陌生, 周旋了几天, 官网文档快速开始照着做了下. 看 ...

  4. 大数据分析界的“神兽”Apache Kylin有多牛?【转】

    本文作者:李栋,来自Kyligence公司,也是Apache Kylin Committer & PMC member,在加入Kyligence之前曾就职于eBay.微软. 1.Apache ...

  5. Splunk大数据分析经验分享

    转自:http://www.freebuf.com/articles/database/123006.html Splunk大数据分析经验分享:从入门到夺门而逃 Porsche 2016-12-19 ...

  6. 使用Kylin构建企业大数据分析平台的4种部署方式

    本篇博客重点介绍如何使用Kylin来构建大数据分析平台.根据官网介绍,其实部署Kylin非常简单,称为非侵入式安装,也就是不需要去修改已有的 Hadoop大数据平台.你只需要根据的环境下载适合的Kyl ...

  7. 《基于Apache Kylin构建大数据分析平台》

    Kyligence联合创始人兼CEO,Apache Kylin项目管理委员会主席(PMC Chair)韩卿 武汉市云升科技发展有限公司董事长,<智慧城市-大数据.物联网和云计算之应用>作者 ...

  8. 《开源大数据分析引擎Impala实战》目录

    当当网图书信息: http://product.dangdang.com/23648533.html <开源大数据分析引擎Impala实战>目录 第1章  Impala概述.安装与配置.. ...

  9. 【转】使用Apache Kylin搭建企业级开源大数据分析平台

    http://www.thebigdata.cn/JieJueFangAn/30143.html 本篇文章整理自史少锋4月23日在『1024大数据技术峰会』上的分享实录:使用Apache Kylin搭 ...

随机推荐

  1. Xamarin.Forms 开发资源集合

    收集整理了下 Xamarin.Forms 的学习参考资料,分享给大家,稍后会不断补充: UI样式 Snppts: Xamarin Forms UI Snippets. Prebuilt Templat ...

  2. bootstrap表格添加按钮、模态框实现

    bootstrap表格添加按钮.模态框实现 原创 2017年07月20日 17:35:48 标签: bootstrap 1723 bootstrap表格添加按钮.模态框实现 - 需求: 需要表格后面每 ...

  3. POJ 1390 Blocks(区间DP)

    Blocks [题目链接]Blocks [题目类型]区间DP &题意: 给定n个不同颜色的盒子,连续的相同颜色的k个盒子可以拿走,权值为k*k,求把所有盒子拿完的最大权值 &题解: 这 ...

  4. docker 标记和推送镜像

    打开Launchpad并定位到docker Quickstart Terminal图标. 点击Docker Quickstart Terminal图标, 打开一个窗口. 将光标定位到Docker Qu ...

  5. oracle - 查询某些表是空白,需要提升权限后,才可查询出数据

    begin fnd_global.apps_initialize(user_id => 1150 ,resp_id => 50738 ,resp_appl_id => 660 ); ...

  6. Java-线程间通信小结

    1)方法wait的作用是使当前执行代码的线程进行等待,将当前线程置入预执行队列,并且在wait所在代码行处停止执行,直到接到通知或者中断.在wait之前,要获得一个对象锁,即wait只能在同步方法/块 ...

  7. Java面试题整理---Redis篇

    1.redis支持五种数据结构类型?   2.redis内部结构?   3.redis持久化机制?   4.redis集群方案与实现?   5.redis为什么是单线程的?   6.redis常见回收 ...

  8. 使用google earth engine根据NDWI(归一化水指数)提取水体信息

    交流合作请联系: ab000c@163.com

  9. Java EE开发技术课程

    新的学期开始了,j2e已经上了两节课,接下来就是对该课程的一些作业以及相关的认识: 一.课程目标: Java EE是java的企业级应用,所以在我看来在学习这门课程之前肯定要对java有一个具体的认识 ...

  10. Connector for Python

    连接mysql, 需要mysql connector, conntector是一种驱动程序,python连接mysql的驱动程序,mysql官方给出的名称为connector/python, 可参考m ...