- select distinct A.ID from A where A.ID not in (select ID from B)
- select A.ID from A left join B on A.ID=B.ID where B.ID is null
- select * from A where (select count(*) from B where A.ID = B.ID) = 0;
以上是存在A表,但是不存在B表的数据
雄关漫道真如铁 而今迈步从头越
以上是存在A表,但是不存在B表的数据
两者都可用来表示YYYY-MM-DD HH:MM:SS[.fraction]类型的日期。
对于TIMESTAMP,它把客户端插入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。
而对于DATETIME,不做任何改变,基本上是原样输入和输出。
timestamp所能存储的时间范围为:’1970-01-01 00:00:01.000000′ 到 ‘2038-01-19 03:14:07.999999’。
datetime所能存储的时间范围为:’1000-01-01 00:00:00.000000′ 到 ‘9999-12-31 23:59:59.999999’。
在MySQL 5.6.5版本之前,Automatic Initialization and Updating只适用于TIMESTAMP,而且一张表中,最多允许一个TIMESTAMP字段采用该特性。从MySQL 5.6.5开始,Automatic Initialization and Updating同时适用于TIMESTAMP和DATETIME,且不限制数量。
ps: 自动初始化和自动更新(Automatic Initialization and Updating)
自动初始化指的是如果对该字段(譬如上例中的hiredate字段)没有显性赋值,则自动设置为当前系统时间。
自动更新指的是如果修改了其它字段,则该字段的值将自动更新为当前系统时间。
设置自动修改时间:
–添加UpdateTime 设置 默认时间 CURRENT_TIMESTAMP 设置更新时间为 ON UPDATE CURRENT_TIMESTAMP
ALTER TABLE table_name
ADD COLUMN UpdateTime
datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘创建时间’ ;
TIMESTAMP(3)与 DATETIME(3)意思是保留3为毫秒数
TIMESTAMP(6)与 DATETIME(6)意思是保留6为毫秒数
# 直接定位到第100行 less +100g xx.log
# 定位到最后一行 less +GG xx.log
# 直接定位到50%的位置 less +100p xx.log
大多数网上都是这种
function msectime()
{
list($msec, $sec) = explode(' ', microtime());
$msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
return $msectime;
}
但是,PHP `microtime`函数可以支持毫秒
`round(microtime(true)*1000)` 可以输出毫秒时间戳
进入https://www.vultr.com/resources/faq/ 页面
搜 `speed`
查找搜索结果,How can I test Vultr download speeds?
下载对应的节点数据。哪个速度快表示那个服务器合适
bulk的格式:
{action:{metadata}}\n
{requstbody}\n (请求体)
action:(行为),包含create(文档不存在时创建)、update(更新文档)、index(创建新文档或替换已用文档)、delete(删除一个文档)。
create和index的区别:如果数据存在,使用create操作失败,会提示文档已存在,使用index则可以成功执行。
metadata:(行为操作的具体索引信息),需要指明数据的_index、_type、_id。
批量添加
POST /lib2/books/_bulk
{"index":{"_id":1}} \\行为:索引信息
{"title":"Java","price","55"} \\请求体
{"index":{"_id":2}}
{"title":"Html5","price","45"}
{"index":{"_id":3}}
{"title":"Php","price","35"}
{"index":{"_id":4}}
{"title":"Python","price","50"}
批量删除
删除的批量操作不需要请求体
POST /lib/books/_bulk
{"delete":{"_index":"lib","_type":"books","_id":"4"}} //删除的批量操作不需要请求体
{"create":{"_index":"tt","_type":"ttt","_id":"100"}}
{"name":"lisi"} //请求体
{"index":{"_index":"tt","_type":"ttt"}} //没有指定_id,elasticsearch将会自动生成_id
{"name":"zhaosi"} //请求体
{"update":{"_index":"lib","_type":"books","_id":"4"}} //更新动作不能缺失_id,文档不存在更新将会失败
{"doc":{"price":58}} //请求体
bluk一次最大处理多少数据量
bulk会将要处理的数据载入内存中,所以数据量是有限的,最佳的数据两不是一个确定的数据,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载。
一般建议是1000-5000个文档,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件(即$ES_HOME下的config下的elasticsearch.yml)中,bulk的线程池配置是内核数+1。
Update API可以根据提供的脚本更新文档。 该操作从索引获取文档,运行脚本(脚本语言和参数是可选的),并返回操作的结果(也允许删除或忽略该操作)。 使用版本控制来确保在“get”(查询文档)和“reindex”(重新索引文档)期间没有发生更新。
值得注意的是,该操作会重新索引文档(也就是说更新操作会先查文档,对文档合并,删除之前的文档,重新添加合并的文档。),它只是减少了网络往返以及减少了get(获取文档)和index(索引文档)之间版本冲突的可能性。 需要启用_source字段才能使此特性生效。
比如,索引一个简单的文档:
PUT test/_doc/1 { "counter" : 1, "tags" : ["red"] }
以下示例演示了如何执行一个增加counter的脚本:
POST test/_doc/1/_update { "script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } } }
现在我们就可以往tags列表里添加一个tag(注意,如果tag存在,仍会添加,因为它是一个list)
POST test/_doc/1/_update { "script" : { "source": "ctx._source.tags.add(params.tag)", "lang": "painless", "params" : { "tag" : "blue" } } }
不止_source,以下变量也可以通过ctx来取得: _index, _type, _id, _version, _routing and _now(当前的时间戳)
以下示例演示了如何获取_id,比如:
POST test/_doc/1/_update { "script" : "ctx._source.tags.add(ctx._id)" }
也可以向文档添加新字段:
POST test/_doc/1/_update { "script" : "ctx._source.new_field = 'value_of_new_field'" }
从文档移除某个字段:
POST test/_doc/1/_update { "script" : "ctx._source.remove('new_field')" }
甚至可以改变已执行的操作。 以下示例:如果标签字段包含green,将删除doc,否则它不执行任何操作(即该操作会被忽略,返回noop):
POST test/_doc/1/_update { "script" : { "source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }", "lang": "painless", "params" : { "tag" : "green" } } }
update API还支持传递部分文档,该部分文档将合并到现有文档中(简单的递归合并,对象的内部合并,替换核心”keys/values”和数组)。 要完全替换现有文档,应使用index API。 以下示例演示了如何使用部分更新向现有文档添加新字段:
POST test/_doc/1/_update { "doc" : { "name" : "new_name" } }
如果同时指定了doc和script,会报错。 最好是将部分文档的字段对放在脚本本身中(目前我还不知道该怎么操作)。
POST test/_doc/1/_update { "doc" : { "age" : "18" }, "script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } } }
返回结果如下:
{ "error": { "root_cause": [ { "type": "action_request_validation_exception", "reason": "Validation Failed: 1: can't provide both script and doc;" } ], "type": "action_request_validation_exception", "reason": "Validation Failed: 1: can't provide both script and doc;" }, "status": 400 }
检测noop更新
如果指定了doc,则其值将与现有_source合并。 默认情况下,不更改任何内容的更新,会检测到并会返回“result”:“noop”,如下所示:
POST test/_doc/1/_update { "doc" : { "name" : "new_name" } }
如果在发送请求之前name是new_name,则忽略整个更新请求。 如果请求被忽略,响应中的result元素将返回noop。
{ "_index": "test", "_type": "_doc", "_id": "1", "_version": 2, "result": "noop", "_shards": { "total": 0, "successful": 0, "failed": 0 } }
设置”detect_noop”: false可以禁用这种默认行为:
POST test/_doc/1/_update { "doc" : { "name" : "new_name" }, "detect_noop": false }
如果文档尚不存在,则upsert元素的内容将作为新文档插入。 如果文档确实存在,则执行脚本:
POST test/_doc/1/_update { "script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } }, "upsert" : { "counter" : 1 } }
scripted_upsert
如果希望无论文档是否存在,都运行脚本(即使用脚本处理初始化文档而不是upsert元素)可以将scripted_upsert设置为true:
POST sessions/session/dh3sgudg8gsrgl/_update { "scripted_upsert":true, "script" : { "id": "my_web_session_summariser", "params" : { "pageViewEvent" : { "url":"foo.com/bar", "response":404, "time":"2014-01-01 12:32" } } }, "upsert" : {} }
下面来看看和直接写脚本不用upsert的区别,当文档不存在时,直接下面这样写会报错。
POST test/_doc/1/_update { "scripted_upsert":true, "script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } } }
返回错误消息如下:
{ "error": { "root_cause": [ { "type": "document_missing_exception", "reason": "[_doc][1]: document missing", "index_uuid": "YgmlkeEERGm20yUBDJHKtQ", "shard": "3", "index": "test" } ], "type": "document_missing_exception", "reason": "[_doc][1]: document missing", "index_uuid": "YgmlkeEERGm20yUBDJHKtQ", "shard": "3", "index": "test" }, "status": 404 }
设置scripted_upsert:true,当文档不存在时,执行下面的代码:
POST test/_doc/1/_update { "scripted_upsert":true, "script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } }, "upsert" : { "counter" : 10 } }
返回的结果如下:
{ "_index": "test", "_type": "_doc", "_id": "1", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 6, "_primary_term": 1 }
可见,执行成功了,下面来看看文档:
{ "_index": "test", "_type": "_doc", "_id": "1", "_version": 1, "found": true, "_source": { "counter": 14 } }
counter的值为14,可见是先执行了upsert的内容,然后执行了脚本。
doc_as_upsert
将doc_as_upsert设置为true将使用doc的内容作为upsert值,而不是发送部分doc加上upsert文档:
POST test/_doc/1/_update { "doc" : { "name" : "new_name" }, "doc_as_upsert" : true }
下面来看看和直接写doc的区别:
POST test/_doc/1/_update { "doc" : { "name" : "new_name" } }
当文档不存在时,设置doc_as_upsert为true,可以成功执行。而上面这种情况会报错,提示文档不存在。如果向下面这样写会出现什么情况呢?
POST test/_doc/1/_update { "doc" : { "name" : "new_name" }, "upsert" : { "counter" : 10 }, "doc_as_upsert" : true }
结果是upsert永远不会被执行,不管文档存在不存在,始终执行的是doc的内容。
转载: https://www.cnblogs.com/ginb/p/9413382.html
主键:
所谓主键就是能够唯一标识表中某一行的属性或属性组,一个表只能有一个主键,是唯一性索引。书大家都看过吧,每页有个页码,我们的数据表主键就相当于是这个页码。
索引:
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。索引相当于书的目录,有了目录我们可以很快的知道这本书的基本内容和结构,数据索引也一样,它可以加快数据表的查询速度。
主键是索引的一种,唯一性索引。
MySql查看数据库中所有表的创建时间等信息:
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ‘数据库名’ ORDER BY create_time DESC;