Apache的Directory配置指南

使用<Directory>… </Directory>设置指定目录的访问权限,其中可包含:
Options
AllowOverride
Order
Allow 
Deny
五个属性。
Options属性
Options FollowSymLinks Indexes MultiViews
Options可以组合设置下列选项:
All:用户可以在此目录中作任何事情。
ExecCGI:允许在此目录中执行CGI程序。
FollowSymLinks:服务器可使用符号链接指向的文件或目录。
Indexes:服务器可生成此目录的文件列表。
None:不允许访问此目录。
AllowOverride
AllowOverride None
AllowOverride会根据设定的值决定是否读取目录中的.htaccess文件,来改变原来所设置的权限。
All:读取.htaccess文件的内容,修改原来的访问权限。
None:不读取.htaccess文件
为避免用户自行建立.htaccess文件修改访问权限,http.conf文件中默认设置每个目录为: AllowOverride None。
AccessFileName
AccessFileName filename
AccessFileName指令用于指定保护目录设定文件的文件名称,默认值为“.htaccess”。
AccessFileName .acl

Allow
设定允许访问Apache服务器的主机
Allow from all
允许所有主机的访问
Allow from 202.96.0.97 202.96.0.98
允许来自指定IP地址主机的访问

Deny 设定拒绝访问Apache服务器的主机 Deny from all 拒绝来自所有主机的访问 Deny from 202.96.0.99 202.96.0.88 拒绝指定IP地址主机的访问

Order Order allow,deny Order用于指定allow和deny的先后次序。

不懂技术的人不要对懂技术的人说这很容易实现

        “这个网站相当简单,所有你需要做的就是完成X,Y,Z。你看起来应该是技术很好,所以,我相信,你不需要花费太多时间就能把它搭建起来。”

 

        我时不时的就会收到这样的Email。写这些邮件的人几乎都是跟技术不沾边的人,或正在研究他们的第一个产品。起初,当听到人们这样的话,我总是十分的恼怒。他们在跟谁辩论软件开发所需要的时间?但后来我意识到,即使我自己对自己的项目预测要花去多少开发时间,我也是一筹莫展。如果连我自己都做不好,我何必对那些人恼怒呢?

 

真正让我郁闷的不是他们预估的错误。问题在于他们竟然认为自己可以做出正确的估计。作为开发人员,我们经常会发现,在软件开发的问题上,一个外行人会很自然的把复杂的事情估计的很简单。

 

        这并不是为我们的愤怒找借口。但这引起了另外一个有趣的问题:为什么我们天生的预测复杂性的能力在遇到编程问题时会失灵?

 

        为了回答这个问题,让我们来认识一下我们的大脑如何估计事情的。有些事情对于一些没有经验的人也很容易预估正确,但有些事情则不然。

 

我们来想想观看一个人弹吉他。即使你从来没有弹过吉他,在观看了一场弹奏《玛丽有只小羊羔(Mary had a Little Lamb)》的吉他表演后,你也能大概推测出这很简单,一个人不需要太高的技术就能演奏出来。同样,当观看了有人演奏D大调的《卡农(Pachabel’s Canon)》后,你也很容易推测出,这很复杂,需要很长时间的练习才能演奏的出来。

 

        为什么我们能够很迅速准确的预估这两首曲子的复杂性呢?这是跟我们用来判断一个事情简单和还是复杂的方法有关的。我们的大脑有一些现成的模式来完成这些事情,首先一个就是根据速度。这种情况下,大脑会辨别每秒钟演奏的东西。根据每秒钟演奏了多少东西,我们很容易有一个直观的判断曲子的复杂度。因为用吉他演奏一首歌是一种物理过程,一种感官上的活动,我们的大脑很容易依此来推测速度,继而转换成复杂度。

 

我们还有另外一个天生的推测依据:体积。想想把一个帐篷和一栋公寓放在一起对比。即使一个人从来没有学过建筑学,他也能告诉你通常设计和建造一个帐篷会比设计和建造一栋公寓要简单。为什么?因为我们天生的会使用物理体积作为事物复杂性的一个指标。

 

