MySQL using having

MySQL using having http://wuzhangshu927.blog.163.com/blog/static/1142246872010113093426574/ USING() using 可用在 join 语句相同字段连接, 起到和 ON 相同作用, inner join 和 left join 中都可以使用 LEFT JOIN 正常写法: SELECT t1.id,t2.name FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE .... 其实也可以这么写: SELECT t1.id,t2.name FROM t1 LEFT JOIN t2 USING(id) WHERE .... HAVING MySQL 中的 where 和 having 子句都可以实现筛选记录的功能, having 可以认为是对 where 的补充, 因为它可以对分组数据进行再次判断, 一般跟在 group by 后面, 并可以使用聚集函数 (sum, min, max, avg, count) SELECT `uid`, SUM(`points`) num FROM table GROUP BY `uid` HAVING num > 1000

2017-11-22 · 1 min · 78 words · -

grpc

python grpc grpcio==1.48.2 grpc 会忽略 linux 环境变量 里配置的 no_proxy, 导致请求失败, 在启动客户端之前 临时删除环境变量 unset HTTP_PROXY golang grpc gRPC 通过 HTTP2 协议传输 定义协议 protobuf syntax = "proto3"; message SearchRequest { string query = 1; int32 page_number = 2; int32 results_per_page = 3; } 生成 python 文件 python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. logServer.proto python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. .\tests\remote\grpc_wrapper\service.proto golang grpc install protocol compiler plugins 在 https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go 可以看到最新的版本号 go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.1 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0 # 安装后查看 版本 ./protoc-gen-go --version ./protoc-gen-go-grpc --version protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ helloworld/helloworld.proto protoc -I proto/ proto/helloworld.proto -go_out=plugins=grpc:proto grpc-dump go install github.com/bradleyjkemp/grpc-tools/grpc-dump@latest grpc-dump --port=12345 http_proxy=http://localhost:12345 my-app wireshark grpc https://mp.weixin.qq.com/s/BdcFRO58ytrtcpYZVT1ymQ ...

2017-09-07 · 1 min · 133 words · -

influxdb basic

