首页 文章 精选 留言 我的

精选列表

搜索[全文检索],共9733篇文章
优秀的个人博客,低调大师

sql优化-检索及定位

一、执行频率早知道 >show status; 使用showstatus了解各种sql的执行频率 可搭配参数global全局查看,或者session当前连接开始计数默认不加参数是指查看当前连接 showstatus; +-----------------------------------------------+----------------+ |Variable_name|Value| +-----------------------------------------------+----------------+ |Aborted_clients|65| |Aborted_connects|589| |Binlog_cache_disk_use|0| |Binlog_cache_use|0| |Binlog_stmt_cache_disk_use|0| |Binlog_stmt_cache_use|0| |Bytes_received|1649| |Bytes_sent|11767| |Com_admin_commands|0| |Com_assign_to_keycache|0| |Com_alter_db|0| |Com_alter_db_upgrade|0| ... >常见的统计参数 Com_select:执行select操作的次数,一次只累加1 Com_insert:执行insert操作的次数,一次也只累加1 Com_update:执行update操作的次数 Com_delete:执行delete的次数 Innodb_rows_readselect查询的返回的行数 Innodb_rows_inserted执行INSERT操作插入的行数 Innodb_rows_updated执行update操作更新的行数 Innodb_rows_deleted执行deleted操作删除的行数 Connections:试图连接MYSQL服务器的次数。 Uptime服务器工作时间。 Slow_queries慢查询的次数。 >查看慢查询次数 mysql>showglobalstatuslike'Slow_queries'; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |Slow_queries|4| +---------------+-------+ 1rowinset(0.00sec) 二、效率较低早查询 >开启慢查询日志 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间通过long_query_time值来设定,超过这个值则会被记录到慢查询日志中。long_query_time的默认值为10,默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数,当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。 1>查看是否开启忙日志查询 showvariableslike'%slow_query_log%'; 2>开启满日志查询 1.配置文件修改 log-slow-queries=/usr/local/mysql/var/slowquery.log long_query_time=3#单位是秒 log-queries-not-using-indexes 2.使用sql语句修改 setgloballog_slow_queries=ON; setglobalslow_query_log=ON; setgloballong_query_time=0.01#单位是秒 3>慢日志格式 select*fromauction1.userwhereuser_name='liaoxz'; 执行的慢查询语句 #Time:1704274:41:48 日志记录的时间 #User@Host:root[root]@localhost[] 服务器用户/主机名 #Query_time:10.007816Lock_time:0.000000Rows_sent:1Rows_examined:0 总的查询时间、锁定时间、"发送"或者返回的行数、查询过程中所检查的行数 三、分析语句早实行 >show profiles profiling在mysql中默认是关闭的,在数据库会话级别可以打开,开启之后会收集在执行语句时候所使用的资源 在会话打开profilinges setprofiling=1; >使用show profiles查看执行的语句的持续时间和ID MariaDB[auction1]>showprofiles; +----------+------------+------------------------------------------------------------------------------------------------------------------+ |Query_ID|Duration|Query| +----------+------------+------------------------------------------------------------------------------------------------------------------+ |6|0.00038804|select*fromorderslimit1| |7|0.00019379|select*fromorderslimit1| |8|0.00028797|select*fromuserlimit1| |9|0.00006671|select*fromordersrightuserwhereorders.ID=user.id| |10|0.00336970|selectorders*.user.idfromwhereorders.ID=user.id| |11|0.00005291|selectorders*,user.idfromwhereorders.ID=user.id| |12|0.00004725|selectorders*,user.idfromorders,userwhereorders.ID=user.id| |13|0.00003863|selectorders*,user.idfromorders,userwhereorders.ID=user.id| |14|0.00024284|select*fromorderslimit1| |15|0.00027788|select*fromorderslimit10| |16|0.00007312|select*fromuserwhereuser='liaoxz'; select*fromuserwhereuser='liaoxz'| |17|0.00031860|select*fromuserlimit1| |18|0.02771239|select*fromuserwhereuser_name='liaoxz'| |19|0.03121868|select*fromuserwhereuser_name='liaoxz'| |20|0.02219678|select*fromuserwhereuser_name='liaoxz'| +----------+------------+------------------------------------------------------------------------------------------------------------------+ 15rowsinset(0.00sec) >通过指定ID查询执行时的持续时间 MariaDB[auction1]>showprofileforquery20; +----------------------+----------+ |Status|Duration| +----------------------+----------+ |starting|0.000038| |checkingpermissions|0.000005| |Openingtables|0.000010| |Afteropeningtables|0.000004| |Systemlock|0.000002| |Tablelock|0.000002| |Aftertablelock|0.000004| |init|0.000035| |optimizing|0.000011| |statistics|0.000013| |preparing|0.000008| |executing|0.000002| |Sendingdata|0.021981| |end|0.000012| |queryend|0.000004| |closingtables|0.000007| |freeingitems|0.000006| |updatingstatus|0.000019| |loggingslowquery|0.000032| |cleaningup|0.000002| +----------------------+----------+ 20rowsinset(0.00sec) >具体资源耗费查询(all,cpu,block io,context switch,page faults) MariaDB[auction1_1]>showprofilecpuforquery20; +----------------------+----------+----------+------------+ |Status|Duration|CPU_user|CPU_system| +----------------------+----------+----------+------------+ |starting|0.000038|0.000000|0.000000| |checkingpermissions|0.000005|0.000000|0.000000| |Openingtables|0.000010|0.000000|0.000000| |Afteropeningtables|0.000004|0.000000|0.000000| |Systemlock|0.000002|0.000000|0.000000| |Tablelock|0.000002|0.000000|0.000000| |Aftertablelock|0.000004|0.000000|0.000000| |init|0.000035|0.000000|0.000000| |optimizing|0.000011|0.000000|0.000000| |statistics|0.000013|0.000000|0.000000| |preparing|0.000008|0.000000|0.000000| |executing|0.000002|0.000000|0.000000| |Sendingdata|0.021981|0.026852|0.000000| |end|0.000012|0.000000|0.000000| |queryend|0.000004|0.000000|0.000000| |closingtables|0.000007|0.000000|0.000000| |freeingitems|0.000006|0.000000|0.000000| |updatingstatus|0.000019|0.000000|0.000000| |loggingslowquery|0.000032|0.000000|0.000000| |cleaningup|0.000002|0.000000|0.000000| +----------------------+----------+----------+------------+ 20rowsinset(0.00sec) 四、常见show命令大全 >sql show大全 >1. show tables/show tables from database_name; -- 显示当前数据库中所有表的名称。 >2. show databases; -- 显示mysql中所有数据库的名称。 >3. show columns from table_name from database_name; 或show columns from database_name.table_name; -- 显示表中列名称。 >4. show grants for user_name; -- 显示一个用户的权限,显示结果类似于grant 命令。 >5. show index from table_name; -- 显示表的索引。 >6. show variables; -- 显示系统变量的名称和值。 >7. show processlist; -- 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。 >8. show table status; -- 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间。 >9. show privileges; -- 显示服务器所支持的不同权限。 >10. show create database database_name; -- 显示create database 语句是否能够创建指定的数据库。 >11. show create table table_name; -- 显示create database 语句是否能够创建指定的数据库。 >12. show engines; -- 显示安装以后可用的存储引擎和默认引擎。 >13. show innodb status; -- 显示innoDB存储引擎的状态。 >14. show logs; -- 显示BDB存储引擎的日志。 >15. show warnings; -- 显示最后一个执行的语句所产生的错误、警告和通知。 >16. show errors; -- 只显示最后一个执行语句所产生的错误。 >17. show [storage] engines; --显示安装后的可用存储引擎和默认引擎。 五、mysql配置文件来一套 >配置文件/etc/my.cnf [client] port=3306 socket=/tmp/mysql.sock default-character-set=utf8 [mysqld] default-time-zone='+8:00' server-id=9527 user=mysql #bin-log日志相关优化参数 log-bin=mysql-master-bin #混合模式复制 binlog_format=mixed #存储二进制缓存 binlog_cache_size=16M #bin-log日志保存多长时间 expire_logs_days=7 #最大连接数 max_connections=1000 #事务提交或事务外的指令把日志写入(flush)硬盘 innodb_flush_log_at_trx_commit=1 #文件系统自动识别缓存大小是否写入磁盘 sync_binlog=0 datadir=/data/mysqldb port=3306 socket=/tmp/mysql.sock #table_cache=5000 #缓存大小设置 query_cache_size=256M #单个查询使用多大缓冲区 query_cache_limit=16M #内存表大小 max_heap_table_size=128M #线程池大小 thread_cache_size=128 #慢查询超过多长时间写入日志 long_query_time=3 #临时表大小 tmp_table_size=128M #设置索引缓冲区大小 key_buffer_size=256M #数据包大小接受设置 max_allowed_packet=64M #索引扫描,范围索引扫描,无索引全表扫描的表连接缓存的大小 join_buffer_size=16M #排序会话的缓存大小 sort_buffer_size=16M #顺序读表缓存 read_buffer_size=16M #随机读缓冲区大小 read_rnd_buffer_size=64M #缓存innodb表的索引,数据,插入数据时的缓冲 innodb_buffer_pool_size=6G sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid #timestamp类型的列明确的注明default值 explicit_defaults_for_timestamp=true #禁止域名解析 skip-name-resolve #数据库是否支持符号链接存储,1为允许 symbolic-links=0 #数据库级的字符集,对之前数据不产生影响 character-set-server=utf8mb4 #大小写铭感 lower_case_table_names=1 服务器关闭非交互连接之前等待活动的秒数 wait_timeout=180 #闭一个交互的连接之前所要等待的秒数 interactive_timeout=180

