站三界导航
首页 文章资讯
  • 21个常用的JS代码片段,每段代码花30秒就能看懂
    21个常用的JS代码片段,每段代码花30秒就能看懂

    JavaScript是目前最流行的编程语言之一,正如大多数人所说:“如果你想学一门编程语言,请学JavaScript。”FreeCodeCamp的创始人QuincyLarson在最近的一次采访中被问到哪种语言开发人员应该首先学习。他回答:“JavaScript。”“软件正在吞噬世界,JavaScript正在吞噬软件。JavaScript每年都在变得越来越占主导地位,而且没人知道最终会取代它的是什么。"如果您没有充分的理由学习一种新语言(例如您的工作要求您维护非JavaScript代码库),那么我的建议是着重于提高JavaScript的水平。”听我说这么多,你是不是很激动呢。这里有127个常用的JS代码片段,方便你学习和使用。1、all如果数组所有元素满足函数条件,则返回true。调用时,如果省略第二个参数,则默认传递布尔值。constall=(arr,fn=Boolean)=>arr.every(fn);all([4,2,3],x=>x>1);//trueall([1,2,3]);//true2、allEqual判断数组中的元素是否都相等constallEqual=arr=>arr.every(val=>val===arr[0]);allEqual([1,2,3,4,5,6]);//falseallEqual([1,1,1,1]);//true3、approximatelyEqual此代码示例检查两个数字是否近似相等,差异值可以通过传参的形式进行设置constapproximatelyEqual=(v1,v2,epsilon=0.001)=>Math.abs(v1-v2)<epsilon;approximatelyEqual(Math.PI/2.0,1.5708);//true4、arrayToCSV此段代码将没有逗号或双引号的元素转换成带有逗号分隔符的字符串即CSV格式识别的形式。constarrayToCSV=(arr,delimiter=',')=>arr.map(v=>v.map(x=>`"${x}"`).join(delimiter)).join('\n');arrayToCSV([['a','b'],['c','d']]);//'"a","b"\n"c","d"'arrayToCSV([['a','b'],['c','d']],';');//'"a";"b"\n"c";"d"'5、arrayToHtmlList此段代码将数组元素转换成<li>标记,并将此元素添加至给定的ID元素标记内。constarrayToHtmlList=(arr,listID)=>(el=>((el=document.querySelector('#'+listID)),(el.innerHTML+=arr.map(item=>`<li>${item}</li>`).join(''))))();arrayToHtmlList(['item1','item2'],'myListID');6、attempt此段代码执行一个函数,将剩余的参数传回函数当参数,返回相应的结果,并能捕获异常。constattempt=(fn,...args)=>{try{returnfn(...args);}catch(e){returneinstanceofError?e:newError(e);}};varelements=attempt(function(selector){returndocument.querySelectorAll(selector);},'>_>');if(elementsinstanceofError)elements=[];//elements=[]7、average此段代码返回两个或多个数的平均数。constaverage=(...nums)=>nums.reduce((acc,val)=>acc+val,0)/nums.length;average(...[1,2,3]);//2average(1,2,3);//28、averageBy一个map()函数和reduce()函数结合的例子,此函数先通过map()函数将对象转换成数组,然后在调用reduce()函数进行累加,然后根据数组长度返回平均值。constaverageBy=(arr,fn)=>arr.map(typeoffn==='function'?fn:val=>val[fn]).reduce((acc,val)=>acc+val,0)/arr.length;averageBy([{n:4},{n:2},{n:8},{n:6}],o=>o.n);//5averageBy([{n:4},{n:2},{n:8},{n:6}],'n');//59、bifurcate此函数包含两个参数,类型都为数组,依据第二个参数的真假条件,将一个参数的数组进行分组,条件为真的放入第一个数组,其它的放入第二个数组。这里运用了Array.prototype.reduce()和Array.prototype.push()相结合的形式。constbifurcate=(arr,filter)=>arr.reduce((acc,val,i)=>(acc[filter[i]?0:1].push(val),acc),[[],[]]);bifurcate(['beep','boop','foo','bar'],[true,true,false,true]);//[['beep','boop','bar'],['foo']]10、bifurcateBy此段代码将数组按照指定的函数逻辑进行分组,满足函数条件的逻辑为真,放入第一个数组中,其它不满足的放入第二个数组。这里运用了Array.prototype.reduce()和Array.prototype.push()相结合的形式,基于函数过滤逻辑,通过Array.prototype.push()函数将其添加到数组中。constbifurcateBy=(arr,fn)=>arr.reduce((acc,val,i)=>(acc[fn(val,i)?0:1].push(val),acc),[[],[]]);bifurcateBy(['beep','boop','foo','bar'],x=>x[0]==='b');//[['beep','boop','bar'],['foo']]11、bottomVisible用于检测页面是否滚动到页面底部。constbottomVisible=()=>document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight);bottomVisible();//true12、byteSize此代码返回字符串的字节长度。这里用到了Blob对象,Blob(BinaryLargeObject)对象代表了一段二进制数据,提供了一系列操作接口。其他操作二进制数据的API(比如File对象),都是建立在Blob对象基础上的,继承了它的属性和方法。生成Blob对象有两种方法:一种是使用Blob构造函数,另一种是对现有的Blob对象使用slice方法切出一部分。constbyteSize=str=>newBlob([str]).size;byteSize('????');//4byteSize('HelloWorld');//1113、capitalize将字符串的首字母转成大写,这里主要运用到了ES6的展开语法在数组中的运用。constcapitalize=([first,...rest])=>first.toUpperCase()+rest.join('');capitalize('fooBar');//'FooBar'capitalize('fooBar',true);//'FooBar'14、capitalizeEveryWord将一个句子中每个单词首字母转换成大写字母,这里中要运用了正则表达式进行替换。constcapitalizeEveryWord=str=>str.replace(/\b[a-z]/g,char=>char.toUpperCase());capitalizeEveryWord('helloworld!');//'HelloWorld!'15、castArray此段代码将非数值的值转换成数组对象。constcastArray=val=>(Array.isArray(val)?val:[val]);castArray('foo');//['foo']castArray([1]);//[1]16、compact将数组中移除值为false的内容。constcompact=arr=>arr.filter(Boolean);compact([0,1,false,2,'',3,'a','e'*23,NaN,'s',34]);//[1,2,3,'a','s',34]17、countOccurrences统计数组中某个值出现的次数constcountOccurrences=(arr,val)=>arr.reduce((a,v)=>(v===val?a+1:a),0);countOccurrences([1,1,2,1,2,3],1);//318、CreateDirectory此代码段使用existSync()检查目录是否存在,然后使用mkdirSync()创建目录(如果不存在)。constfs=require('fs');constcreateDirIfNotExists=dir=>(!fs.existsSync(dir)?fs.mkdirSync(dir):undefined);createDirIfNotExists('test');//createsthedirectory'test',ifitdoesn'texist19、currentURL返回当前访问的URL地址。constcurrentURL=()=>window.location.href;currentURL();//'https://www.zhansanjie.com/'20、dayOfYear返回当前是今年的第几天constdayOfYear=date=>Math.floor((date-newDate(date.getFullYear(),0,0))/1000/60/60/24);dayOfYear(newDate());//27221、decapitalize将字符串的首字母转换成小写字母constdecapitalize=([first,...rest])=>first.toLowerCase()+rest.join('')decapitalize('FooBar');//'fooBar'小节今天的内容就和大家分享到这里,感谢你的阅读,如果你喜欢我的分享,麻烦给个关注、点赞加转发哦,你的支持,就是我分享的动力,后续会持续分享剩余的代码片段,欢迎持续关注。

    • JS代码
    • 264阅读
    • 2022-05-07

  • thinkphp插入数据有则更新,没有则添加,支持批量插入
    thinkphp插入数据有则更新,没有则添加,支持批量插入

    在测试的时候发现此方法会删除重复的数据进行添加新的数据,也就是id会发生变化,如数据库有id为1,2的五条数据唯一索引name分别为xiaoming、xiaohua,如果我们在批量插入数据的时候,唯一索引对比相同,则会删除掉之前的旧数据添加新数据。也就是如果我们现在要插入一条name为xiaohua的数据,那么id为2的数据将会被删除创建id为3的name为xiaohua的数据。//平常我们会这样来写$user是model类我们也可以用Db::name('table_name')$user->insert($data);//这样写将会自动处理$user->insert($data,true)$user->insertAll($data,true);//对于批量插入也适用,当有重复时,则进行更新

    • TP代码
    • 230阅读
    • 2022-05-07

  • tp5 提升性能的几个方法
    tp5 提升性能的几个方法

    首先说明如果是linux或者是Mac,需要给予权限才能操作以下方法建议,在网站稳定后再生成上传。1生成路由缓存phpthinkoptimize:route如果你的应用定义了大量的路由规则,那么建议在实际部署后生成路由缓存文件,可以免去路由注册的开销,从而改善路由的检测效率这里如果没有权限会报异常我这里是Mac需要加sudosudophpthinkoptimize:route成功以后会在runtime目录下生成一个route.php文件2生成类库映射文件sudophpthinkoptimize:autoload类库映射文件可以提高自动加载的性能成功以后会在runtime目录下生成classmap.php文件3生成数据表字段缓存如果你希望提高查询的性能,可以通过生成字段缓存来减少查询sudophpthinkoptimize:schema执行完毕,会在RUNTIME_PATH目录下面创建schema目录,然后在该目录下面按照database.table.php的文件命名生成数据表字段缓存文件。4开启请求缓存 如果你的数据实时性不是很大可以开启, //是否开启请求缓存true自动缓存支持设置请求缓存规则<br>'request_cache'=>true,这里默认是false,开始后性能有很大的提高5可以为应用或者模块生成配置缓存文件sudophpthinkoptimize:config默认生成应用的配置缓存文件,调用后会在runtime目录下面生成init.php文件,生成配置缓存文件后,应用目录下面的config.phpcommon.php以及tags.php不会被加载,被runtime/init.php取代。这里要注意在本地生成配置缓存时需要把数据库等重要的配置替换成服务器上的配置以后,在生成。

    • TP代码
    • 248阅读
    • 2022-05-06

  • tp5插入百万条数据处理优化
    tp5插入百万条数据处理优化

    <?phpnamespaceapp\index\controller;usethink\Controller;usethink\Db;classCharuextendsController{publicfunctionindex(){date_default_timezone_set("PRC");//此处修改php.ini的内存,不然无法执行插入,因为数据量太大ini_set('memory_limit','1024M');echodate('Y-m-dH:i:s').'<br>';$start=time();$data=array();for($i=0;$i<1000000;$i++){array_push($data,['name'=>'测试','age'=>10]);}print_r(db('charu')->insertAll($data));$end=time();echo'<br>'.date('Y-m-dH:i:s').'<br>';$a=$end-$start;print_r('耗时分秒'.date('i:s',$a));}}遇到下面的错误就表示你php.ini文件设置的内存值不够放Fatalerror:Allowedmemorysizeof157286400bytesexhausted(triedtoallocate32bytes)in 第一种解决方案是:在PHP文件中加入ini_set(”memory_limit”,”80M”);当然80M可以根据自己的情况改动,也不要太大哦,否则系统其它资源会遇到问题哦,其中-1为不设限。我用的是第一种方法第二种解决方案是:修改php.ini配置文件,在php.ini中找到memory_limit=16M,将前面的分号去掉,改动值的大小,将memory_limit由8M改成16M(或更大),重启apache服务即可。

    • TP代码
    • 263阅读
    • 2022-05-06

  • Thinkphp where() 方法的 查找数据优化
    Thinkphp where() 方法的 查找数据优化

    第一种方式$bank=array(12){["bank_id"]=>string(1)"9"["bank_type"]=>string(1)"1"["bank_operator_id"]=>string(1)"2"["bank_operator_name"]=>string(9)"唐新朋"["bank_operator_type"]=>string(1)"3"["bank_accept_id"]=>string(1)"1"["bank_accept_name"]=>string(9)"汪昌宁"["bank_accept_type"]=>string(1)"1"["bank_sum"]=>string(5)"50000"["bank_mark"]=>string(3)"500"["bank_confirm"]=>string(1)"0"["bank_create_time"]=>string(10)"1467113725"}$m->where($bank)->setField('bank_confirm','1');第二种方式$bank=array(12){["bank_id"]=>string(1)"9"["bank_type"]=>string(1)"1"["bank_operator_id"]=>string(1)"2"["bank_operator_name"]=>string(9)"唐新朋"["bank_operator_type"]=>string(1)"3"["bank_accept_id"]=>string(1)"1"["bank_accept_name"]=>string(9)"汪昌宁"["bank_accept_type"]=>string(1)"1"["bank_sum"]=>string(5)"50000"["bank_mark"]=>string(3)"500"["bank_confirm"]=>string(1)"0"["bank_create_time"]=>string(10)"1467113725"}$condition['bank_id']=$bank["bank_id"];$m->where($condition)->setField('bank_confirm','1');这两种方法都可以实现我想要的操作但是第一种方法是否会对服务器或数据库造成压力第二种是可以多写这一行代码$condition['bank_id']=$bank["bank_id"];纠结中(⊙﹏⊙)回复内容:第一种方式$bank=array(12){["bank_id"]=>string(1)"9"["bank_type"]=>string(1)"1"["bank_operator_id"]=>string(1)"2"["bank_operator_name"]=>string(9)"唐新朋"["bank_operator_type"]=>string(1)"3"["bank_accept_id"]=>string(1)"1"["bank_accept_name"]=>string(9)"汪昌宁"["bank_accept_type"]=>string(1)"1"["bank_sum"]=>string(5)"50000"["bank_mark"]=>string(3)"500"["bank_confirm"]=>string(1)"0"["bank_create_time"]=>string(10)"1467113725"}$m->where($bank)->setField('bank_confirm','1');第二种方式$bank=array(12){["bank_id"]=>string(1)"9"["bank_type"]=>string(1)"1"["bank_operator_id"]=>string(1)"2"["bank_operator_name"]=>string(9)"唐新朋"["bank_operator_type"]=>string(1)"3"["bank_accept_id"]=>string(1)"1"["bank_accept_name"]=>string(9)"汪昌宁"["bank_accept_type"]=>string(1)"1"["bank_sum"]=>string(5)"50000"["bank_mark"]=>string(3)"500"["bank_confirm"]=>string(1)"0"["bank_create_time"]=>string(10)"1467113725"}$condition['bank_id']=$bank["bank_id"];$m->where($condition)->setField('bank_confirm','1');这两种方法都可以实现我想要的操作但是第一种方法是否会对服务器或数据库造成压力第二种是可以多写这一行代码$condition['bank_id']=$bank["bank_id"];纠结中(⊙﹏⊙)谢谢邀请。不知道你查询中的bank_id是不是唯一的,如果是唯一的第二种条件就足够了。虽然你第一种条件很多查询起来精确度也高,我看都是string类型,如果都是有索引还好,如果有的没有索引,一个条件足够的话我建议还是第二种。谢邀,bank_id不出意外必然是唯一键或者主键,所以肯定$m->where(array('bank_id'=>$bank['bank_id']))->setField('bank_confirm','1');楼上已经正确回答了你的问题,bank_id是唯一键则单条件查询理论上查询条件越多,过滤数据越多,查询越快。但有一个主键或者索引字段即可,加个limit=1,效率就足够好了。

    • TP代码
    • 239阅读
    • 2022-05-06

  • 使用ThinkPHP开发中MySQL性能优化的最佳21条经验
    使用ThinkPHP开发中MySQL性能优化的最佳21条经验

    使用ThinkPHP开发中MySQL性能优化的最佳21条经验讲解,目前,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显。关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情。当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能。这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库。希望下面的这些优化技巧对你有用。1.为查询缓存优化你的查询大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中,这样,后续的相同的查询就不用操作表而直接访问缓存结果了。这里最主要的问题是,对于程序员来说,这个事情是很容易被忽略的。因为,我们某些查询语句会让MySQL不使用缓存。请看下面的示例://查询缓存不开启$r=mysql_query("SELECTusernameFROMuserWHEREsignup_date>=CURDATE()");//开启查询缓存$today=date("Y-m-d");$r=mysql_query("SELECTusernameFROMuserWHEREsignup_date>='$today'");上面两条SQL语句的差别就是CURDATE(),MySQL的查询缓存对这个函数不起作用。所以,像NOW()和RAND()或是其它的诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的。所以,你所需要的就是用一个变量来代替MySQL的函数,从而开启缓存。2.EXPLAIN你的SELECT查询使用EXPLAIN关键字可以让你知道MySQL是如何处理你的SQL语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。EXPLAIN的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的……等等,等等。挑一个你的SELECT语句(推荐挑选那个最复杂的,有多表联接的),把关键字EXPLAIN加到前面。你可以使用phpmyadmin来做这个事。然后,你会看到一张表格。下面的这个示例中,我们忘记加上了group_id索引,并且有表联接:当我们为group_id字段加上索引后:我们可以看到,前一个结果显示搜索了7883行,而后一个只是搜索了两个表的9和16行。查看rows列可以让我们找到潜在的性能问题。3.当只要一行数据时使用LIMIT1当你查询表的有些时候,你已经知道结果只会有一条结果,但因为你可能需要去fetch游标,或是你也许会去检查返回的记录数。在这种情况下,加上LIMIT1可以增加性能。这样一样,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。下面的示例,只是为了找一下是否有“中国”的用户,很明显,后面的会比前面的更有效率。(请注意,第一条中是Select*,第二条是Select1)//没有效率的:$r=mysql_query("SELECT*FROMuserWHEREcountry='China'");if(mysql_num_rows($r)>0){//...}//有效率的:$r=mysql_query("SELECT1FROMuserWHEREcountry='China'LIMIT1");if(mysql_num_rows($r)>0){//...}4.为搜索字段建索引索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索,那么,请为其建立索引吧。从上图你可以看到那个搜索字串“last_nameLIKE‘a%’”,一个是建了索引,一个是没有索引,性能差了4倍左右。另外,你应该也需要知道什么样的搜索是不能使用正常的索引的。例如,当你需要在一篇大的文章中搜索一个词时,如:“WHEREpost_contentLIKE‘%apple%’”,索引可能是没有意义的。你可能需要使用MySQL全文索引或是自己做一个索引(比如说:搜索关键词或是Tag什么的)5.在Join表的时候使用相当类型的例,并将其索引如果你的应用程序有很多JOIN查询,你应该确认两个表中Join的字段是被建过索引的。这样,MySQL内部会启动为你优化Join的SQL语句的机制。而且,这些被用来Join的字段,应该是相同的类型的。例如:如果你要把DECIMAL字段和一个INT字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行。(两个表的字符集有可能不一样)//在state中查找company$r=mysql_query("SELECTcompany_nameFROMusersLEFTJOINcompaniesON(users.state=companies.state)WHEREusers.id=$user_id");//两个state字段应该是被建过索引的,而且应该是相当的类型,相同的字符集。6.千万不要ORDERBYRAND()想打乱返回的数据行?随机挑一个数据?真不知道谁发明了这种用法,但很多新手很喜欢这样用。但你确不了解这样做有多么可怕的性能问题。如果你真的想把返回的数据行打乱了,你有N种方法可以达到这个目的。这样使用只让你的数据库的性能呈指数级的下降。这里的问题是:MySQL会不得不去执行RAND()函数(很耗CPU时间),而且这是为了每一行记录去记行,然后再对其排序。就算是你用了Limit1也无济于事(因为要排序)下面的示例是随机挑一条记录//千万不要这样做:$r=mysql_query("SELECTusernameFROMuserORDERBYRAND()LIMIT1");//这要会更好:$r=mysql_query("SELECTcount(*)FROMuser");$d=mysql_fetch_row($r);$rand=mt_rand(0,$d[0]-1);$r=mysql_query("SELECTusernameFROMuserLIMIT$rand,1");7.避免SELECT*从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。所以,你应该养成一个需要什么就取什么的好的习惯。//不推荐$r=mysql_query("SELECT*FROMuserWHEREuser_id=1");$d=mysql_fetch_assoc($r);echo"Welcome{$d['username']}";//推荐$r=mysql_query("SELECTusernameFROMuserWHEREuser_id=1");$d=mysql_fetch_assoc($r);echo"Welcome{$d['username']}";8.永远为每张表设置一个ID我们应该为数据库里的每张表都设置一个ID做为其主键,而且最好的是一个INT型的(推荐使用UNSIGNED),并设置上自动增加的AUTO_INCREMENT标志。就算是你users表有一个主键叫“email”的字段,你也别让它成为主键。使用VARCHAR类型来当主键会使用得性能下降。另外,在你的程序中,你应该使用表的ID来构造你的数据结构。而且,在MySQL数据引擎下,还有一些操作需要使用主键,在这些情况下,主键的性能和设置变得非常重要,比如,集群,分区……在这里,只有一个情况是例外,那就是“关联表”的“外键”,也就是说,这个表的主键,通过若干个别的表的主键构成。我们把这个情况叫做“外键”。比如:有一个“学生表”有学生的ID,有一个“课程表”有课程ID,那么,“成绩表”就是“关联表”了,其关联了学生表和课程表,在成绩表中,学生ID和课程ID叫“外键”其共同组成主键。9.使用ENUM而不是VARCHARENUM类型是非常快和紧凑的。在实际上,其保存的是TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用ENUM而不是VARCHAR。MySQL也有一个“建议”(见第十条)告诉你怎么去重新组织你的表结构。当你有一个VARCHAR字段时,这个建议会告诉你把其改成ENUM类型。使用PROCEDUREANALYSE()你可以得到相关的建议。10.从PROCEDUREANALYSE()取得建议PROCEDUREANALYSE()会让MySQL帮你去分析你的字段和其实际的数据,并会给你一些有用的建议。只有表中有实际的数据,这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础的。例如,如果你创建了一个INT字段作为你的主键,然而并没有太多的数据,那么,PROCEDUREANALYSE()会建议你把这个字段的类型改成MEDIUMINT。或是你使用了一个VARCHAR字段,因为数据不多,你可能会得到一个让你把它改成ENUM的建议。这些建议,都是可能因为数据不够多,所以决策做得就不够准。在phpmyadmin里,你可以在查看表时,点击“Proposetablestructure”来查看这些建议一定要注意,这些只是建议,只有当你的表里的数据越来越多时,这些建议才会变得准确。一定要记住,你才是最终做决定的人。 6.千万不要ORDERBYRAND()想打乱返回的数据行?随机挑一个数据?真不知道谁发明了这种用法,但很多新手很喜欢这样用。但你确不了解这样做有多么可怕的性能问题。如果你真的想把返回的数据行打乱了,你有N种方法可以达到这个目的。这样使用只让你的数据库的性能呈指数级的下降。这里的问题是:MySQL会不得不去执行RAND()函数(很耗CPU时间),而且这是为了每一行记录去记行,然后再对其排序。就算是你用了Limit1也无济于事(因为要排序)下面的示例是随机挑一条记录//千万不要这样做:$r=mysql_query("SELECTusernameFROMuserORDERBYRAND()LIMIT1");//这要会更好:$r=mysql_query("SELECTcount(*)FROMuser");$d=mysql_fetch_row($r);$rand=mt_rand(0,$d[0]-1);$r=mysql_query("SELECTusernameFROMuserLIMIT$rand,1");7.避免SELECT*从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。所以,你应该养成一个需要什么就取什么的好的习惯。//不推荐$r=mysql_query("SELECT*FROMuserWHEREuser_id=1");$d=mysql_fetch_assoc($r);echo"Welcome{$d['username']}";//推荐$r=mysql_query("SELECTusernameFROMuserWHEREuser_id=1");$d=mysql_fetch_assoc($r);echo"Welcome{$d['username']}";8.永远为每张表设置一个ID我们应该为数据库里的每张表都设置一个ID做为其主键,而且最好的是一个INT型的(推荐使用UNSIGNED),并设置上自动增加的AUTO_INCREMENT标志。就算是你users表有一个主键叫“email”的字段,你也别让它成为主键。使用VARCHAR类型来当主键会使用得性能下降。另外,在你的程序中,你应该使用表的ID来构造你的数据结构。而且,在MySQL数据引擎下,还有一些操作需要使用主键,在这些情况下,主键的性能和设置变得非常重要,比如,集群,分区……在这里,只有一个情况是例外,那就是“关联表”的“外键”,也就是说,这个表的主键,通过若干个别的表的主键构成。我们把这个情况叫做“外键”。比如:有一个“学生表”有学生的ID,有一个“课程表”有课程ID,那么,“成绩表”就是“关联表”了,其关联了学生表和课程表,在成绩表中,学生ID和课程ID叫“外键”其共同组成主键。9.使用ENUM而不是VARCHARENUM类型是非常快和紧凑的。在实际上,其保存的是TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用ENUM而不是VARCHAR。MySQL也有一个“建议”(见第十条)告诉你怎么去重新组织你的表结构。当你有一个VARCHAR字段时,这个建议会告诉你把其改成ENUM类型。使用PROCEDUREANALYSE()你可以得到相关的建议。10.从PROCEDUREANALYSE()取得建议PROCEDUREANALYSE()会让MySQL帮你去分析你的字段和其实际的数据,并会给你一些有用的建议。只有表中有实际的数据,这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础的。例如,如果你创建了一个INT字段作为你的主键,然而并没有太多的数据,那么,PROCEDUREANALYSE()会建议你把这个字段的类型改成MEDIUMINT。或是你使用了一个VARCHAR字段,因为数据不多,你可能会得到一个让你把它改成ENUM的建议。这些建议,都是可能因为数据不够多,所以决策做得就不够准。在phpmyadmin里,你可以在查看表时,点击“Proposetablestructure”来查看这些建议一定要注意,这些只是建议,只有当你的表里的数据越来越多时,这些建议才会变得准确。一定要记住,你才是最终做决定的人。16.垂直分割“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。(以前,在银行做过项目,见过一张表有100多个字段,很恐怖)示例一:在Users表中有一个字段是家庭地址,这个字段是可选字段,相比起,而且你在数据库操作的时候除了个人信息外,你并不需要经常读取或是改写这个字段。那么,为什么不把他放到另外一张表中呢?这样会让你的表有更好的性能,大家想想是不是,大量的时候,我对于用户表来说,只有用户ID,用户名,口令,用户角色等会被经常使用。小一点的表总是会有好的性能。示例二:你有一个叫“last_login”的字段,它会在每次用户登录时被更新。但是,每次更新时会导致该表的查询缓存被清空。所以,你可以把这个字段放到另一个表中,这样就不会影响你对用户ID,用户名,用户角色的不停地读取了,因为查询缓存会帮你增加很多性能。另外,你需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去Join他们,不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降。17.拆分大的DELETE或INSERT语句如果你需要在一个在线的网站上去执行一个大的DELETE或INSERT查询,你需要非常小心,要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。Apache会有很多的子进程或线程。所以,其工作起来相当有效率,而我们的服务器也不希望有太多的子进程,线程和数据库链接,这是极大的占服务器资源的事情,尤其是内存。如果你把你的表锁上一段时间,比如30秒钟,那么对于一个有很高访问量的站点来说,这30秒所积累的访问进程/线程,数据库链接,打开的文件数,可能不仅仅会让你泊WEB服务Crash,还可能会让你的整台服务器马上掛了。所以,如果你有一个大的处理,你定你一定把其拆分,使用LIMIT条件是一个好的方法。下面是一个示例:while(1){//每次只做1000条mysql_query("DELETEFROMlogsWHERElog_date<='2009-11-01'LIMIT1000");if(mysql_affected_rows()==0){//没得可删了,退出!break;}//每次都要休息一会儿usleep(50000);}18.越小的列会越快对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈。所以,把你的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问。参看MySQL的文档StorageRequirements查看所有的数据类型。如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用INT来做主键,使用MEDIUMINT,SMALLINT或是更小的TINYINT会更经济一些。如果你不需要记录时间,使用DATE要比DATETIME好得多。当然,你也需要留够足够的扩展空间,不然,你日后来干这个事,你会死的很难看,参看Slashdot的例子(2009年11月06日),一个简单的ALTERTABLE语句花了3个多小时,因为里面有一千六百万条数据。19.选择正确的存储引擎在MySQL中有两个存储引擎MyISAM和InnoDB,每个引擎都有利有弊。酷壳以前文章《MySQL:InnoDB还是MyISAM?》讨论和这个事情。MyISAM适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM对于SELECTCOUNT(*)这类的计算是超快无比的。InnoDB的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比MyISAM还慢。他是它支持“行锁”,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。下面是MySQL的手册target=”_blank”MyISAMStorageEngineInnoDBStorageEngine20.使用一个对象关系映射器(ObjectRelationalMapper)使用ORM(ObjectRelationalMapper),你能够获得可靠的性能增涨。一个ORM可以做的所有事情,也能被手动的编写出来。但是,这需要一个高级专家。ORM的最重要的是“LazyLoading”,也就是说,只有在需要的去取值的时候才会去真正的去做。但你也需要小心这种机制的副作用,因为这很有可能会因为要去创建很多很多小的查询反而会降低性能。ORM还可以把你的SQL语句打包成一个事务,这会比单独执行他们快得多得多。目前,个人最喜欢的PHP的ORM是:Doctrine。21.小心“永久链接”“永久链接”的目的是用来减少重新创建MySQL链接的次数。当一个链接被创建了,它会永远处在连接的状态,就算是数据库操作已经结束了。而且,自从我们的Apache开始重用它的子进程后——也就是说,下一次的HTTP请求会重用Apache的子进程,并重用相同的MySQL链接。PHP手册:mysql_pconnect()在理论上来说,这听起来非常的不错。但是从个人经验(也是大多数人的)上来说,这个功能制造出来的麻烦事更多。因为,你只有有限的链接数,内存问题,文件句柄数,等等。而且,Apache运行在极端并行的环境中,会创建很多很多的了进程。这就是为什么这种“永久链接”的机制工作地不好的原因。在你决定要使用“永久链接”之前,你需要好好地考虑一下你的整个系统的架构。

    • TP代码
    • 182阅读
    • 2022-05-06

  • TP5.1查询二维数组中某个键值的所有和
    TP5.1查询二维数组中某个键值的所有和

    $course_money=0;foreach($course_arras$key=>$v){$course_money=$course_money+$v->money;}$course_arr是从数据库中查询的多条数据;现目的是算出多条数据中money字段的总和;最终:$course_money 就是最终的总和!

    • TP代码
    • 235阅读
    • 2022-05-06

  • tp5三种查询数据的方式
    tp5三种查询数据的方式

    方式一:原生sql查询代码示例:<?php/***CreatedbyPhpStorm.*User:chenzhitao*Date:2017/5/8*Time:下午2:15*/namespaceapp\api\model;usethink\Db;usethink\Exception;classBanner{publicstaticfunctiongetBannerByID($id){$result=Db::query('select*frombanner_itemwherebanner_id=?',[$id]);return$result;}}方式二:使用查询构建器代码示例:<?php/***CreatedbyPhpStorm.*User:chenzhitao*Date:2017/5/8*Time:下午2:15*/namespaceapp\api\model;usethink\Db;usethink\Exception;classBanner{publicstaticfunctiongetBannerByID($id){//1.使用原生sql//$result=Db::query('select*frombanner_itemwherebanner_id=?',[$id]);//return$result;//2.使用查询构建器/**链式查询Db::table('banner_item')->where('banner_id','=',$id)返回查询对象,->select();返回查询结果,*除了select操作还有find(返回一条数据)updatedeleteinsert*对应的where也分三种,1.表达式where('字段名','表达式','查询条件')2.数组发3.闭包。*///2.1表达式法//$result=Db::table('banner_item')//->where('banner_id','=',$id)//->select();//return$result;//2.2闭包法$result=Db::table('banner_item')->where(function($query)use($id){$query->where('banner_id','=',$id);})->select();return$result;}}方式三:ORM(ObjectRelationMapping)对象关系映射使用ORM查询数据库主要区别就是在写模型的继承think\model类,然后控制器就可以使用model的默认方法来获取数据而不是自己再在模型中专门写一个获取方法代码示例:model:<?php/***CreatedbyPhpStorm.*User:chenzhitao*Date:2017/5/8*Time:下午2:15*/namespaceapp\api\model;usethink\Db;usethink\Model;classBannerextendsModel{//publicstaticfunctiongetBannerByID($id){////1.使用原生sql$result=Db::query('select*frombanner_itemwherebanner_id=?',[$id]);return$result;////2.使用查询构建器///*//*链式查询Db::table('banner_item')->where('banner_id','=',$id)返回查询对象,->select();返回查询结果,//*除了select操作还有find(返回一条数据)updatedeleteinsert//*对应的where也分三种,1.表达式where('字段名','表达式','查询条件')2.数组发3.闭包。//*///////2.1表达式法$result=Db::table('banner_item')->where('banner_id','=',$id)->select();return$result;////2.2闭包法//$result=Db::table('banner_item')//->where(function($query)use($id){//$query->where('banner_id','=',$id);////})//->select();//return$result;////////////}}controller:<?php/***CreatedbyPhpStorm.*User:chenzhitao*Date:2017/5/7*Time:下午1:49*/namespaceapp\api\controller\v1;useapp\api\validate\IDMustBePositiveInt;useapp\lib\exception\BannerMissException;useapp\api\model\BannerasBannerModel;classBanner{publicfunctiongetBanner($id){//调用验证器(newIDMustBePositiveInt())->goCheck();//$banner=BannerModel::getBannerByID($id);$banner=BannerModel::get($id);if(!$banner){thrownewBannerMissException();}return$banner;}}

    • TP代码
    • 234阅读
    • 2022-05-06

  • 分享一个TP5实现Create()方法的心得
    分享一个TP5实现Create()方法的心得

    在TP5中发现用不了以前3.X的Create()方法,虽然用input更严谨,但是字段比较多的话还是有些不艺术的3.X中的实现方法如下:$Model=D('User');$Model->create();$Model->add();在仔细阅读了TP5文档后,发现有这么一段:欣喜之余便测试了一下,发现返回的内容是个类,不能直接做修改,只能接着连贯操作:app\category\model\CategoryObject([connection:protected]=>Array()[name:protected]=>Category[table:protected]=>[class:protected]=>app\category\model\Category[pk:protected]=>[error:protected]=>[validate:protected]=>[field:protected]=>Array()[visible:protected]=>Array()[hidden:protected]=>Array()[append:protected]=>Array()[data:protected]=>Array([title]=>dd[sort]=>1[pcid]=>0)[change:protected]=>Array()[auto:protected]=>Array()[insert:protected]=>Array()[update:protected]=>Array()[autoWriteTimestamp:protected]=>[createTime:protected]=>create_time[updateTime:protected]=>update_time[deleteTime:protected]=>delete_time[dateFormat:protected]=>Y-m-dH:i:s[type:protected]=>Array()[isUpdate:protected]=>[updateWhere:protected]=>[relation:protected]=>[failException:protected]=>)仔细看了一下,当中有这么一段是我post的数据:[data:protected]=>Array([title]=>dd[sort]=>1[pcid]=>0)翻看了一下tp5的model类,有这么一个方法:/***获取对象原始数据如果不存在指定字段返回false*@accesspublic*@paramstring$name字段名留空获取全部*@returnmixed*@throwsInvalidArgumentException*/publicfunctiongetData($name=null){if(is_null($name)){return$this->data;}elseif(array_key_exists($name,$this->data)){return$this->data[$name];}else{thrownewInvalidArgumentException('propertynotexists:'.$this->class.'->'.$name);}}调用了一下,果然可以获取到post的数组了。实现代码如下:$data=newCategory($_POST);$data=$data->getData();

    • TP代码
    • 246阅读
    • 2022-05-06

  • 关于TP字段field的一些理解
    关于TP字段field的一些理解

    field方法属于模型的连贯操作方法之一,主要目的是标识要返回或者操作的字段,可以用于查询和写入操作。1、用于查询指定字段在查询操作中field方法是使用最频繁的。$Model->field('id,title,content')->select();这里使用field方法指定了查询的结果集中包含id,title,content三个字段的值。执行的SQL相当于:SELECTid,title,contentFROMtable可以给某个字段设置别名,例如:$Model->field('id,nicknameasname')->select();执行的SQL语句相当于:SELECTid,nicknameasnameFROMtable使用SQL函数可以在field方法中直接使用函数,例如:$Model->field('id,SUM(score)')->select();执行的SQL相当于:SELECTid,SUM(score)FROMtable当然,除了select方法之外,所有的查询方法,包括find等都可以使用field方法,这里只是以select为例说明。使用数组参数field方法的参数可以支持数组,例如:$Model->field(array('id','title','content'))->select();最终执行的SQL和前面用字符串方式是等效的。数组方式的定义可以为某些字段定义别名,例如:$Model->field(array('id','nickname'=>'name'))->select();执行的SQL相当于:SELECTid,nicknameasnameFROMtable对于一些更复杂的字段要求,数组的优势则更加明显,例如:$Model->field(array('id','concat(name,'-',id)'=>'truename','LEFT(title,7)'=>'sub_title'))->select();执行的SQL相当于:SELECTid,concat(name,'-',id)astruename,LEFT(title,7)assub_titleFROMtable获取所有字段如果有一个表有非常多的字段,需要获取所有的字段(这个也许很简单,因为不调用field方法或者直接使用空的field方法都能做到):$Model->select();$Model->field()->select();$Model->field('*')->select();上面三个用法是等效的,都相当于执行SQL:SELECT*FROMtable但是这并不是我说的获取所有字段,我希望显式的调用所有字段(对于对性能要求比较高的系统,这个要求并不过分,起码是一个比较好的习惯),那么OK,仍然很简单,下面的用法可以完成预期的作用:$Model->field(true)->select();field(true)的用法会显式的获取数据表的所有字段列表,哪怕你的数据表有100个字段。字段排除如果我希望获取排除数据表中的content字段(文本字段的值非常耗内存)之外的所有字段值,我们就可以使用field方法的排除功能,例如下面的方式就可以实现所说的功能:$Model->field('content',true)->select();则表示获取除了content之外的所有字段,要排除更多的字段也可以:$Model->field('user_id,content',true)->select();//或者用$Model->field(array('user_id','content'),true)->select();2、用于写入除了查询操作之外,field方法还有一个非常重要的安全功能--字段合法性检测(注意:该功能3.1版本开始才能支持)。field方法结合create方法使用就可以完成表单提交的字段合法性检测,如果我们在表单提交的处理方法中使用了:$Model->field('title,email,content')->create();即表示表单中的合法字段只有title,email和content字段,无论用户通过什么手段更改或者添加了浏览器的提交字段,都会直接屏蔽。因为,其他是所有字段我们都不希望由用户提交来决定,你可以通过自动完成功能定义额外的字段写入。同样的,field也可以结合add和save方法,进行字段过滤,例如:$Model->field('title,email,content')->save($data);如果data数据中包含有title,email,content之外的字段数据的话,也会过滤掉。

    • TP代码
    • 251阅读
    • 2022-05-06

站三界导航
本站声明:本站严格遵守国家相关法律规定,非正规网站一概不予收录。本站所有资料取之于互联网,任何公司或个人参考使用本资料请自辨真伪、后果自负,站三界导航不承担任何责任。在此特别感谢您对站三界导航的支持与厚爱。