influxdb basic influxdb v2 install docker compose yaml # compose.yaml services: influxdb2: image: influxdb:2.7.10-alpine ports: - 8086:8086 environment: DOCKER_INFLUXDB_INIT_MODE: setup DOCKER_INFLUXDB_INIT_USERNAME_FILE: /run/secrets/influxdb2-admin-username DOCKER_INFLUXDB_INIT_PASSWORD_FILE: /run/secrets/influxdb2-admin-password DOCKER_INFLUXDB_INIT_ADMIN_TOKEN_FILE: /run/secrets/influxdb2-admin-token DOCKER_INFLUXDB_INIT_ORG: docs DOCKER_INFLUXDB_INIT_BUCKET: home secrets: - influxdb2-admin-username - influxdb2-admin-password - influxdb2-admin-token volumes: - type: volume source: influxdb2-data target: /var/lib/influxdb2 - type: volume source: influxdb2-config target: /etc/influxdb2 secrets: influxdb2-admin-username: file: ~/.env.influxdb2-admin-username influxdb2-admin-password: file: ~/.env.influxdb2-admin-password influxdb2-admin-token: file: ~/.env.influxdb2-admin-token volumes: influxdb2-data: influxdb2-config: sudo docker compose -f influxdb-compose.yaml up influxdb2 influxdb http api # http api curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "q=show databases" curl -i -XPOST http://localhost:8086/query --data-urlencode "db=mydb" --data-urlencode "q=CREATE DATABASE db0" curl -i -XPOST "http://192.168.97.1:8086/write?db=monitor" --data-binary 'measurement_0,location=us-midwest temperature=82 1594349970000000000' curl -x http://127.0.0.1:8899/ -i -XPOST "http://192.168.97.1:8086/write?db=monitor" --data-binary 'measurement_0,location=us-midwest temperature=86 1594349970000000000' database management #show db show databases # 创建数据库,同时配置retention policy # DURATION: 数据生命周期 30天 # SHARD DURATION: 分片周期 1小时 # NAME: retention policies 名 CREATE DATABASE "database0" WITH DURATION 30d REPLICATION 1 SHARD DURATION 1h NAME "default" # create db # 数据库名不能包含"-", 可以用"_" create database db0 drop database db0 insert -- float value INSERT measurement0,tag0=tag_value0 field0=1,field1=field_value1 -- int value INSERT measurement0,tag0=tag_value0 field0=1i,field1=field_value1 -- with time INSERT measurement0,tag0=tag_value0 field0=1,field1=field_value1 1570611600000000000 delete DELETE FROM measurement0 WHERE tag0=tag_value0 导出 influx -database 'db0' -execute "select field0,\"field1\" from measurement0 where tag-name0='tag-value0' and time>'2018-05-05 02:00:00' and time<'2018-05-07 11:00:00' order by time tz('Etc/GMT-8')" -format 'csv' -precision 'rfc3339' > xxx.csv # 使用 tz('Etc/GMT-8') 后,过滤条件中的time>'xxx' 填写东8区时间. 安装, influxdb install & config dnf sudo tee /etc/yum.repos.d/influxdb.repo<<EOF [influxdb] name = InfluxDB Repository baseurl = https://repos.influxdata.com/rhel/7/x86_64/stable/ enabled = 1 gpgcheck = 1 gpgkey = https://repos.influxdata.com/influxdb.key EOF dnf install influxdb vim /etc/influxdb/influxdb.conf systemctl enable influxdb # install # archlinux yay -S influxdb # centos # https://www.influxdata.com/blog/package-repository-for-linux/ sudo yum install influxdb sudo yum localinstall influxdb-1.2.4.x86_64.rpm # for Linux Binaries (64-bit) tar xvfz influxdb-1.3.1_linux_amd64.tar.gz rsync -r /path/to/influxdb-1.2.4-1/ / #edit config file emacs /etc/influxdb/influxdb.conf /etc/influxdb/influxdb.conf #reporting-disabled = false [meta] dir = "/var/lib/influxdb/influxdb/meta" #retention-autocreate = true [data] dir = "/var/lib/influxdb/influxdb/data" wal-dir = "/var/lib/influxdb/influxdb/wal" wal-fsync-delay = "100ms" # index-version = "inmem" index-version = "tsi1" trace-logging-enabled = false query-log-enabled = true cache-max-memory-size = "512m" cache-snapshot-memory-size = "32m" # 超过10分钟没有写入, 把cache写到新的TSM文件 cache-snapshot-write-cold-duration = "10m" [coordinator] #慢查询 log-queries-after = "10s" [retention] #edit file /etc/default/influxdb STDERR=/data/logs/influxdb/influxdb.log #edit logrotate config, modify log path /etc/logrotate.d/influxdb # chown chown influxdb:influxdb /data/influxdb/ chown influxdb:influxdb /data/logs/influxdb/ #start systemctl start influxdb #or sudo influxd #connect via cli, rfc3339: 日期格式YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ influx -precision rfc3339 docker docker pull influxdb:2.7.10-alpine docker run -d \ --name influxdb \ -p 8086:8086 \ -v "influxdb-data:/var/lib/influxdb2" \ -v "influxdb-config:/etc/influxdb2" \ influxdb:2.7.10-alpine # docker docker run -d \ --name influxdb \ --net net0 \ --ip 192.168.1.xxx \ -p 8086:8086 \ -p 8083:8083 \ -v influxdb-config:/etc/influxdb:ro \ -v influxdb-storage:/var/lib/influxdb \ -v /etc/localtime:/etc/localtime:ro \ influxdb # podman podman run -d \ --name influxdb \ -p 8086:8086 \ -p 8083:8083 \ -p 25826:25826 \ -v influxdb-config:/etc/influxdb:ro \ -v influxdb-storage:/var/lib/influxdb \ -v /etc/localtime:/etc/localtime:ro \ influxdb:1.8.10-alpine # in pod podman run -d \ --name influxdb \ --pod monitor \ -v influxdb-config:/etc/influxdb:ro \ -v influxdb-storage:/var/lib/influxdb \ -v /etc/localtime:/etc/localtime:ro \ influxdb chronograf podman run -d \ --name chronograf \ --pod monitor \ -v chronograf:/var/lib/chronograf \ -v /etc/localtime:/etc/localtime:ro \ chronograf --influxdb-url=http://monitor:8086 run influx sudo podman exec -it influxdb influx sudo podman run -it --rm influxdb influx -host influxdb.wiloon.com retention policies show retention policies show retention policies on db0 CREATE RETENTION POLICY "default" ON db0 DURATION 30d REPLICATION 1 SHARD DURATION 1d DEFAULT # ALTER RETENTION POLICY "<policy name>" ON <database> DURATION <duration> REPLICATION 1 SHARD DURATION <shard group duration> DEFAULT ALTER RETENTION POLICY "default" ON db0 DURATION 3h REPLICATION 1 SHARD DURATION 1h DEFAULT # policy name: retention policy 名: default # database: 库名 # duration 3h: 保留3个小时的数据 # shard group duration 1h: 每1个小时的数据一个分片 # DEFAULT: 设置此策略为默认策略 shard list shard id show shards DROP SHARD <shard_id_number> measurement show measurements DROP MEASUREMENT <measurement_name> DROP MEASUREMENT "kernel" select select * from ping where time > now()-1s select average_response_ms from ping where time > now()-1s and url='192.168.53.8' select "database",id,retentionPolicy,seriesCreate,writeReq from "shard" WHERE time>now()-20s AND "database"='database0' AND retentionPolicy='default' AND writeReq>0 select * from "database0"."rentention-policies-0"."measurement0" sELECT mean(m1) * 10 FROM metric0."default".m0 WHERE time >= now() - 10m AND host='host0' GROUP BY time(10s), host influx influx -execute 'select * from "database0"."retention_policies_0"."measurement0" order by time desc limit 1' # show tag keys SHOW TAG KEYS [ON <database_name>] [FROM_clause] [WHERE <tag_key> <operator> ['<tag_value>' | <regular_expression>]] [LIMIT_clause] [OFFSET_clause] show tag keys show tag keys on db0 from measurements0 show tag values on db0 from measure0 with key="host" SHOW FIELD KEYS [ON <database_name>] [FROM <measurement_name>] show tag values from cpu with key=host where service_name=~/xxx/ influx -precision rfc3339 select * from m0 where tag0='tag-value0' and time > '2018-05-16 13:00:00' and time < '2018-05-16 13:01:00' tz('Etc/GMT-8') #use use db0 drop series from series_name select f0,f1 from s0 where t0=~/xxx.*/ ERR: error parsing query: found /, expected regex at line 1, char 56 # =~和后面的正则表达式之间要有空格T_T select f0,f1 from s0 where t0=~ /xxx.*/ 协议, 整数, 浮点数 浮点数 —— 默认是浮点数,InfluxDB假定收到的所有field value都是浮点数。 以浮点类型存储上面的82: ...

2017-08-02 · 4 min · 819 words · -

时间序列数据库