当然。上面说的这两种逻辑分析并不是总是100%的有效。但大多数情况下,人们就是这样干,而且很成功。大多数情况中,我们在对物理过程评估时,我们的大脑会对物理事物进行有效的关联,不需要依赖之前的经验。

 

        现在让我们来谈谈软件。当一个不懂技术的人试图对软件开发时间进行评估时,有两个很基本的直观指标在辅助他们:以体积为指标的复杂度和以速度为指标的复杂度。但他们没有意识到,软件跟他们想象的不一样。软件本质上不是有形物质。没有体积和速度。它的极小的组成部分可能会时不时的在电脑屏幕上闪现。正因为如此,当面对开发一个web应用时(或任何类型的软件),我们的基本直观感觉失效了。

 

这第一点,速度,很显然根本不可能被外行人拿来对软件进行评估。于是很自然的,他们倾向于使用体积指标进行评估。要么是根据描述文档的页数,要么是根据软件的功能用例数或特征数。

 

有时候,这种评估手段确实有效!当面对一个静态网站,没有特别的设计要求,外行人很容易用这种方法估计出开发时间。但是,通常情况下,对于软件开发,体积并不能真实有效的反映复杂度。

 

        不幸的是,对于软件的复杂度,唯一有效的推测方法是依据经验。而且还不是时时都好用。作为一个程序员,我知道,根据我之前开发过的相似的功能特征,我可以估计出现在的这些功能特征各自要多少开发时间。然后,我把总时间加起来,这就得到了完成整个项目需要的大致时间。然而,事实情况中,每个项目在开发过程中都遇到二、三个瓶颈。这些瓶颈会肆意的消耗程序员的大量时间,你在遇到它们之前根本不会有所预见。它们会拖住整个项目,致使工期延后数周甚至数月。

 

        这些是没有经验的人在评估复杂度时不会理解的。他们不明白在其他事情上都很灵的方法,为什么放到软件开发上就不灵了。所以,下一次当你听到有人说“我想你几天时间就能把它开发出来”时,不管是谁说的,都不要懊恼。深呼吸一下,告诉他这篇文章的地址,自己该干什么还干什么。

如何系统学习 iOS 开发?

来源:知乎

有网友在知乎提问:“本人大四学生,用iOS设备两年多了,真正的接触开发有半年时间吧,之前Java基础还行。现在感觉有点小瓶颈,很多东西仅仅限于会用或者按照规范依葫芦画瓢,但不知道深层次的原理以及为什么这样做,感觉知识学习不够系统,经常遇到一些NS类不知所以,翻查Apple的docs有时也看不太懂(可能有外语水平问题,但应该不是主要原因),比如NSApplication、NSOperation、NSRunLoop等。哪位前辈能指点一下进一步的学习方法?”  Wang Hailong 的回复的投票数最高,整理如下:

我当时刚学iOS开发的时候一样的感觉,总想知道原理,内部怎么回事,感觉在像在雾里。但是iOS开发就是这样,它是封闭的 本身就是在雾里…

关于iOS开发的学习,打个比方就像把汽车分解:

  • 最底层的原料有塑料,钢铁
  • 再用这些底层的东西造出来发动机,座椅
  • 最后再加上写螺丝,胶水等,把汽车就拼起来了

iOS基本都是英文的资料,也由于封闭,文档写的相当好。在遇到新框架的时候:

  • 弄明白框架的功能
  • 去文档里搜搜 框架的 Programming Guide 很有用
  • 要弄明白框架类的继承结构