优秀的个人博客,低调大师

elasticsearch 拼音检索能力研究

gitchennan/elasticsearch-analysis-lc-pinyin 配置参数少,功能满足需求。 对应版本 elasticsearch2.3.2 对应 elasticsearch-analysis-lc-pinyin 分支 2.4.2.1 或者 tag 2.2.2.1 创建一个类型 elasticsearch-analysis-lc-pinyin 的 README 是根据 elasticsearch5.0 编写的,给出的创建一个类型的语法如下 curl -XPOST http://localhost:9200/index/_mapping/brand -d' { "brand": { "properties": { "name": { "type": "text", "analyzer": "lc_index", "search_analyzer": "lc_search", "term_vector": "with_positions_offsets" } } } }' type=text 是 elasticsearch5.0 之后的类型,所以无法创建成功,稍作修改 type=text,使用如下语法创建一个类型 curl -XPOST http://localhost:9200/index/_mapping/brand -d' { "brand": { "properties": { "name": { "type": "string", "analyzer": "lc_index", "search_analyzer": "lc_search", "term_vector": "with_positions_offsets" } } } }' index 索引结构如下 { "index": { "aliases": {}, "mappings": { "brand": { "properties": { "name": { "type": "string", "term_vector": "with_positions_offsets", "analyzer": "lc_index", "search_analyzer": "lc_search" } } } }, "settings": { "index": { "creation_date": "1490152096129", "number_of_shards": "5", "number_of_replicas": "1", "uuid": "Lp1sSHGhQZyZ57LKO5KwRQ", "version": { "created": "2030299" } } }, "warmers": {} } } 存入几条数据 curl -XPOST http://localhost:9200/index/brand/1 -d'{"name":"百度"}' curl -XPOST http://localhost:9200/index/brand/8 -d'{"name":"百度糯米"}' curl -XPOST http://localhost:9200/index/brand/2 -d'{"name":"阿里巴巴"}' curl -XPOST http://localhost:9200/index/brand/3 -d'{"name":"腾讯科技"}' curl -XPOST http://localhost:9200/index/brand/4 -d'{"name":"网易游戏"}' curl -XPOST http://localhost:9200/index/brand/9 -d'{"name":"大众点评"}' curl -XPOST http://localhost:9200/index/brand/10 -d'{"name":"携程旅行网"}' 查出目前的所有数据 http://localhost:9200/index/_search { "took": 70, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 7, "max_score": 1, "hits": [ { "_index": "index", "_type": "brand", "_id": "8", "_score": 1, "_source": { "name": "百度糯米" } }, { "_index": "index", "_type": "brand", "_id": "9", "_score": 1, "_source": { "name": "大众点评" } }, { "_index": "index", "_type": "brand", "_id": "10", "_score": 1, "_source": { "name": "携程旅行网" } }, { "_index": "index", "_type": "brand", "_id": "2", "_score": 1, "_source": { "name": "阿里巴巴" } }, { "_index": "index", "_type": "brand", "_id": "4", "_score": 1, "_source": { "name": "网易游戏" } }, { "_index": "index", "_type": "brand", "_id": "1", "_score": 1, "_source": { "name": "百度" } }, { "_index": "index", "_type": "brand", "_id": "3", "_score": 1, "_source": { "name": "腾讯科技" } } ] } } 插件自带分词器 lc_index 原文:lc_index : 该分词器用于索引数据时指定,将中文转换为全拼和首字,同时保留中文 分词器分词效果 curl -X POST -d '{ "analyzer" : "lc_index", "text" : ["刘德华"] }' "http://localhost:9200/lc/_analyze" { "tokens": [ { "token": "刘", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "l", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "德", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "d", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "华", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "h", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 } ] } 插件自带分词器 lc_search 原文:lc_search: 该分词器用于拼音搜索时指定,按最小拼音分词个数拆分拼音,优先拆分全拼 curl -X POST -d '{ "analyzer" : "lc_search", "text" : ["刘德华"] }' "http://localhost:9200/index/_analyze" { "tokens": [ { "token": "刘", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "德", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "华", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 } ] } 拼音全拼 搜索 baidu,结果正确 curl -X POST -d '{ "query": { "match": { "name": { "query": "baidu", "analyzer": "lc_search", "type": "phrase" } } }, "highlight" : { "pre_tags" : ["<tag1>"], "post_tags" : ["</tag1>"], "fields" : { "name" : {} } } }' "http://localhost:9200/index/brand/_search" { "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 2, "max_score": 1.4054651, "hits": [ { "_index": "index", "_type": "brand", "_id": "8", "_score": 1.4054651, "_source": { "name": "百度糯米" }, "highlight": { "name": [ "<tag1>百度</tag1>糯米" ] } }, { "_index": "index", "_type": "brand", "_id": "1", "_score": 0.38356602, "_source": { "name": "百度" }, "highlight": { "name": [ "<tag1>百度</tag1>" ] } } ] } } 单字拼音全拼与中文混合 搜索 xie程lu行,结果正确 { "took": 11, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 2.459564, "hits": [ { "_index": "index", "_type": "brand", "_id": "10", "_score": 2.459564, "_source": { "name": "携程旅行网" }, "highlight": { "name": [ "<tag1>携程旅行</tag1>网" ] } } ] } } 单字拼音首字母与中文混合 搜索 携cl行,结果正确 curl -X POST -d '{ "query": { "match": { "name": { "query": "携cl行", "analyzer": "lc_search", "type": "phrase" } } }, "highlight" : { "pre_tags" : ["<tag1>"], "post_tags" : ["</tag1>"], "fields" : { "name" : {} } } }' "http://localhost:9200/index/brand/_search" { "took": 6, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 2.459564, "hits": [ { "_index": "index", "_type": "brand", "_id": "10", "_score": 2.459564, "_source": { "name": "携程旅行网" }, "highlight": { "name": [ "<tag1>携程旅行</tag1>网" ] } } ] } } 拼音首字母 搜索 albb,结果正确 curl -X POST -d '{ "query": { "match": { "name": { "query": "albb", "analyzer": "lc_search", "type": "phrase" } } }, "highlight" : { "pre_tags" : ["<tag1>"], "post_tags" : ["</tag1>"], "fields" : { "name" : {} } } }' "http://localhost:9200/index/brand/_search" { "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 2.828427, "hits": [ { "_index": "index", "_type": "brand", "_id": "2", "_score": 2.828427, "_source": { "name": "阿里巴巴" }, "highlight": { "name": [ "<tag1>阿里巴巴</tag1>" ] } } ] } } 结论 elasticsearch-analysis-lc-pinyin 按照全拼、首字母,拼音中文混合搜索 elasticsearch-analysis-pinyin v1.7.2 github 项目 elasticsearch-analysis-pinyin v1.7.2 完全是为 elasticsearch 2.3.2 服务 first_letter 改变 first_letter=prefix padding_char=" " curl -X POST -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin", "filter" : ["word_delimiter"] } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "first_letter" : "prefix", "padding_char" : " " } } } } } }' "http://localhost:9200/medcl" 拼音效果如下 curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl/_analyze" { "tokens": [ { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 0 }, { "token": "liu", "start_offset": 0, "end_offset": 3, "type": "word", "position": 1 }, { "token": "de", "start_offset": 0, "end_offset": 3, "type": "word", "position": 2 }, { "token": "hua", "start_offset": 0, "end_offset": 3, "type": "word", "position": 3 } ] } first_letter=append padding_char=" " curl -X POST -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin", "filter" : ["word_delimiter"] } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "first_letter" : "append", "padding_char" : " " } } } } } }' "http://localhost:9200/medcl2" 拼音效果如下 curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl2/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 3, "type": "word", "position": 0 }, { "token": "de", "start_offset": 0, "end_offset": 3, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 0, "end_offset": 3, "type": "word", "position": 2 }, { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 3 } ] } first_letter=only padding_char=" " curl -X POST -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin", "filter" : ["word_delimiter"] } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "first_letter" : "only", "padding_char" : " " } } } } } }' "http://localhost:9200/medcl3" 拼音效果如下 curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: 67015c0d-cd07-961b-4c46-da90f7d558d8" -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl3/_analyze" { "tokens": [ { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 0 } ] } first_letter=none padding_char=" " curl -X POST -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin", "filter" : ["word_delimiter"] } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "first_letter" : "none", "padding_char" : " " } } } } } }' "http://localhost:9200/medcl4" 拼音效果如下 curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl4/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 3, "type": "word", "position": 0 }, { "token": "de", "start_offset": 0, "end_offset": 3, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 0, "end_offset": 3, "type": "word", "position": 2 } ] } padding_char 改变 first_letter=prefix padding_char="" curl -X POST -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin", "filter" : ["word_delimiter"] } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "first_letter" : "prefix", "padding_char" : "" } } } } } }' "http://localhost:9200/medcl5" 拼音效果如下 curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl5/_analyze" { "tokens": [ { "token": "ldhliudehua", "start_offset": 0, "end_offset": 3, "type": "word", "position": 0 } ] } first_letter=append padding_char="" curl -X PUT -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin", "filter" : ["word_delimiter"] } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "first_letter" : "append", "padding_char" : "" } } } } } }' "http://localhost:9200/medcl7" 拼音效果如下 curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl7/_analyze" { "tokens": [ { "token": "liudehualdh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 0 } ] } first_letter=only padding_char="" curl -X PUT -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin", "filter" : ["word_delimiter"] } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "first_letter" : "only", "padding_char" : "" } } } } } }' "http://localhost:9200/medcl8" 拼音效果如下 curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl8/_analyze" { "tokens": [ { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 0 } ] } first_letter=none padding_char="" curl -X PUT -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin", "filter" : ["word_delimiter"] } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "first_letter" : "none", "padding_char" : "" } } } } } }' "http://localhost:9200/medcl9" 拼音效果如下 curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl9/_analyze" { "tokens": [ { "token": "liudehua", "start_offset": 0, "end_offset": 3, "type": "word", "position": 0 } ] } 结论 elasticsearch 2.3.2 对应 elasticsearch-analysis-pinyin 1.7.2,pinyin 1.7.2 可配置参数有:first_letter 和 padding_char。 padding_char 的作用是将字符串按照什么字符分隔,比如 padding_char = " ",那么 刘德华 将先被分隔为 刘,德,华;如果 padding_char = "",那么 刘德华 将不会被分隔 first_letter 取值:prefix,append,only,none。 padding_char 与 first_letter 的组合会影响拼音输出的结果 elasticsearch-analysis-pinyin 2.x 分支 github 项目 elasticsearch-analysis-pinyin 2.x 分支 是为 elasticsearch 2.x 服务,经过测试 elasticsearch 2.3.2 也可以使用该插件。 官方文档中的说明 remove_duplicated_term when this option enabled, duplicated term will be removed to save index, eg: de的>de, default: false, NOTE: position related query maybe influenced keep_first_letter when this option enabled, eg: 刘德华>ldh, default: true keep_separate_first_letter when this option enabled, will keep first letters separately, eg: 刘德华>l,d,h, default: false, NOTE: query result maybe too fuzziness due to term too frequency limit_first_letter_length set max length of the first_letter result, default: 16 keep_full_pinyin when this option enabled, eg: 刘德华> [liu,de,hua], default: true keep_joined_full_pinyin when this option enabled, eg: 刘德华> [liudehua], default: false keep_none_chinese keep non chinese letter or number in result, default: true keep_none_chinese_together keep non chinese letter together, default: true, eg: DJ音乐家 -> DJ,yin,yue,jia, when set to false, eg: DJ音乐家 -> D,J,yin,yue,jia, NOTE: keep_none_chinese should be enabled first keep_none_chinese_in_first_letter keep non Chinese letters in first letter, eg: 刘德华AT2016->ldhat2016, default: true none_chinese_pinyin_tokenize break non chinese letters into separate pinyin term if they are pinyin, default: true, eg: liudehuaalibaba13zhuanghan -> liu,de,hua,a,li,ba,ba,13,zhuang,han, NOTE: keep_none_chinese and keep_none_chinese_together should be enabled first keep_original when this option enabled, will keep original input as well, default: false lowercase lowercase non Chinese letters, default: true trim_whitespace default: true 基准配置 基准配置参数 "keep_joined_full_pinyin": "false", "lowercase": "true", "keep_original": "false", "keep_none_chinese_together": "true", "remove_duplicated_term": "false", "keep_first_letter": "true", "keep_separate_first_letter": "false", "trim_whitespace": "true", "keep_none_chinese": "true", "limit_first_letter_length": "16", "keep_full_pinyin": "true" 创建索引与分词器 curl -X POST -d '{ "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "pinyin_analyzer" : { "tokenizer" : "my_pinyin" } }, "tokenizer" : { "my_pinyin" : { "type" : "pinyin", "remove_duplicated_term" : false, "keep_joined_full_pinyin" : false, "keep_separate_first_letter" : false, "keep_first_letter" : true, "limit_first_letter_length" : 16, "keep_full_pinyin" : true, "keep_original" : true, "keep_none_chinese" : true, "keep_none_chinese_together" : true, "lowercase" : true, "trim_whitespace" : true } } } } } }' "http://localhost:9200/medcl20" 生成索引结构 curl -X GET "http://localhost:9200/medcl20" { "medcl20": { "aliases": {}, "mappings": { "folk": { "properties": { "text": { "type": "string", "analyzer": "pinyin_analyzer" } } } }, "settings": { "index": { "creation_date": "1490170676090", "analysis": { "analyzer": { "pinyin_analyzer": { "tokenizer": "my_pinyin" } }, "tokenizer": { "my_pinyin": { "keep_joined_full_pinyin": "false", "lowercase": "true", "keep_original": "true", "keep_none_chinese_together": "true", "remove_duplicated_term": "false", "keep_first_letter": "true", "keep_separate_first_letter": "false", "trim_whitespace": "true", "type": "pinyin", "keep_none_chinese": "true", "limit_first_letter_length": "16", "keep_full_pinyin": "true" } } }, "number_of_shards": "5", "number_of_replicas": "1", "uuid": "31Y9PizQQ2KQn_Fl6bpPNw", "version": { "created": "2030299" } } }, "warmers": {} } } 分词器分词效果 curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl20/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "刘德华", "start_offset": 0, "end_offset": 3, "type": "word", "position": 3 }, { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 4 } ] } keep_original keep_original = true curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl20/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "刘德华", "start_offset": 0, "end_offset": 3, "type": "word", "position": 3 }, { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 4 } ] } keep_original = false curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl20/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 3 } ] } keep_original 功能 keep_original=true 将保留原字符串,比如存入索引的数据为 刘德华 那么 刘德华 将也会被保存到索引中。keep_original=false 则不保存原字符串到索引 trim_whitespace trim_whitespace=true curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : [" 最爱 刘德华 的帅气帅气的 "] }' "http://localhost:9200/medcl20/_analyze" { "tokens": [ { "token": "zui", "start_offset": 3, "end_offset": 4, "type": "word", "position": 0 }, { "token": "ai", "start_offset": 4, "end_offset": 5, "type": "word", "position": 1 }, { "token": "liu", "start_offset": 8, "end_offset": 9, "type": "word", "position": 2 }, { "token": "de", "start_offset": 9, "end_offset": 10, "type": "word", "position": 3 }, { "token": "hua", "start_offset": 10, "end_offset": 11, "type": "word", "position": 4 }, { "token": "de", "start_offset": 14, "end_offset": 15, "type": "word", "position": 5 }, { "token": "shuai", "start_offset": 15, "end_offset": 16, "type": "word", "position": 6 }, { "token": "qi", "start_offset": 16, "end_offset": 17, "type": "word", "position": 7 }, { "token": "shuai", "start_offset": 17, "end_offset": 18, "type": "word", "position": 8 }, { "token": "qi", "start_offset": 18, "end_offset": 19, "type": "word", "position": 9 }, { "token": "de", "start_offset": 19, "end_offset": 20, "type": "word", "position": 10 }, { "token": "最爱 刘德华 的帅气帅气的", "start_offset": 0, "end_offset": 23, "type": "word", "position": 11 }, { "token": "zaldhdsqsqd", "start_offset": 0, "end_offset": 11, "type": "word", "position": 12 } ] } trim_whitespace=false curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : [" 最爱 刘德华 的帅气帅气的 "] }' "http://localhost:9200/medcl20/_analyze" { "tokens": [ { "token": "zui", "start_offset": 3, "end_offset": 4, "type": "word", "position": 0 }, { "token": "ai", "start_offset": 4, "end_offset": 5, "type": "word", "position": 1 }, { "token": "liu", "start_offset": 8, "end_offset": 9, "type": "word", "position": 2 }, { "token": "de", "start_offset": 9, "end_offset": 10, "type": "word", "position": 3 }, { "token": "hua", "start_offset": 10, "end_offset": 11, "type": "word", "position": 4 }, { "token": "de", "start_offset": 14, "end_offset": 15, "type": "word", "position": 5 }, { "token": "shuai", "start_offset": 15, "end_offset": 16, "type": "word", "position": 6 }, { "token": "qi", "start_offset": 16, "end_offset": 17, "type": "word", "position": 7 }, { "token": "shuai", "start_offset": 17, "end_offset": 18, "type": "word", "position": 8 }, { "token": "qi", "start_offset": 18, "end_offset": 19, "type": "word", "position": 9 }, { "token": "de", "start_offset": 19, "end_offset": 20, "type": "word", "position": 10 }, { "token": " 最爱 刘德华 的帅气帅气的 ", "start_offset": 0, "end_offset": 23, "type": "word", "position": 11 }, { "token": "zaldhdsqsqd", "start_offset": 0, "end_offset": 11, "type": "word", "position": 12 } ] } trim_whitespace 功能 去除字符串首尾空格字符,不去除字符串中间的空格。这个参数只有当 keep_original=true 时才能够看到效果。 例如当字符串为:最爱 刘德华 的帅气帅气的,trim_whitespace=true 则原字符串将被保存为 最爱 刘德华 的帅气帅气的,如果 trim_whitespace=false 则原字符串将被保存为 最爱 刘德华 的帅气帅气的。如果 keep_original=false,那么原字符串没有被保存,也将看不到效果。 keep_joined_full_pinyin keep_joined_full_pinyin = false curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl21/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "刘德华", "start_offset": 0, "end_offset": 3, "type": "word", "position": 3 }, { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 4 } ] } keep_joined_full_pinyin = true curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华"] }' "http://localhost:9200/medcl22/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "刘德华", "start_offset": 0, "end_offset": 3, "type": "word", "position": 3 }, { "token": "liudehua", "start_offset": 0, "end_offset": 8, "type": "word", "position": 4 }, { "token": "ldh", "start_offset": 0, "end_offset": 3, "type": "word", "position": 5 } ] } keep_joined_full_pinyin 功能 keep_joined_full_pinyin=true 将保存字符串拼音全拼,false 则不保存。例如,当 kepp_joined_full_pinyin=true 时,文本 刘德华 的拼音全拼 liudehua 将会被保留;当 keep_joined_full_pinyin=false 则 全拼liudehua remove_duplicated_term remove_duplicated_term = false curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华刘德华帅帅帅,帅帅帅"] }' "http://localhost:9200/medcl20/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "liu", "start_offset": 3, "end_offset": 4, "type": "word", "position": 3 }, { "token": "de", "start_offset": 4, "end_offset": 5, "type": "word", "position": 4 }, { "token": "hua", "start_offset": 5, "end_offset": 6, "type": "word", "position": 5 }, { "token": "shuai", "start_offset": 6, "end_offset": 7, "type": "word", "position": 6 }, { "token": "shuai", "start_offset": 7, "end_offset": 8, "type": "word", "position": 7 }, { "token": "shuai", "start_offset": 8, "end_offset": 9, "type": "word", "position": 8 }, { "token": "shuai", "start_offset": 10, "end_offset": 11, "type": "word", "position": 9 }, { "token": "shuai", "start_offset": 11, "end_offset": 12, "type": "word", "position": 10 }, { "token": "shuai", "start_offset": 12, "end_offset": 13, "type": "word", "position": 11 }, { "token": "刘德华刘德华帅帅帅,帅帅帅", "start_offset": 0, "end_offset": 13, "type": "word", "position": 12 }, { "token": "ldhldhssssss", "start_offset": 0, "end_offset": 12, "type": "word", "position": 13 } ] } remove_duplicated_term = true curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华刘德华帅帅帅,帅帅帅"] }' "http://localhost:9200/medcl26/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "shuai", "start_offset": 6, "end_offset": 7, "type": "word", "position": 3 }, { "token": "刘德华刘德华帅帅帅,帅帅帅", "start_offset": 0, "end_offset": 13, "type": "word", "position": 4 }, { "token": "ldhldhssssss", "start_offset": 0, "end_offset": 12, "type": "word", "position": 5 } ] } remove_duplicated_term 功能 remove_duplicated_term=true 则会将文本中相同的拼音只保存一份,比如 刘德华刘德华 只会保留一份拼音 liu,de,hua;相对的 remove_duplicated_term=false 则会保留两份 liu,de,hua。注意:remove_duplicated_term 并不会影响文本首字母的文本,刘德华刘德华 生成的首字母拼音始终都为 ldhldh remove_duplicated_term = true 并且 keep_joined_full_pinyin = true curl -X POST -d '{ "analyzer" : "pinyin_analyzer", "text" : ["刘德华刘德华帅帅帅,帅帅帅"] }' "http://localhost:9200/medcl27/_analyze" { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 1, "end_offset": 2, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 2, "end_offset": 3, "type": "word", "position": 2 }, { "token": "shuai", "start_offset": 6, "end_offset": 7, "type": "word", "position": 3 }, { "token": "刘德华刘德华帅帅帅,帅帅帅", "start_offset": 0, "end_offset": 13, "type": "word", "position": 4 }, { "token": "liudehualiudehuashuaishuaishuaishuaishuaishuai", "start_offset": 0, "end_offset": 46, "type": "word", "position": 5 }, { "token": "ldhldhssssss", "start_offset": 0, "end_offset": 12, "type": "word", "position": 6 } ] } remove_duplicated_term 功能 remove_duplicated_term = true 会过滤相同的拼音,但是不影响全拼,刘德华刘德华 生成的字符串全拼为 liudehualiudehua keep_none_chinese keep_none_chinese = true POST /medcl20/_analyze HTTP/1.1 Host: localhost:9200 { "analyzer" : "pinyin_analyzer", "text" : ["刘*20*德b华DJ"] } { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "20", "start_offset": 3, "end_offset": 5, "type": "word", "position": 1 }, { "token": "de", "start_offset": 5, "end_offset": 6, "type": "word", "position": 2 }, { "token": "b", "start_offset": 6, "end_offset": 7, "type": "word", "position": 3 }, { "token": "hua", "start_offset": 7, "end_offset": 8, "type": "word", "position": 4 }, { "token": "d", "start_offset": 7, "end_offset": 9, "type": "word", "position": 5 }, { "token": "j", "start_offset": 7, "end_offset": 9, "type": "word", "position": 6 }, { "token": "刘*20*德b华dj", "start_offset": 0, "end_offset": 10, "type": "word", "position": 7 }, { "token": "l20dbhdj", "start_offset": 0, "end_offset": 8, "type": "word", "position": 8 } ] } keep_none_chinese = false POST /medcl28/_analyze HTTP/1.1 Host: localhost:9200 { "analyzer" : "pinyin_analyzer", "text" : ["刘*20*德b华DJ"] } { "tokens": [ { "token": "liu", "start_offset": 0, "end_offset": 1, "type": "word", "position": 0 }, { "token": "de", "start_offset": 5, "end_offset": 6, "type": "word", "position": 1 }, { "token": "hua", "start_offset": 7, "end_offset": 8, "type": "word", "position": 2 }, { "token": "刘*20*德b华dj", "start_offset": 0, "end_offset": 10, "type": "word", "position": 3 }, { "token": "l20dbhdj", "start_offset": 0, "end_offset": 8, "type": "word", "position": 4 } ] } keep_none_chinese 功能 keep_none_chinese = true 则非中文字母以及数字将会被保留,但是要确定所有的特别字符都是无法被保留下来的。例如,文本 刘*20*德b华dj 中的数字 20,字母 b 与 dj 将会被保留,而特殊字符 * 是不会保留的;当 keep_none_chinese=false 则非中文字母以及数字将不会被保留,上述文本中的数字 20,字母 b 与 dj 将不会被保留。注意:参数 keep_none_chinese 是不会影响首字母以及所有字符组成全拼的拼音,上述文本生成的首字母拼音为 l20dbhdj,所有字符组成的全拼为:liu20debhuadj,特别字符始终是被过滤去除的。 欢迎转载,请注明本文链接,谢谢你。 2017.4.12 20:44