时间序列数据库 存储大量时间相关的数据(如日志,用户行为等) 创造了一种新型的数据库分类——时间序列数据库(Time Series Database). 时间序列数据库主要用于指处理带时间标签 (按照时间的顺序变化,即时间序列化)的数据,带时间标签的数据也称为时间序列数据。 influxdb influxdb是最新的一个时间序列数据库,最新一两年才产生,但已经拥有极高的人气。influxdb 是用Go写的,现在v0.9正在开发中,之前开源出来的最稳定的版本是0.88的,但是0.8X是没有集群方案的,但在0.9中会加入进来。 0.9版本的influxdb对于之前会有很大的改变,后端存储有LevelDB换成了BoltDB,读写的API也是有了很大的变化,也将支持集群化,continuous query,支持retention policy,读写性能也是哇哇的,可以说是时间序列存储的完美方案,但是由于还很年轻,可能还会存在诸多的问题,就像现在正在开发的0.9一样,发布一拖再拖,就是由于还有些技术壁垒没有攻陷。 对于influxdb我不想多说些什么,之后打算开一个专题,专门详细来说一说这个玩意,因为我看国内几乎没有详细的文章来讲influxdb的。 http://www.opscoder.info/tsdb.html 对于时间序列的存储,一般会采用专门的时间序列数据库,而不会去使用MySQL或是mongo(但zabbix就是用的MySQL,所以它在IO上面遇到了瓶颈)。现在时间序列的数据库是有很多的,比如graphite、opentsdb以及新生的influxdb。最近也相继研究了一下这三个数据库,现在把研究所得记录下来。 特性: 高效的时间序列数据写入性能。自定义TSM引擎,快速数据写入和高效数据压缩。 无额外存储依赖。 简单,高性能的HTTP查询和写入API。 以插件方式支持许多不同协议的数据摄入,如:graphite,collectd,和openTSDB SQL-like查询语言,简化查询和聚合操作。 索引Tags,支持快速有效的查询时间序列。 保留策略有效去除过期数据。 连续查询自动计算聚合数据,使频繁查询更有效。 influxDB 不支持数据库的更新操作,毕竟时间数据只能随着时间产生新数据,肯定无法对过去的数据修改。 适合于写多读少的场景 graphite graphite算是一个老牌的时间序列存储解决方案了,graphite由三个部分组成,分别是carbon、whisper和graphite web carbon:实际上是一系列守护进程,这些守护进程用Twisted的事件驱动网络引擎监听时间序列数据。Twisted框架让Carbon守护进程能够以很低的开销处理大量的客户端和流量。 whisper:是一个用于存储时间序列数据的数据库,之后应用程序可以用create,update和fetch操作获取并操作这些数据。 graphite web:使用django开发的一套web,提供一些常用的聚合函数,可以界面友好的展示出图形。再盗图: whisper支持RRD,可以很方便的定义retention,以及定义storage scheme,不需要手动做,graphite会自动帮你按照不同的scheme实现aggregation。这样每个metric的大小就是固定的了,所以理论上可以永久存储数据。graphite的集群方案主要有两种,分别是使用graphite自带的relay或是使用第三方的工具。 当使用自带的relay时,只需要在配置文件中配置要relay到哪些机器即可,这样在数据写入的时候,被写入的节点会relay一份到这些机器中。在读取的时候,在graphite web的settings中配置HOSTS的列表,这样在django的web中会依次从这些HOSTS中读出数据。 另一种是需用第三方的relay工具,Booking公司开源出来了他们所用的用C写得 carbon-c-relay,以及用GO写得carbon-relay-ng。其基本的思想是运用一致性哈希,可以将不同的metric发到不同的机器,以来达到集群的目的,据Booking称他们的graphite集群的规模达到了百台机器,而mertic也达到了百万的级别. 以上的两种方式都会遇到了一个共同的问题,就是集群扩容的问题,我不知道Booking是怎么来解决这个问题的,但是我这边目前是想到了几种方式,这个在我前一篇的文章中已经阐述了: graphite集群扩容方案探究,在这里就先不赘述了。 最后说一下,除了集群问题以外,graphite的还有一性能问题就是读的性能稍差,这决定于其存储的方式,其实在读的时候会去读whisper文件(虽然在django层做了缓存,但是缓存的功能比较弱),通过seek的方式来获取数据的位置,在将数据取出。 opentsdb Opentsdb是一个基于Hbase的时间序列数据库 (新版也支持Cassandra)。 其基于Hbase的分布式列存储特性实现了数据高可用,高性能写的特性。受限于Hbase,存储空间较大,压缩不足。依赖整套 HBase, ZooKeeper 采用无模式的tagset数据结构(sys.cpu.user 1436333416 23 host=web01 user=10001) 结构简单,多value查询不友好 HTTP-DSL查询 opentsdb是一个比较重的时间序列解决方案,为什么说他重呢?因为它的组成是这样的: 可以看到opentsdb所依赖的存储是Hbase集群。TSD在其中担任的责任是IO部分,TSD其实就是一个后台的daemon,一般我会会用一组TSD达成一个TSD的集群 (其实不能算是集群) ,没有master/slave之分,也没有共享状态,然后在之前用LB设备来做负载均衡,官方比较推荐的是用varnish。 当让后端的存储也可以用其他的例如hadoop,但是官方还是建议用Hbase,因为opentsdb就是Hbase社区孵化出来的产品。那么问题来了,Hbase的运维将是一个艰巨的任务,这个依赖于 zookeeper 搭建的集群的坑还是很多的,我看了一下官方文档就有上千页。这里面的优化维护需要有专业的Hbase专家才能完成。 另外opentsdb做不到graphite那样自动做downsample,也就是做不到RRD那样地去存储数据,需要在外面自己做一层手动干这活,再把聚合后的数据写入Hbase,唉,还真是一个费时费力的活。 除此之外opentsdb还是很不错的,读写性能挺高,而且支持tag,支持ttl,支持各种聚合函数。现在很多的监控的metric的存储都是用的opentsdb,嗯,是的,只要有能力玩转还是个不错的选择。 Timescale 基于传统关系型数据库postgresql改造的时间序列数据库 一款兼容sql的时序数据库, 底层存储架构在postgresql上。 作为一个postgresql的扩展提供服务。 ...

2017-08-02 · 1 min · 109 words · -

InfluxDB

InfluxDB 时间序列数据库 InfluxDB 基于 Go 语言开发,社区非常活跃,项目更新速度很快,日新月异,关注度高。 特点 可以设置metric的保存时间。 支持通过条件过滤以及正则表达式删除数据。 支持类似 sql 的语法。 可以设置数据在集群中的副本数。 支持定期采样数据,写入另外的measurement,方便分粒度存储数据。 概念 数据格式 Line Protocol measurement[,tag_key1=tag_value1…] field_key=field_value[,field_key2=field_value2] [timestamp] cpu_load,host_id=1 value=0.1 1434055562000000000 相比于 JSON 格式,无需序列化,更加高效。 measurement: metric name,例如 cpu_load。 field-key, field-value: 通常用来存储数据,类似 opentsdb 中的 value=0.6,但是支持各种类型,数据存储时不会进行索引,每条数据必须拥有一个 field-key,如果使用 field-key 进行过滤,需要遍历一遍所有数据。 tags-key, tags-value: 和 field-key 类似,但是会进行索引,方便查询时用于过滤条件。 Series measurement, tag set, retention policy 相同的数据集合算做一个 series。 假设 cpu_load 有两个 tags,host_id 和 name,host_id 的数量为 100,name 的数量为 200,则 series 基数为 100 * 200 = 20000。 ...

2017-07-12 · 3 min · 578 words · -