写iOS的程序不一定都是用OBJC,很多框架是用C写的。学习iOS开发基础可以按照下面两个方面学:

  1. 基础 (原料 钢铁 塑料)
  • OBJ-C — 语法弄明白 @interface @property 这些东西总要知道是干嘛的 怎么用
  • 基础库 — NSString NSArray NSDictionary等 这些东西在所有的框架里都会出现

    • iOS大部分类都是继承自NSObject (我还没见过不是继承自NSObject的..)
    • 还有一些 像NSCopying的接口(经@李禹龙提醒 应该叫协议) 不是特别用到开始不用了解
    • NSObject 创建对象的时候用 + (id)alloc 方法 创建后需要init方法初始化 这个init指的是所有前面是init的方法比如UIView的初始化方法是 – (id)initWithFrame:(CGRect)aRect 在Objc里有很多这样关于函数命名的约定 类似于在python中的函数__xxx
    • NSString 字符串 NSArray 数组 NSDictionary 字典 这些都需要弄很清楚 其他的类都是一个套路
    • NSMutableArray 这样带Mutable的类代表可变的 继承自相应的不可变类 比如NSMutableArray继承自NSArray 他们都添加了可以改变对象内容的方法比如

      • – (void)addObject:(id)anObject 添加对象
      • – (void)removeObject:(id)anObject 删除对象
    • 上面只是一个大概的总结 还有很多东西需要学 iOS5的SDK已经支持ARC 可以自动进行release 但是对iOS4的支持还有一个小问题 现在要开发应用 可能还需要按照之前的MRC的方式alloc release retain autorelease 之类的内存管理方法 不过如果你现在开始学 到编出像样的APP iOS5可能已经普及了 可以直接用ARC (另 之前对ARC的了解很粗浅 现在开发程序完全可以直接ARC iOS4不支持的weak是有办法替代的 用unsafe_unretained 如果同时支持iOS5和iOS4 用宏判断下就可以 当然也可以直接用assign)
    • 还有一点开始学习的时候肯定很疑惑 内存管理是基于函数名称的 比如带alloc copy的函数 用了之后返回的对象一定要release 这个不用疑惑 照做就行了
  • 文档:CocoaFundamentals Introduction
  1. 高级库(发动机)
  • UIKit — UI库 OBJC

    • UIResponder 父类是NSObject UIKit里最底层的库 可以响应一些触摸事件 设置焦点等功能
    • UIView 父类是UIResponder 所有View的父类 方法太多了 大部分很有用 这个不赘述了 中文的资料也很多了

    • 关于UIView的子类 有很多 UIButton UITableView 这个都需要各个击破 看看文档从名字上就很容易理解是做什么的
    • UIViewController 是管理View 和 Model的类 (@张开 说UIViewController是用来管理view的,管理model 的类自己写,当然,model也可以用UIViewController来管理,不过恐怕成为不好的代码。 的确是这样的 Model的改变最好通过Notification来传播 之前吃过这样的亏 最好不要用delegate模式)

      • UIViewController 管理所有设备发生的事件 比如屏幕旋转 屏幕关闭 或者一些其他的 程序的控制逻辑也应该写在这里
      • 他的初始化函数是- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle 后面那个NibName 是Interface Builder 里设计的界面

        • 现在IB已经集成到XCode里了 打开.xib的文件打开的就是IB
        • IB和代码交互用的是IBAction IBOutlet 这些标记 这些标记追踪到他们的定义其实对编译器来说什么都不表示 只能IB识别
        • IB也没那么高深 XIB文件解开之后就是一堆代码
        • 之前面过一家小公司 看我当时写的程序里面用到了IB 一脸不屑 说他们都是用代码控制view 意思他们玩的都是高科技 IB都是垃圾 很多人也纠结到底用不用IB 的确 很多时候IB灵活度不行 但是不需要灵活度的时候还不用IB 那不是装X吗 要是没人用苹果还开发IB干嘛 早去掉了 IB在很多时候节省很多工作量
    • UINavigationController 再说说NavigationController

      • 刚接触开发的时候 不明白 View和View之间怎么切换的 最重要的就是UINavigationController 他是一层一层推进view的 打开iPhone里的联系人 每点一个联系人屏幕就会像右推到下一个界面 这就是UINavigationController在做的事
      • UINavigationController 维护一个堆栈
      • – (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated 是像堆栈里压一个UIViewController
      • – (UIViewController *)popViewControllerAnimated:(BOOL)animated 是从堆栈里弹出来一个UIViewController
      • 就算你的程序不是像联系人那样 向右推进 也可以用UINavigationController 管理你的ViewController的层次 可以自己写View切换的动画 关掉他默认的动画
      • 文档: /ViewControllerPGforiPhoneOS/ModalViewControllers
    • UIWindow 还有个蛋疼的UIWindow 都快忘了他了 因为iOS是从Mac os X过来的 很多东西直接拿来用 这个UIWindow就是 在iOS里 每个App独占屏幕 所以同时存在的只有一个UIWindow 除了在程序加载的时候把我的view 加载到他上 目前我还没用到过其他的
    • 苹果一直很推崇MVC的程序结构 视图 模型 控制器 简单说就是 视图负责显示内容 模型负责所有数据的保存结构或者一些其他数据操作 控制器是用来协调 视图和模型 举车的发动机系统的例子 视图是仪表盘 模型是发动机 控制器是控制芯片
  • Core Data — 管理数据 OBJC

    • 刚学的时候觉得 CD很高深 其实他是最容易用的库之一 他麻烦之处在于多线程问题 还有胶水代码的问题
    • 建立一个 基于Core Data的工程 你会看到他自动创建3个类的对象

      • NSManagedObjectModel

        • 管理数据的存储结构文件 扩展名是 xcdatamodeld
      • NSPersistentStoreCoordinator

        • 用来管理底层数据的存储 用官方的话说

          Core Data is not a relational database or a relational database management system (RDBMS).

        • 所以你可以用很多方法存储数据 比如最长用的sqlite 当然如果另类也可以用plist文件 或者其他
      • NSManagedObjectContext

        • NSManagedObjectContext 把上面两个对象连在一起 把他们变成一个整体
        • 所有的CD操作都是通过这个类的 这个需要仔细看文档了
      • 举个不恰当的例子 就像三个人收拾衣服 一个人负责衣服的存放位置(NSManagedObjectModel) 一个人负责把衣服分类 冬天穿 夏天穿等(NSPersistentStoreCoordinator) 一个人负责协调他们的工作 并且如果有新增加的衣服或者要移除之前的衣服 通知他俩(NSManagedObjectContext)
    • NSManagedObject 这个类是具体的数据对象 用上面的例子说就是衣服

      • 一般都是继承这个对象 XCode 可以帮你做 具体搜搜 这种文章很多
    • NSFetchRequest

      • 用来执行CD请求的 相当与select语句外壳
    • NSEntityDescription

      • 用来描述实体的 对应sql里的table
    • NSPredicate

      • 谓语 类似select语句中的条件
    • 上面这三个类就可以用来请求数据了 具体看教程吧
    • 中文介绍:http://c.gzl.name/archives/tag/core-data (访问需要点技术…)
    • 文档: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/coredata/cdprogrammingguide.html

掌握上面的内容 差不多就能写个APP了 最好的学习方法就是边写边学 自己构想一个小的APP 在做的时候遇到问题 去找找资料 我觉得这样学习比较快 也比较扎实
下面这些库都是有专门功能的库

  • Core Animation — 制作动画 很强大 很喜欢的框架 可以用少量的代码写出漂亮的动画 C
  • Quartz 2D — 强大的2D绘图库 C
  • OpenGL — 不用介绍了 超级强大的3D库 C
  • Core Image — 听说 iOS5开始支持Core Image 了 还没去看 Mac 上的CI是很强大的
  • CFNetwork — 从来没用过 我一般都会用ASIHttpRequset 封装好的高层网络库 OBJC实现的 CFNetwork 好像是C实现
  • Core Location — 获取位置的库 东西很少 很简单 OBJC
  • AVFoundation — 播放视频相关的库 最近正在学习

这些算是学iOS开发的一些方法,当时要是有人告诉我这些,估计少走不少弯路。还有提醒各位初学者,刚开始学的时候会有几个月的低谷期,很容易放弃。如果挺过最开始的几个月,后来就越学越容易了。

什么是Workerman

Workerman是一款开源高性能PHP socket 服务器框架。已经被多家公司用于移动通讯、手游服务端、网络游戏服务器、聊天室服务器、硬件通讯服务器、智能家居等服务端的开发。 只要会PHP,你就可以基于Workerman轻而易举的开发出你想要的网络应用,不必再为PHP Socket底层开发而烦恼。

 

http://www.workerman.net/

Mysql 常用函数

Ø function 函数

 

函数的作用比较大,一般多用在select查询语句和where条件语句之后。按照函数返回的结果,

可以分为:多行函数和单行函数;所谓的单行函数就是将每条数据进行独立的计算,然后每条数据得到一条结果。

如:字符串函数;而多行函数,就是多条记录同时计算,得到最终只有一条结果记录。如:sum、avg等

多行函数也称为聚集函数、分组函数,主要用于完成一些统计功能。MySQL的单行函数有如下特征:

    单行函数的参数可以是变量、常量或数据列。单行函数可以接受多个参数,但返回一个值。

    单行函数就是它会对每一行单独起作用,每一行(可能包含多个参数)返回一个结果。

    单行函数可以改变参数的数据类型。单行函数支持嵌套使用:内层函数的返回值是外层函数的参数。

 

单行函数可以分为:

    类型转换函数;

    位函数;

    流程控制语句;

    加密解密函数;

    信息函数

 

单行函数

1、    char_length字符长度
select char_length(tel) from user;
 
2、    sin函数
select sin(age) from user;
select sin(1.57);
 
3、    添加日期函数
select date_add('2010-06-21', interval 2 month);
interval是一个关键字,2 month是2个月的意思,2是数值,month是单位
select addDate('2011-05-28', 2);
在前面的日期上加上后面的天数
 
4、    获取当前系统时间、日期
select curdate();
select curtime();
 
5、    加密函数
select md5('zhangsan');
 
6、    Null 处理函数
select ifnull(birthday, 'is null birthday') from user;
如果birthday为null,就返回后面的字符串
 
select nullif(age, 245) from user;
如果age等于245就返回null,不等就返回age
 
select isnull(birthday) from user;
判断birthday是否为null
 
select if(isnull(birthday), 'birthday is null', 'birthday not is null') from user;
如果birthday为null或是0就返回birthday is null,否则就返回birthday not is null;类似于三目运算符
 
7、    case 流程函数
case函数是一个流程控制函数,可以接受多个参数,但最终只会返回一个结果。
select name, 
age, 
(case sex
    when 1 then '男'
    when 0 then '女'
    else '火星人'
    end
) sex
from user;

 

 

组函数

组函数就是多行函数,组函数是完成一行或多行结果集的运算,最后返回一个结果,而不是每条记录返回一个结果。

 

1、    avg平均值运算
select avg(age) from user;
select avg(distinct age) from user;
 
2、    count 记录条数统计
select count(*), count(age), count(distinct age) from user;
 
3、    max 最大值
select max(age), max(distinct age) from user;
 
4、    min 最小值
select min(age), min(distinct age) from user;
 
5、    sum 求和、聚和
select sum(age), sum(distinct age) from user;
select sum(ifnull(age, 0)) from user;
 
6、    group by 分组
select count(*), sex from user group by sex;
select count(*) from user group by age;
select * from user group by sex, age;
 
7、    having进行条件过滤
不能在where子句中过滤组,where子句仅用于过滤行。过滤group by需要having
不能在where子句中用组函数,having中才能用组函数
select count(*) from user group by sex having sex <> 2;

 

Ø 多表查询和子查询

 

数据库的查询功能最为丰富,很多时候需要用到查询完成一些事物,而且不是单纯的对一个表进行操作。而是对多个表进行联合查询,

MySQL中多表连接查询有两种规范,较早的SQL92规范支持,如下几种表连接查询:

    等值连接

    非等值连接

    外连接

    广义笛卡尔积

SQL99规则提供了可读性更好的多表连接语法,并提供了更多类型的连接查询,SQL99支持如下几种多表连接查询:

    交叉连接

    自然连接

    使用using子句的连接

    使用on子句连接

    全部连接或者左右外连接

SQL92的连接查询
SQL92的连接查询语法比较简单,多将多个table放置在from关键字之后,多个table用“,”隔开;
连接的条件放在where条件之后,与查询条件直接用and逻辑运算符进行连接。如果条件中使用的是相等,
则称为等值连接,相反则称为非等值,如果没有任何条件则称为广义笛卡尔积。
广义笛卡尔积:select s.*, c.* from student s, classes c;
等值:select s.*, c.* from student s, classes c where s.cid = c.id;
非等值:select s.*, c.* from student s, classes c where s.cid <> c.id;
select s.*, c.name classes from classes c, student s where c.id = s.classes_id and s.name is not null;
 
SQL99连接查询
1、交叉连接cross join,类似于SQL92的笛卡尔积查询,无需条件。如:
select s.*, c.name from student s cross join classes c;
 
2、自然连接 natural join查询,无需条件,默认条件是将2个table中的相同字段作为连接条件,如果没有相同字段,查询的结果就是空。
select s.*, c.name from student s natural join classes c;
 
3、using子句连接查询:using的子句可以是一列或多列,显示的指定两个表中同名列作为连接条件。
如果用natural join的连接查询,会把所有的相同字段作为连接查询。而using可以指定相同列及个数。
select s.*, c.name from student s join classes c using(id);
 
4、    join … on连接查询,查询条件在on中完成,每个on语句只能指定一个条件。
select s.*, c.name from student s join classes c on s.classes_id = c.id;
 
5、    左右外连接:3种外连接,left [outer] join、right [outer] join,连接条件都是通过用on子句来指定,条件可以等值、非等值。
select s.*, c.name from student s left join classes c on s.classes_id = c.id;
select s.*, c.name from student s right join classes c on s.classes_id = c.id;
 
    子查询
    子查询就是指在查询语句中嵌套另一个查询,子查询可以支持多层嵌套。子查询可以出现在2个位置:
    from关键字之后,被当做一个表来进行查询,这种用法被称为行内视图,因为该子查询的实质就是一个临时视图
    出现在where条件之后作为过滤条件的值
 
子查询注意点:
    子查询用括号括起来,特别情况下需要起一个临时名称
    子查询当做临时表时(在from之后的子查询),可以为该子查询起别名,尤其是要作为前缀来限定数据列名时
    子查询用作过滤条件时,将子查询放在比较运算符的右边,提供可读性
    子查询作为过滤条件时,单行子查询使用单行运算符,多行子查询用多行运算符
 
将from后面的子查询当做一个table来用:
select * from (select id, name from classes) s where s.id in (1, 2);
当做条件来用:
select * from student s where s.classes_id in (select id from classes);
select * from student s where s.classes_id = any (select id from classes);
select * from student s where s.classes_id > any (select id from classes);
Ø 操作符和函数

1、    boolean只判断
select 1 is true, 0 is false, null is unknown;
select 1 is not unknown, 0 is not unknown, null is not unknown;
 
2、    coalesce函数,返回第一个非null的值
select coalesce(null, 1);
select coalesce(1, 1);
select coalesce(null, 1);
select coalesce(null, null);
 
3、    当有2个或多个参数时,返回最大的那个参数值
select greatest(2, 3);
select greatest(2, 3, 1, 9, 55, 23);
select greatest('D', 'A', 'B');
 
4、    Least函数,返回最小值,如果有null就返回null值
select least(2, 0);
select least(2, 0, null);
select least(2, 10, 22.2, 35.1, 1.1);
 
5、    控制流函数
select case 1 when 1 then 'is 1' when 2 then 'is 2' else 'none' end;
select case when 1 > 2 then 'yes' else 'no' end;
 
6、    ascii字符串函数
select ascii('A');
select ascii('1');
 
7、    二进制函数
select bin(22);
 
8、    返回二进制字符串长度
select bit_length(11);
 
9、    char将值转换成字符,小数取整四舍五入
select char(65);
select char(65.4);
select char(65.5);
select char(65.6);
select char(65, 66, 67.4, 68.5, 69.6, '55.5', '97.3');
 
10、    using改变字符集
select charset(char(0*65)), charset(char(0*65 using utf8));
 
11、    得到字符长度char_length,character_length
select char_length('abc');
select character_length('eft');
 
12、    compress压缩字符串、uncompress解压缩
select compress('abcedf');
select uncompress(compress('abcedf'));
 
13、    concat_ws分隔字符串
select concat_ws('#', 'first', 'second', 'last');
select concat_ws('#', 'first', 'second', null, 'last');

 

 

Ø 事务处理

动作

    开始事务:start transaction

    提交事务:commit

    回滚事务:rollback

    设置自动提交:set autocommit 1 | 0 

    atuoCommit系统默认是1立即提交模式;如果要手动控制事务,需要设置set autoCommit 0;

    这样我们就可以用commit、rollback来控制事务了。

 

在一段语句块中禁用autocommit 而不是set autocommit

start transaction;

select @result := avg(age) from temp;

update temp set age = @result where id = 2;

select * from temp where id = 2;//值被改变

rollback;//回滚

select * from temp where id = 2;//变回来了

在此期间只有遇到commit、rollback,start Transaction的禁用autocommit才会结束。然后就恢复到原来的autocommit模式;

 

不能回滚的语句

    有些语句不能被回滚。通常,这些语句包括数据定义语言(DDL)语句,比如创建或取消数据库的语句,

    和创建、取消或更改表或存储的子程序的语句。

    您在设计事务时,不应包含这类语句。如果您在事务的前部中发布了一个不能被回滚的语句,

    则后部的其它语句会发生错误,在这些情况下,通过发布ROLLBACK语句不能 回滚事务的全部效果。

 

一些操作也会隐式的提交事务

如alter、create、drop、rename table、lock table、set autocommit、start transaction、truncate table 等等,

在事务中出现这些语句也会提交事务的

    事务不能嵌套事务

    事务的保存点

Savepoint pointName/Rollback to savepoint pointName

一个事务可以设置多个保存点,rollback可以回滚到指定的保存点,恢复保存点后面的操作。

如果有后面的保存点和前面的同名,则删除前面的保存点。

Release savepoint会删除一个保存点,如果在一段事务中执行commit或rollback,则事务结束,所以保存点删除。

 

 Set Transaction设计数据库隔离级别

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL

{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

本语句用于设置事务隔离等级,用于下一个事务,或者用于当前会话。

在默认情况下,SET TRANSACTION会为下一个事务(还未开始)设置隔离等级。

如果您使用GLOBAL关键词,则语句会设置全局性的默认事务等级,

用于从该点以后创建的所有新连接。原有的连接不受影响。使用SESSION关键测可以设置默认事务等级,

用于对当前连接执行的所有将来事务。

默认的等级是REPEATABLE READ全局隔离等级。

 

 

 

Ø 注释

select 1+1;     # 单行注释
select 1+1;     -- 单行注释
select 1 /* 多行注释 */ + 1;
Ø 基本数据类型操作

字符串
    select 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
    select "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
 
\n换行
    select 'This\nIs\nFour\nLines';
 
\转义
    select 'hello \ world!';
    select 'hello \world!';
    select 'hello \\ world!';
    select 'hello \' world!';
Ø 设置数据库mode模式

SET sql_mode='ANSI_QUOTES';
create table t(a int);
create table "tt"(a int);
create table "t""t"(a int);
craate talbe tab("a""b" int);
Ø 用户变量

set @num1 = 0, @num2 = 2, @result = 0; 
select @result := (@num1 := 5) + @num2 := 3, @num1, @num2, @result; 
Ø 存储过程

创建存储过程:
delimiter //
create procedure get(out result int)
begin
 select max(age) into result from temp;
end//
调用存储过程:
call get(@temp);
查询结果:
select @temp;
 
删除存储过程:
drop procedure get;
 
查看存储过程创建语句:
show create procedure get;
 
select…into 可以完成单行记录的赋值:
create procedure getRecord(sid int)
begin
    declare v_name varchar(20) default 'jason';
    declare v_age int;
    declare v_sex bit;
    select name, age, sex into v_name, v_age, v_sex from temp where id = sid;
    select v_name, v_age, v_sex;
end;
call getRecord(1);
Ø 函数

函数类似于存储过程,只是调用方式不同
例如:select max(age) from temp;
 
创建函数:
create function addAge(age int) returns int
     return age + 5;
 
使用函数:
select addAge(age) from temp;
 
删除函数:
drop function if exists addAge;
drop function addAge;
 
显示创建语法:
show create function addAge; 
Ø 游标

声明游标:declare cur_Name cursor for select name from temp;
打开游标:open cur_Name;
Fetch游标:fetch cur_Name into @temp;
关闭游标:close cur_Name;
 
示例:
CREATE PROCEDURE cur_show()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE v_id, v_age INT;
  DECLARE v_name varchar(20);
  DECLARE cur_temp CURSOR FOR SELECT id, name, age FROM temp;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
 
  OPEN cur_temp;
 
  REPEAT
    FETCH cur_temp INTO v_id, v_name, v_age;
    IF NOT done THEN
       IF isnull(v_name) THEN
          update temp set name = concat('test-json', v_id) where id = v_id;
       ELSEIF isnull(v_age) THEN
          update temp set age = 22 where id = v_id;
       END IF;
    END IF;
  UNTIL done END REPEAT;
 
  CLOSE cur_temp;
END
Ø 触发器

触发器分为insert、update、delete三种触发器事件类型
还有after、before触发时间
创建触发器:
create trigger trg_temp_ins
before insert
on temp for each row
begin
insert into temp_log values(NEW.id, NEW.name);
end//
 
删除触发器:
drop trigger trg_temp_ins

php和js的取整

1.丢弃小数部分,保留整数部分

php: intval(7/2)

js:parseInt(7/2)

 

2.向上取整,有小数就整数部分加1

php: ceil(7/2)

js: Math.ceil(7/2)

 

3,四舍五入.

php: round(7/2)

js: Math.round(7/2)

 

4,向下取整

php: floor(7/2)

js: Math.floor(7/2)

ci 释放mysql资源

使用ci框架提供的类查询数据:

$this->load->database();

$query = $this->db->query($sql);

程序运行一段时间之后,报错,告知数据库too many connections

很明显mysql数据库连接资源超过了 max_connections 设定值。立马在每个查询之后,添加资源释放脚本:

$this->db->close();

仍然无法释放资源,怎么办呢?查看手册之后,知道了,只要把pconnect设置为false就可以了,设置大致如下:

$db['default']['pconnect'] = FALSE;

设置 过之后,无需调用   $this->db->close(); 即可自动关闭连接。

看来ci框架代码还是需要多看看。

PHP报错: A non well formed numeric value encountered

问题背景:

处理时间的时候报错: A non well formed numeric value encountered

解决方案:

这种现象常常出现在弱类型语言上!时间戳并不是真正的int类型, 这种问题经常出现在从数据库中提取出数据,但是数据不是int类型的,可能是varchar等等,大家可以使用intval()函数将非格式良好的数据转换成良好的数据类型就OK了!