优秀的个人博客,低调大师

P++ 的想法: 常见问题( 全文翻译 )

关键字 PHP, PPlusPlus, FAQ, Zeev Suraski, internals@ P++ 的想法: 常见问题 原文:https://wiki.php.net/pplusplus/faq 时间: 2019 年 8 月 9 日 作者: Zeev Suraski, zeev@php.net 这是一份对在 internals@译注1上提出的想法的常见问题澄清,它试图解决许多在随后讨论中被反复提出的问题。 注:P++ 是一个临时代码命名,未来可能会变化。 这到底是怎么回事? 试图将冗长的邮件内容浓缩为几点: PHP 世界有两个大的阵营。第一个大致喜欢 PHP 的动态性,带有强烈的 BC译注2偏见,并特别强调简单性,另一个更喜欢减掉包袱,拥有更高级、更复杂功能的更严格的语言。 这里没有“对”或“错”。这两种流派都有效,并具有非常坚定的追随者。然而,创建一种同时迎合这两个阵营的语言则是一项挑战,这也是 internals@ 上争论的一贯的原因。 该提议是创建一种新的 PHP 方言(代码名 P++),与 PHP 并存,但不受语言背后的历史哲学约束。换句话说,这种新方言本质上可能更加严格,它可能会更加大胆地消除向后兼容,并删除被认为是“包袱”的元素(例如短标签),并添加更复杂的特性,尤其是那些非常适合严格类型化的语言的,而无需为 PHP 方言引入相同的复杂性。 这不是 PHP 代码分支。代码库将是同一个,在该代码库上工作的开发人员是相同的。绝大多数代码都是相同的。只有两种方言之间的特定差异点才会有不同的实现。它有点类似于 PHP 7 中的 strict_types 所做的,只是在更大的范围内。 我们真的要做的就是因为有些人不能放弃短标签吗? 这与短标签无关,“弃用短标签 RFC译注3”不是这个想法的主要动力。这个提案的目标是更有野心,它是为 PHP 提供一个清晰的愿景,并希望通过向两个阵营提供他们想要的东西来最终解决两方的紧张关系。 为什么要分叉 PHP? 这不是分叉。 代码库将完全相同,它将由相同的人开发版本。二进制文件将完全相同,如果你安装 PHP,你也将安装 P++,反之亦然。相同的二进制将运行 PHP,P++ 或组合 PHP/P++ 的应用程序。 虽然目前还不清楚如何将一个文件“标记”为 P++ 文件,但它可能是文件顶部的某种特殊标记,例如: <?p++?> <?php 'Hello, world!'; ?> 此外,我们可能会找到将整个命名空间标记为 P++ 的方法,因此,框架不必将每个单独的文件明确标记为 P++。 这意味着我们的开发工作量增加了一倍,而internals@ 的贡献者已经很低(low)了。 我们如何处理? 值得庆幸的是,这并不意味着是那样(工作量增加了一倍)。绝大多数代码将在 PHP 模式和 P++ 模式之间共享——包括源代码和运行时。 无论运行的文件是 PHP 还是 P++文件,数据结构、关键子系统、扩展、Web服务器接口、OPcache 以及其他所有代码都将是完全相同的代码。唯一的额外开发开销会是 PHP 和 P++ 之间的差异部分。 确实,这意味着我们必须维护某些代码片段的两个版本,并且我们在各个地方都会有一些 if() 语句,因为与 PHP 相比,P++ 可能会有额外的检查。 但是,如果我们要转向更严格的 PHP 版本,这些元素无论如何都必须引入。此外,即使是严格阵营中的人,也不建议我们在没有提供迁移途径的情况下转向未来严格版本——实际上,这种方法所涉及的努力和几乎任何其他的方法都是相似的。 当我们转向更严格的 PHP 8/9时, 为什么不只是开发一个永久维护的 PHP 7.4 长期维护版? 这种方法存在许多问题。 即使我们忽视这样一个事实,即这会让庞大的动态偏好阵营悬而未决——没有任何特性或性能更新,从开发工作的角度来看,这是不切实际的。 这与这个提议不同,事实上,这确实意味着事实上的分叉。 我需要在 PHP 和 P++ 之间做出选择吗? 是,也不是。 如上所述,当你安装一个,你就有了另一个,所以就应用而言,你可以在一台服务器上运行这两种方言。 然而,实际上,项目和个人通常可能选择并标准化其中一个,类似于严格类型的情况。 我能在同一个应用程序中混合使用 PHP 和 P++ 吗? 是的。 虽然我们需要确定精确的机制,但代码是 PHP 还是 P++ 的指定将在文件级别,而不是在请求级别。 单个执行(请求)可以加载许多不同的文件,这些文件可以来自两种方言。PHP文件中的代码将表现为 PHP 语义——而来自 P++ 文件的代码将表现为 P++ 语义。 这也是,与 strict_types 类似。 虽然这开始听起来可能听很尴尬,但可能会有非常实用的用例。例如,PHP 应用程序使用的只含 P++ 的框架,反之亦然。 对于那些熟悉 C 和 C++ 的人来说,这有点类似。 这是否意味着 PHP 将不再发展? 所有新功能都会用于 P++ 吗? 不,这只是意味着它会以不同的方式发展。 严格性和类型相关的功能可能只适用于 P++,并且只能在 P++ 文件中使用。向后兼容偏差将保留在 PHP 中(这并不意味着向后兼容永不会被打破,只是每个这样的案例必须有良好的投资回报案例)。 但是,与此无关的功能,例如引擎的性能改进(如 JIT ),扩展的开发,或新的异步相关的功能,PHP 和 P++ 都可以使用。 这个方法有什么好处? 这种方法有很多好处。 首先,它为 internals@ 的两个阵营提供了一个很好的解决方案。 那些喜欢 PHP 动态特性的人可以保留它,而那些喜欢更严格类型语言的人也可以获得它,而不受任何 PHP 限制。 而替代方案是零和游戏,一个阵营的胜利是另一个的失败,反之亦然。 除了设计一个好的技术解决方案(使我们能够以最少的努力支持整个受众)之外,还可以终结近年来 internals@ 上争论的关键根源。 最后,虽然本文档的大多数读者可能是技术人员,但应该注意的是,启动 P++ 将从一个新的基点译注4不计过去重新开始,可能具有巨大的定位和品牌优势。未使用 PHP 的公司、开发经理和个人开发者更有可能注意到 P++ 的推出,而不是 PHP 8.0 或 PHP 9.0 的推出。 我们不是冒着分裂用户群的风险吗? 在某种程度上,我们是。但这不是这一想法的缺陷, 而是现实已经存在的表现。 如上所述,那里有很多人喜欢 PHP 的动态本质,并且谨慎地看待尝试使其越来越多地面向类型。 与此同时,还有另外一群看着 PHP 的人,自己在想:“为什么它变得如此缓慢,以至于我最终要放弃这动态的废材(原文:dynamicnonsense)?” 这里没有对或错。这两种观点都有效。当我们研究在这两个相互矛盾的观点之间架起桥梁的可能的解决方案时,没有太多可用的方案: 坚持使用动态PHP。这将不会被更严格语言的支持者所接受。 向严格的PHP发展。动态语言的支持者不会接受这一点。 分叉代码库。无论如何完成,都是所有参与者的净损失选项。 这样做没有技术优势,即使我们想要(我们不想要),我们也没有足够的贡献者去做。 提出一些创意解决方案,以满足双方观众的需求。 这就是该提案试图做的。它在保持项目本身统一的同时,也确保两种方言之间的永久互操作性。这虽然会有一定程度的碎片化,但它仍然是满足每个人的主要需求的最小可能。 这与 Nikita译注5版本的想法有何不同? 这两个想法之间有许多相似之处,但也存在一些实质性差异。 请注意,这是基于对版本方法的有限理解,因此部分可能缺乏,不准确或不正确。 在这个提议中,有一个明确的目标是保持当前动态类型的 PHP,作为一个长期的,完全支持的,平等的对等方言。 发版本的方法将当前行为视为“遗留”。 这意味着它可能会被劝止(使用),然后在某些时候弃用和删除。 推出策略完全不同。 P++ 提案旨在首先关注兼容性破坏元素,例如严格的操作、类型转换逻辑的更改、数组索引处理、需要变量声明等等,并且旨在在 P++ 的第一期提供它们。这样做的目的是允许新项目/框架重新开始,而不需知道在引入更多兼容性更改时,他们可能不得不在一两年内进行重大改写。 版本化提案似乎没有这样的目标,而是旨在逐步添加/更改 PHP 中的元素。 与推出方式相关,版本化方法不允许只有两种方言,而是任何数量的方言。我们可能有 PHP2020 方言,以及 PHP2022 方言和 PHP2027 方言。 如果我们全部保留它们,实际上这可能会增加我们的维护复杂性。 该提议还提到了 PHP 与 P++(保守与积极)的不同打破向后兼容策略,而版本化方案可能根本不会涉及该主题。 版本提案与此提案的定位/营销方面并不完全相同。 重要的是,要注意这两个想法不一定是相互排斥的。 我们可以介绍 P++ 并使用版本进行改进,特别是当证明很难将所有重要的变化都放到 P++ 的第一期中。 有哪些挑战? 在我们能运行第一个 P++ 应用程序之前,不乏挑战。 我们需要获得支持。这意味着,两派的人都需要放弃让 PHP 完全动态或完全类型化的梦想,而忽略那些与他们想法不同的人。这似乎是一个非常重大的挑战。 为获得成功,P++ 第一个版本应该处理来自 PHP 的所有,或至少大多数兼容性破坏的更改,以便切换(可能相当痛苦)的开发人员不必在未来重新审核/彻底重构他们的代码。一些人表示担心,由于我们的开发人员能力有限,他们可能过于乐观,无法在一期发布。一旦我们对列表的内容有了更好的了解,我们就必须对此进行评估。 请注意,这并不意味着我们需要在第一个期中实现我们可能对 P++ 提出的所有想法,只是我们应该优先考虑会触发大量最终用户代码重写的元素,并尝试在我们的第一版之前处理它们。 当然,最具挑战性的——我们需要为这种新方言找到一个合理的名字。 pplusplus/faq.txt· 最后修改: zeev 于 2019/08/09 21:44 译注 internals@:PHP 内部开发人员邮件列表。这里涉及 PHP 的开发机制,当内部讨论成熟后,会公开在externals,通常用来提交 RFC 和发布版本通知。 BC:即 Backward Compatibility,向后兼容,也叫向下兼容,兼容过去的版本,即升级的软件要考虑旧版本的兼容性,比如,Office 2019 的 Word 默认使用 .docx 文件格式,但也可以打开 Office 2017/2013/2010,甚至是 2003 的 .doc 格式。相对的概念叫做 FC,即 Forward Compatibility,向前兼容,也叫向上兼容,即升级的软件会考虑对未来的兼容性。这在软件中通常为一个确定的接口和约定,未来依然遵循,即可实现向前兼容。 RFC:即 Request for Comments,语言特性的加入,以及标准化变更管理的方法,通常加入新特性时,会为新特性提交 RFC 并给出例子,变更委员会评估通过后,语言会合入实现的源码,并入新版本。 新的基点:a clean slate,美国习语,即不计过去新的开始。 Nikita:一位 internals@ 上的发言者,提议在版本中加入特性。顺便提一句,美剧《Nikita》值得一看。 (本文翻译为笔者原创,限于水平有限,如翻译中有不妥的地方请回复留言,如转载请注明出处:IT桃花岛) 相关文章 PHP 联席架构师辞职,原来他想做 P++…