MVCC, Multiversion Concurrency Control, 多版本并发控制

MVCC, Multiversion Concurrency Control, 多版本并发控制 http://donghui.blog.51cto.com/2709336/692586 多版本并发控制技术已经被广泛运用于各大数据库系统中,如 Oracle, MS SQL Server 2005+, Postgresql, Firebird, Maria 等等, 开源数据库 MySQL 中流行的 INNODB 引擎也采用了类似的并发控制技术.本文就将结合实例来解析不同事务隔离等级下 INNODB 的 MVCC 实现原理. 1.1 MVCC 简介 MVCC (Multiversion Concurrency Control), 即多版本并发控制技术, 它使得大部分支持行锁的事务引擎, 不再单纯的使用行锁来进行数据库的并发控制, 取而代之的是, 把数据库的行锁与行的多个版本结合起来, 只需要很小的开销, 就可以实现非锁定读, 从而大大提高数据库系统的并发性能. 1.2 实现原理 MVCC 可以提供基于某个时间点的快照, 使得对于事务看来, 总是可以提供与事务开始时刻相一致的数据, 而不管这个事务执行的时间有多长. 所以在不同的事务看来, 同一时刻看到的相同行的数据可能是不一样的, 即一个行可能有多个版本. 是否听起来不可思议呢? 原来, 为了实现 mvcc, innodb 对每一行都加上了两个隐含的列, 其中一列存储行被更新的"时间", 另外一列存储行被删除的"时间". 但是 innodb 存储的并不是绝对的时间, 而是与时间对应的数据库系统的版本号, 每当一个事务开始的时候, innodb 都会给这个事务分配一个递增的版本号, 所以版本号也可以被认为是事务号. 对于每一个"查询"语句, innodb 都会把这个查询语句的版本号同这个查询语句遇到的行的版本号进行对比, 然后结合不同的事务隔离等级, 来决定是否返回该行. ...

2017-05-09 · 5 min · 859 words · -

kafka config, server, producer

kafka config, server, producer 大体上来说,用户首先构建待发送的消息对象ProducerRecord,然后调用KafkaProducer#send方法进行发送。KafkaProducer接收到消息后首先对其进行序列化,然后结合本地缓存的元数据信息一起发送给partitioner去确定目标分区,最后追加写入到内存中的消息缓冲池(accumulator)。此时KafkaProducer#send方法成功返回。 KafkaProducer中还有一个专门的Sender IO线程负责将缓冲池中的消息分批次发送给对应的broker,完成真正的消息发送逻辑。 基本设计特点 结合源代码,笔者认为新版本的producer从设计上来说具有以下几个特点(或者说是优势): 总共创建两个线程: 执行KafkaPrducer#send逻辑的线程——我们称之为"用户主线程";执行发送逻辑的IO线程——我们称之为"Sender线程" 不同于Scala老版本的producer,新版本producer完全异步发送消息,并提供了回调机制(callback)供用户判断消息是否成功发送 batching机制——“分批发送"机制。每个批次(batch)中包含了若干个PRODUCE请求,因此具有更高的吞吐量 更加合理的默认分区策略: 对于无key消息而言,Scala版本分区策略是一段时间内(默认是10分钟)将消息发往固定的目标分区,这容易造成消息分布的不均匀,而新版本的producer采用轮询的方式均匀地将消息分发到不同的分区 底层统一使用基于 Selector 的网络客户端实现, 结合 Java 提供的 Future 实现完整地提供了更加健壮和优雅的生命周期管理。 其实,新版本 producer 的设计优势还有很多, 诸如监控指标更加完善等这样的就不一一细说了。总之, 新版本producer更加地健壮,性能更好~ Kafka新版本clients在设计底层网络库时采用了Java的Selector机制,而后者在 Linux上的实现机制就是 epoll;但是在 Windows平台上,Java NIO的 Selector 底层是使用 select模型而非IOCP 实现的,只有 Java NIO2才是使用 IOCP 实现的。因此在这一点上,在 Linux 上部署Kafka要比在Windows上部署能够得到更高效的I/O处理性能。 properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("acks", "all"); props.put("retries", 0); props.put("batch.size", 16384); props.put("linger.ms", 1); props.put("buffer.memory", 33554432); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); Producer<String, String> producer = new KafkaProducer<>(props); for(int i = 0; i < 100; i++) producer.send(new ProducerRecord<String, String>("my-topic", Integer.toString(i), Integer.toString(i))); producer.close(); bootstrap.servers 配置kafka 查询集群 metadata 服务的地址, 建立连接时,kafa producer向 bootstrap.servers 发 metadata 请求, 从 返回 的metadata response里得到kafka 集群的地址,再建立连接 ...

2017-05-04 · 4 min · 739 words · -

MySQL INNODB

MySQL INNODB InnoDB 由 Innobase Oy 公司所开发, 发音为 “in-no-db” http://wulijun.github.io/2012/09/29/MySQL-innodb-intro.html InnoDB是MySQL下使用最广泛的引擎, 它是基于 MySQL 的高可扩展性和高性能存储引擎, 从5.5版本开始, 它已经成为了默认引擎。 InnODB 引擎支持众多特性: 支持ACID,简单地说就是支持事务完整性、一致性; 支持行锁,以及类似ORACLE的一致性读,多用户并发; 独有的聚集索引主键设计方式,可大幅提升并发读写性能; 支持外键; 支持崩溃数据自修复; InnoDB有这么多特性,比MyISAM来的优秀多了,还犹豫什么,果断的切换到InnoDB引擎吧 🙂 InnoDB 配置 可以选择官方版本, 或者 Percon a的分支, 如果不知道在哪下载, 就google吧。安装完MySQL后,需要适当修改下 my.cnf 配置文件, 针对 InnoDB 相关的选项做 一些调整, 才能较好的运行InnoDB。 相关的选项有: #InnoDB存储数据字典、内部数据结构的缓冲池,16MB 已经足够大了。 innodb_additional_mem_pool_size = 16M #InnoDB用于缓存数据、索引、锁、插入缓冲、数据字典等 #如果是专用的DB服务器,且以InnoDB引擎为主的场景,通常可设置物理内存的50% #如果是非专用DB服务器,可以先尝试设置成内存的1/4,如果有问题再调整 #默认值是8M,非常坑X,这也是导致很多人觉得InnoDB不如MyISAM好用的缘故 innodb_buffer_pool_size = 4G #InnoDB共享表空间初始化大小,默认是 10MB,也非常坑X,改成 1GB,并且自动扩展 innodb_data_file_path = ibdata1:1G:autoextend #如果不了解本选项,建议设置为1,能较好保护数据可靠性,对性能有一定影响,但可控 innodb_flush_log_at_trx_commit = 1 #InnoDB的log buffer,通常设置为 64MB 就足够了 innodb_log_buffer_size = 64M #InnoDB redo log大小,通常设置256MB 就足够了 ...

2017-04-11 · 2 min · 289 words · -

redis sort set, 有序集, zset

redis sort set, 有序集, zset sort set, zset Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中。它们之间的主要差别是Sorted-Sets中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。然而需要额外指出的是,尽管Sorted-Sets中的成员必须是唯一的,但是分数(score)却是可以重复的 在Sorted-Set中添加、删除或更新一个成员都是非常快速的操作,其时间复杂度为集合中成员数量的对数。由于Sorted-Sets中的成员在集合中的位置是有序的,因此,即便是访问位于集合中部的成员也仍然非常高效。事实上,Redis所具有的这一特征在很多其它类型的数据库中是很难实现的,换句话说,在该点上要想达到和Redis同样的高效,在其它数据库中进行建模会非常困难。 相关命令列表 命令原型,时间复杂度,命令描述,返回值 添加, ZADD zADD key score member [score] [member] 将一个或多个member元素及其score值加入到有序集key当中。 O(log(N)), 时间复杂度中的N表示Sorted-Sets中成员的数量。 添加参数中指定的所有成员及其分数到指定key的Sorted-Set中,在该命令中我们可以指定多组score/member作为参数。如果在添加时参数中的某一成员已经存在,该命令将更新此成员的分数为新值,同时再将该成员基于新值重新排序。如果键不存在,该命令将为该键创建一个新的Sorted-Sets Value,并将score/member对插入其中。如果该键已经存在,但是与其关联的Value不是Sorted-Sets类型,相关的错误信息将被返回。 返回值: 本次操作实际插入的成员数量。 分数的范围 Redis的Sorted Set的分数范围从-(2^53)到+(2^53)。或者说是-9007199254740992 到 9007199254740992。更大的整数在内部用指数表示。 删除, ZREM ZREM key member [member …] 移除有序集key中的一个或多个成员,不存在的成员将被忽略。 O(M log(N)) 时间复杂度中N表示Sorted-Set中成员的数量,M则表示被删除的成员数量。该命令将移除参数中指定的成员,其中不存在的成员将被忽略。如果与该Key关联的Value不是Sorted-Set,相应的错误信息将被返回。 返回值: 实际被删除的成员数量。 ZCARD, 计算集合中元素的数量 ZCARD key 返回有序集key的基数。 O(1) 成员数量。获取与该Key相关联的Sorted-Sets中包含的成员数量。 返回值: 返回Sorted-Sets中的成员数量,如果该Key不存在,返回0。 ZCOUNT,score值在min和max之间的成员数量 ZCOUNT key min max 返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员。 O(log(N)+M) 时间复杂度中的N表示Sorted-Sets中成员的数量,M则表示min和max之间元素的数量。该命令用于获取分数(score)在min和max之间的成员数量。针对min和max参数需要额外说明的是,-inf和+inf分别表示Sorted-Sets中分数的最高值和最低值。缺省情况下,min和max表示的范围是闭区间范围,即min <= score <= max内的成员将被返回。然而我们可以通过在min和max的前面添加"(“字符来表示开区间,如(min max表示min < score <= max,而(min (max表示min < score < max。 ...

2017-02-13 · 2 min · 308 words · -

redis 集群/cluster