优秀的个人博客,低调大师

Python-网页转义字符及正则全文匹配

前言 大部分情况下,通过request去请求网页,response.text返回来的都是正常值,但是有一些反爬虫比较严重的网站(比如知乎)就不会是这样。知乎会返回转义字符,例如: header = { "User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0", "HOST":"www.zhihu.com", "Referer":"https://www.zhihu.com/signup?next=%2F", } def rget(): response = session.get("https://www.zhihu.com/signup?next=%2F", headers=header) target_str = response.text print(target_str) rget() 在给知乎的登录页面发请求后,打印返回结果(内容太多,只返回一小部分): &quot;token&quot;:{&quot;xsrf&quot;:&quot;9b6c6406-db1b-45fa-8626-296c037cfc00&quot;,&quot;xUDID&quot;:&quot;ANBsasFlAg2PTgaqB1CHBtsWMijmJ20s89E=&quot;},&quot;account&quot;:{&quot;lockLevel&quot;:{} 发现有很多字符是转义的,登录需要用到的xsrf字段也在这里面,这样做正则匹配就很麻烦。 解决的办法是将html进行转义: import html target_str = html.unescape(response.text) 就能够得到正常的返回信息了: "token":{"xsrf":"9febf0fd-7c47-4695-93b6-f670e518d920","xUDID":"ACDsF5lmAg2PTi2GMwQTl0Cwh88G51BOgzc="}, 正则匹配 匹配xsrf的值 (为了方便测试,只将一小部分值提取出来做匹配): tokens = '"token":{"xsrf":"9febf0fd-7c47-4695-93b6-f670e518d920","xUDID":"ACDsF5lmAg2PTi2GMwQTl0Cwh88G51BOgzc="},:' matchs = re.search(r'xsrf[:"\w-]+', tokens) if matchs: print(matchs.group(0)) else: print("未匹配") 得到输出结果为: xsrf":"9febf0fd-7c47-4695-93b6-f670e518d920" 然后再借用replace将引号替换,然后用split将值用冒号分开: import re tokens = '"token":{"xsrf":"9febf0fd-7c47-4695-93b6-f670e518d920","xUDID":"ACDsF5lmAg2PTi2GMwQTl0Cwh88G51BOgzc="},:' matchs = re.search(r'xsrf[:"\w-]+', tokens) nstr = matchs.group(0).replace("\"", "").split(":") finall = nstr[1] print(finall) 就得到了我需要的xsrf: 9febf0fd-7c47-4695-93b6-f670e518d920 xUDID的提取也是如此,这两个值在知乎登录的时候是需要携带的,所以要提取: import re tokens = '"token":{"xsrf":"9febf0fd-7c47-4695-93b6-f670e518d920","xUDID":"ACDsF5lmAg2PTi2GMwQTl0Cwh88G51BOgzc="},:' matchs = re.search(r'xUDID[:"\w-]+=', tokens) nstr = matchs.group(0).replace("\"", "").split(":") finall = nstr[1] print(finall) ACDsF5lmAg2PTi2GMwQTl0Cwh88G51BOgzc= re正则匹配html的坑 上面的正则可以匹配到字符串了,如果正常登录的话要将请求返回的内容文本进行匹配的,也就是匹配response.text,代码是否就是 matchs = re.search(r'xUDID[:"\w-]+=', response.text) 坑就在这里! re默认匹配的是单行字符串,而response.text的返回值虽然是一个html页面的构成,但是它是分行的,第一行是html头<! DOCUMENT html>不是我想要的整个文本进行匹配。 re是支持整个文本匹配的,需要在正则代码加上参数re.DOTALL即可: matchs = re.search(r'xUDID[:"\w-]+=', response.text, re.DOTALL) 就可以对整个返回的文本进行匹配了

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册