redis 集群/cluster redis 工作在集群模式的时候除了常规的 tcp 端口 6379, 还需要一个额外的 TCP 端口跟集群内的其它节点通信, 端口号是在 tcp 端口基础上加一个固定的偏移量 10000, 6379 + 10000 = 16379 https://rajivsharma-2205.medium.com/enable-tcp-keepalive-on-redis-cluster-bus-153128e412fa redis5.0.x 上 redis-trib.rb 工具不再可用,redis-trib.rb 相关的全部功能,已迁移到 redis-cli –cluster 命令上了。 # 创建集群主节点 redis-cli --cluster create 192.168.163.132:6379 192.168.163.132:6380 192.168.163.132:6381 # 创建集群主从节点 /redis-cli --cluster create 192.168.163.132:6379 192.168.163.132:6380 192.168.163.132:6381 192.168.163.132:6382 192.168.163.132:6383 192.168.163.132:6384 --cluster-replicas 1 # 集群信息查看 redis-cli --cluster info 192.168.163.132:6384 # 检查集群状态 redis-cli --cluster check 192.168.163.132:6379 # 检查集群, 检查是否有槽同时被分配给了多个节点 redis-cli --cluster check 192.168.163.132:6384 --cluster-search-multiple-owners # 修复集群 redis-cli --cluster fix 192.168.163.132:6384 --cluster-search-multiple-owners # 添加集群主节点 redis-cli --cluster add-node 192.168.163.132:6382 192.168.163.132:6379 # 说明: 为一个指定集群添加节点,需要先连到该集群的任意一个节点IP (192.168.163.132:6379) ,再把新节点加入。这两个参数的顺序有要求: 新加入的节点放前面 # 添加集群从节点 redis-cli --cluster add-node 192.168.163.132:6382 192.168.163.132:6379 --cluster-slave --cluster-master-id 117457eab5071954faab5e81c3170600d5192270 说明: 把6382节点加入到6379节点的集群中,并且当做node_id为 117457eab5071954faab5e81c3170600d5192270 的从节点。如果不指定 --cluster-master-id 会随机分配到任意一个主节点。 # 删除节点 redis-cli --cluster del-node 192.168.163.132:6384 f6a6957421b00009106cb36be3c7ba41f3b603ff # 说明: 指定 IP, 端口和 node_id 来删除一个节点,从节点可以直接删除,主节点不能直接删除,删除之后,该节点会被shutdown。 # 修复集群 redis-cli --cluster fix 192.168.163.132:6379 cluster # 当前连接节点所属集群的配置信息 ./redis-cli -p 7000 cluster nodes # 人工故障切换, 该命令只能在群集slave节点执行 redis-cli -p 7000 CLUSTER FAILOVER # http://www.redis.cn/commands/cluster-failover.html redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave --cluster-master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e ./redis-cli -p 7006> cluster replicate 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e redis-cli --cluster del-node 127.0.0.1:7000 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e ./redis-cli --cluster check 127.0.0.1:7000 # 查看集群状态 cluster info 返回值 cluster_state:状态是ok节点是否能够接收查询。fail状态表示有哈希槽没有被绑定到任意一个节点或者节点可以提供服务但是带有fail标记,或者该节点无法连续到多数master节点 cluster_slots_assigned:与某个节点关联的槽数(不是未绑定的)。这个数字应该是16384,节点才能正常工作,这意味着每个散列槽应该映射到一个节点。 cluster_slots_ok:哈希槽状态不是Fail和PFail的数量 cluster_slots_pfail:哈希槽状态是PFAIL的数量。请注意,只要PFAIL状态不由FAIL故障检测算法提升,这些散列槽仍可正常工作。PFAIL仅意味着我们目前无法与节点通话,但可能只是一个暂时的错误。 cluster_slots_fail:哈希槽状态是FAIL的数量。如果此数字不为零,则该节点无法提供查询,除非在配置中cluster-require-full-coverage设置为no。 cluster_known_nodes:群集中已知节点的总数,包括处于握手(HANDSHAKE)状态还没有称为集群正式成员的节点 cluster_size:至少包含一个哈希槽而且能够提供服务的master节点数量 cluster_current_epoch:集群本地Current Epoch变量的值,这个值在节点故障转移期间创建的独特的自增版本号 cluster_my_epoch:我们正在与之交谈的Config Epoch节点。这是分配给此节点的当前配置版本。 cluster_stats_messages_sent:通过node-to-node二进制总线发送的消息数量 cluster_stats_messages_received:通过node-to-node二进制总线接收的消息数量 redis cluster哈希槽数量 16348=16k, 用 bitmap 来压缩心跳包的话, 就相当于使用 2_8_10=2KB 大小的心跳包。而如果用 crc16 算法( redis使用这个而不是用哈希一致性算法)来确定哈希槽的分配。他的最大值是是2的16次方。用上面的算法换算需要8KB的心跳包来传输, 作者自己认为这样不划算。而一个redis节点一般不会有超过 1000 个master(这个是作者自己说的), 用16k 来划分是比较合适的 ...

2016-12-16 · 3 min · 609 words · -

MySQL explain, 执行计划, Query Execution Plan

MySQL explain, 执行计划, Query Execution Plan 关于explain命令相信大家并不陌生,具体用法和字段含义可以参考官网explain-output,这里需要强调rows是核心指标,绝大部分rows小的语句执行一定很快 (有例外,下面会讲到) 。所以优化语句基本上都是在优化rows。 在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描,这都可以通过explain命令来查看。所以我们深入了解MySQL的基于开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪种策略预计会被优化器采用。 (QEP: sql生成一个执行计划query Execution plan) MySQL> explain select * from servers; +—-+————-+———+——+—————+——+———+——+——+——-+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +—-+————-+———+——+—————+——+———+——+——+——-+ | 1 | SIMPLE | servers | ALL | NULL | NULL | NULL | NULL | 1 | NULL | +—-+————-+———+——+—————+——+———+——+——+——-+ 1 row in set (0.03 sec) expain出来的信息有10列,分别是 id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,下面对这些字段出现的可能进行解释: ...

2016-11-28 · 4 min · 687 words · -

kafka

kafka kafka 大量使用页缓存, 经过良好调优的 kafka 集群, 磁盘读操作很少, 因为大部分消息读取操作会直接命中缓存 kafka 高吞吐量 大量使用操作系统页缓存,内存操作速度快且命中率高。 Kafka 不直接参与物理I/O操作,而是交由最擅长此事的操作系统来完成。 采用追加写入方式,摒弃了缓慢的磁盘随机读/写操作。 使用以 sendfile为代表的零拷贝技术加强网络间的数据传输效率。 摘自:《Apache Kafka实战》 — 胡夕 在豆瓣阅读书店查看:https://read.douban.com/ebook/59895902/ 本作品由电子工业出版社授权豆瓣阅读中国大陆范围内电子版制作与发行。 © 版权所有,侵权必究。 伸缩性,scalability 伸缩性表示向分布式系统中增加额外的计算资源(比如CPU、内存、存储或带宽)时吞吐量提升的能力。 partition Kafka的partition是不可修改的有序消息序列,也可以说是有序的消息日志。 replica 副本(replica) follower replica 是不能提供服务给客户端的,也就是说不负责响应客户端发来的消息写入和消息消费请求。它只是被动地向领导者副本(leader replica)获取数据 ISR的全称是in-sync replica,翻译过来就是与leader replica保持同步的replica集合 正常情况下,partition的所有replica(含leader replica)都应该与leader replica保持同步,即所有 replica都在 ISR中。因为各种各样的原因,一小部分 replica开始落后于 leader replica的进度。当滞后到一定程度时,Kafka会将这些 replica“踢”出 ISR。相反地,当这些 replica重新“追上”了 leader的进度时,那么 Kafka会将它们加回到 ISR中。这一切都是自动维护的,不需要用户进行人工干预,因而在保证了消息交付语义的同时还简化了用户的操作成本。 摘自:《Apache Kafka实战》 — 胡夕 在豆瓣阅读书店查看:https://read.douban.com/ebook/59895902/ 本作品由电子工业出版社授权豆瓣阅读中国大陆范围内电子版制作与发行。 © 版权所有,侵权必究。 Event Sourcing实际上是领域驱动设计(Domain-Driven Design,DDD)的名词,它使用事件序列来表示状态变更,这种思想和 Kafka 的设计特性不谋而合。 数据倾斜(skewed) 分布式消息队列是是大型分布式系统不可缺少的中间件,主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。 为何使用消息系统 解耦 在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息系统在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。 冗余 有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。 ...

2016-07-26 · 2 min · 271 words · -

redis list

redis list 在 Redis 中, List 类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295。 从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。然而需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。 Redis 的列表经常被用作队列(queue),用于在不同程序之间有序地交换消息(message)。 一个程序(称之为生产者,producer)通过LPUSH命令将消息放入队列中,而另一个程序(称之为消费者,consumer)通过RPOP命令取出队列中等待时间最长的消息。 不幸的是,在这个过程中,一个消费者可能在获得一个消息之后崩溃,而未执行完成的消息也因此丢失。 使用RPOPLPUSH命令可以解决这个问题,因为它在返回一个消息之余,还将该消息添加到另一个列表当中,另外的这个列表可以用作消息的备份表: 假如一切正常,当消费者完成该消息的处理之后,可以用LREM命令将该消息从备份表删除。 另一方面,助手(helper)程序可以通过监视备份表,将超过一定处理时限的消息重新放入队列中去(负责处理该消息的消费者可能已经崩溃),这样就不会丢失任何消息了。 头元素和尾元素 头元素指的是列表左端/前端第一个元素,尾元素指的是列表右端/后端第一个元素。 举个例子,列表list包含三个元素: x, y, z,其中x是头元素,而z则是尾元素。 空列表 指不包含任何元素的列表,Redis将不存在的key也视为空列表。 一个列表最多可以包含 232 – 1 个元素 (4294967295, 每个列表超过40亿个元素)。 相关命令 LPUSH LPUSH key value1 [value2] 将一个或多个值插入到列表头部 RPUSH RPUSH key value1 [value2] 将一个或多个值value插入到列表key的表尾。 LPOP key 移出并获取列表的第一个元素 RPOP key RPOP key 移除列表的最后一个元素,返回值为移除的元素。 LLEN key 获取列表长度 LRANGE key start stop LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 BLPOP BLPOP key1 [key2 ] timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 ...

2015-12-01 · 4 min · 771 words · -

redis data type, 数据类型

redis data type, 数据类型 https://redis.io/topics/data-types https://redis.io/topics/data-types-intro String - 字符串 List - 列表 Set - 无序集合 Hashes - 哈希/散列表 Sorted sets - 有序集合 Stream - 消息队列 Bitmaps, url: redis-bitmap HyperLogLogs Hyperloglog https://segmentfault.com/a/1190000020523110 geospatial https://blog.csdn.net/zhang197093/article/details/72979038

2015-09-22 · 1 min · 33 words · -

PostgreSQL execution plan, explain, 执行计划

PostgreSQL execution plan, explain, 执行计划 -- 查看执行计划 EXPLAIN select * from table_0 where id < 1000; -- EXPLAIN ANALYZE - 查看实际执行情况(推荐) EXPLAIN ANALYZE select * from table_0 where id < 1000; -- 更详细的执行计划 EXPLAIN (ANALYZE, BUFFERS, VERBOSE, FORMAT TEXT) select * from table_0 where id < 1000; Seq Scan, 全表扫描,顺序扫描 全表扫描,也叫顺序扫描,扫描时把表中所有的数据块从头到尾遍历一边,找到复合条件的数据块。全表扫描在在explain中使用Seq Scan表示 IndexOnly Scan IndexOnly Scan 是覆盖索引扫描,所需的返回结果能被所扫描的索引全部覆盖 https://www.jianshu.com/p/682d798aee1f 了解 PostgreSQL 执行计划对于开发人员来说是一项关键技能,执行计划是我们优化查询,验证我们的优化查询是否确实按照我们期望的方式运行的重要方式。 PostgreSQL 数据库中的查询生命周期 每个查询都会经历不同的阶段,了解每个阶段对数据库的意义很重要。 查询生命周期 第一阶段是通过 Postgres 的客户端连接到数据库。 ...

2015-09-17 · 4 min · 829 words · -

redis hash

redis hash Redis hash 是一个 string 类型的 field和 value的映射表.一个 key可对应多个 field, 一个 field对应一个 value。将一个对象存储为 hash类型,较于每个字段都存储成string类型更能节省内存。新建一个 hash对象时开始是用 zipmap(又称为small hash)来存储的。这个 zipmap其实并不是 hash table,但是zipmap 相比正常的 hash实现可以节省不少 hash本身需要的一些元数据存储开销。尽管 zipmap的添加, 删除,查找都是O(n),但是由于一般对象的field数量都不太多。所以使用zipmap也是很快的,也就是说添加删除平均还是O(1)。如果field或者value的大小超出一定限制后,Redis会在内部自动将zipmap替换成正常的hash实现。 hash操作命令如下: 删除 key del key hset 向名称为 key 的 hash 中添加元素 hset key field value hget hget(key, field) 返回名称为key的hash中field对应的value hsetnx HSETNX key field value 将哈希表key中的域field的值设置为value,当且仅当域field不存在。若域field已经存在,该操作无效。 如果key不存在,一个新哈希表被创建并执行h#setnx命令。 hmget hmget(key, field1, …,field N) 返回名称为key的hash中field i对应的value hmset hmset(key, field1, value1,…,field N, value N) 向名称为key的hash中添加元素field i<—>value i ...

2015-07-28 · 1 min · 177 words · -

MySQL 存储引擎

MySQL 存储引擎 什么是存储引擎? 关系数据库表是用于存储和组织信息的数据结构,可以将表理解为由行和列组成的表格,类似于Excel的电子表格的形式。有的表简单,有的表复杂,有的表根本不用来存储任何长期的数据,有的表读取时非常快,但是插入数据时去很差;而我们在实际开发过程中,就可能需要各种各样的表,不同的表,就意味着存储不同类型的数据,数据的处理上也会存在着差异,那么。对于MySQL来说,它提供了很多种类型的存储引擎,我们可以根据对数据处理的需求,选择不同的存储引擎,从而最大限度的利用MySQL强大的功能。这篇博文将总结和分析各个引擎的特点,以及适用场合,并不会纠结于更深层次的东西。我的学习方法是先学会用,懂得怎么用,再去知道到底是如何能用的。下面就对MySQL支持的存储引擎进行简单的介绍。 MyISAM MyISAM 发音为 “my-z[ei]m”; 在MySQL客户端中,使用以下命令可以查看MySQL支持的引擎:show engines; MyISAM表是独立于操作系统的,这说明可以轻松地将其从Windows服务器移植到Linux服务器;每当我们建立一个MyISAM引擎的表时,就会在本地磁盘上建立三个文件,文件名就是表明。例如,我建立了一个MyISAM引擎的tb_Demo表,那么就会生成以下三个文件: tb_demo.frm,存储表定义; tb_demo.MYD,存储数据; tb_demo.MYI,存储索引。 MyISAM表无法处理事务,这就意味着有事务处理需求的表,不能使用MyISAM存储引擎。MyISAM存储引擎特别适合在以下几种情况下使用: 选择密集型的表。MyISAM存储引擎在筛选大量数据时非常迅速,这是它最突出的优点。 插入密集型的表。MyISAM的并发插入特性允许同时选择和插入数据。例如: MyISAM存储引擎很适合管理邮件或Web服务器日志数据。 InnoDB InnoDB是一个健壮的事务型存储引擎,这种存储引擎已经被很多互联网公司使用,为用户操作非常大的数据存储提供了一个强大的解决方案。我的电脑上安装的MySQL 5.6.13版,InnoDB就是作为默认的存储引擎。InnoDB还引入了行级锁定和外键约束,在以下场合下,使用InnoDB是最理想的选择: 更新密集的表。InnoDB存储引擎特别适合处理多重并发的更新请求。 事务。InnoDB存储引擎是支持事务的标准MySQL存储引擎。 自动灾难恢复。与其它存储引擎不同,InnoDB表能够自动从灾难中恢复。 外键约束。MySQL支持外键的存储引擎只有InnoDB。 支持自动增加列AUTO_INCREMENT属性。 一般来说,如果需要事务支持,并且有较高的并发读取频率,InnoDB是不错的选择。 MEMORY 使用MySQL Memory存储引擎的出发点是速度。为得到最快的响应时间,采用的逻辑存储介质是系统内存。虽然在内存中存储表数据确实会提供很高的性能,但当MySQLd守护进程崩溃时,所有的Memory数据都会丢失。获得速度的同时也带来了一些缺陷。它要求存储在Memory数据表里的数据使用的是长度不变的格式,这意味着不能使用BLOB和TEXT这样的长度可变的数据类型,VARCHAR是一种长度可变的类型,但因为它在MySQL内部当做长度固定不变的CHAR类型,所以可以使用。 一般在以下几种情况下使用Memory存储引擎: 目标数据较小,而且被非常频繁地访问。在内存中存放数据,所以会造成内存的使用,可以通过参数max_heap_table_size控制Memory表的大小,设置此参数,就可以限制Memory表的最大大小。 如果数据是临时的,而且要求必须立即可用,那么就可以存放在内存表中。 存储在Memory表中的数据如果突然丢失,不会对应用服务产生实质的负面影响。 Memory同时支持散列索引和B树索引。B树索引的优于散列索引的是,可以使用部分查询和通配查询,也可以使用<、>和>=等操作符方便数据挖掘。散列索引进行"相等比较"非常快,但是对"范围比较"的速度就慢多了,因此散列索引值适合使用在=和<>的操作符中,不适合在<或>操作符中,也同样不适合用在order by子句中。 可以在表创建时利用USING子句指定要使用的版本。例如: create table users ( id smallint unsigned not null auto_increment, username varchar(15) not null, pwd varchar(15) not null, index using hash (username), primary key (id) )engine=memory; 上述代码创建了一个表,在username字段上使用了HASH散列索引。下面的代码就创建一个表,使用BTREE索引。 create table users ( id smallint unsigned not null auto_increment, ...

2015-06-28 · 2 min · 405 words · -

内存数据库

内存数据库 内存数据库,顾名思义就是将数据放在内存中直接操作的数据库。相对于磁盘,内存的数据读写速度要高出几个数量级,将数据保存在内存中相比从磁盘上访问能够极大地提高应用的性能。 内存数据库抛弃了磁盘数据管理的传统方式,基于全部数据都在内存中重新设计了体系结构,并且在数据缓存、快速算法、并行操作方面也进行了相应的改进,所以数据处理速度比传统数据库的数据处理速度要快很多,一般都在10倍以上。内存数据库的最大特点是其"主拷贝"或"工作版本"常驻内存,即活动事务只与实时内存数据库的内存拷贝打交道。 定义:设有数据库系统DBS,DB为DBS中的数据库,DBM(t)为在时刻t,DB在内存的数据集,DBM(t)属于DB。TS为DBS中所有可能的事务构成的集合。AT(t)为在时刻t处于活动状态的事务集,AT(t)属于TS。Dt(T)为事务T在时刻t所操作的数据集, Dt(T)属于DB。若在任意时刻t,均有: 任意T属于AT(t) Dt(T)属于DBM(t) 成立,则称DBS为一个内存数据库系统,简称为MMDBS;DB为一个内存数据库,简称为MMDB。 常见的例子有MySQL的MEMORY存储引擎、eXtremeDB、TT、FastDB、SQLite、Microsoft SQL Server Compact,Redis http://baike.baidu.com/view/1210875.htm

2014-01-15 · 1 min · 13 words · -

sql 的四舍五入取整问题

sql 的四舍五入取整问题 转自: http://hi.baidu.com/yahuudang/blog/item/4c65ab77f758b01fb151b953.html 经在sql server 2005测试,可以通过 SELECT CAST(‘123.456’ as decimal) 将会得到 123 (小数点后面的将会被省略掉) 。 如果希望得到小数点后面的两位。 则需要把上面的改为 SELECT CAST(‘123.456’ as decimal(38, 2)) ===>123.46 自动四舍五入了! 自己的例子: select CAST(AmountRmb as decimal(38)) as heji,CAST(NotFinFee as decimal(38)) as whx,* from Bill_Tab

2013-08-20 · 1 min · 37 words · -

FOR XML PATH

FOR XML PATH http://www.cnblogs.com/doubleliang/archive/2011/07/06/2098775.html FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作。那么以一个实例为主. 一.FOR XML PATH 简单介绍 那么还是首先来介绍一下FOR XML PATH ,假设现在有一张兴趣爱好表 (hobby) 用来存放兴趣爱好,表结构如下: 接下来我们来看应用FOR XML PATH的查询结果语句如下: SELECT * FROM @hobby FOR XML PATH 结果: 复制代码 1 爬山 2 ...

2013-07-29 · 2 min · 246 words · -