tp框架中 关于数据库mysql 的一些疑点知识

mysql创建索引, 通常是在 创建表的 同时/时候, 就创建了

即使是在win下, 用命令行操作数据库 , 也要比 图形界面的鼠标操作快得多

索引的类型有: unique, fulltext索引, spatial空间索引, 和普通索引 index/key


fulltext全文索引的使用?

  1. 使用索引的好处, 如同字典 的 索引一样, 如果你从头到尾不使用索引 一个字一个字地 查字典 找一个字的话, 是很老火的. 反之, 使用前面的偏旁部首索引 查字, 可以通过 字 和 页数 的 对应关系 一下子找到该字. mysql的索引是同样的道理, 它创建了 数据和 数据所在的 位置/记录行之间的 对应关系....

  2. fulltext是全文索引, 也叫做 全站索引. 从 mysql4.0 开始支持.
    其中的 ft_min_word_len 叫做 fulltext min word length. 默认的是 4个字符, 对英文的全站索引比较合理, 对中文, 就不是很合理了. 中文最好设置成
    ft_min_word_len =2, 或 1
    方法是在 : 配置文件 my.ini(linux的 my.cnf) 中的 [mysqld] 节中, 增加这一句: ft_min_word_len=2, 或 1 就好了
    全文索引 通常是对 文章的标题(搜索文章标题 title), 或内容(搜索整个文章的内容 content) 进行创建 索引. 然后 对他们进行 搜索就变得 可能....

  3. 创建全文索引的方法是:
    - alter table article add fulltext index_content(content);
    或者直接创建索引
    - create fulltext index index_content on article(content);

  4. 使用 全文索引的搜索方法是:

select title, author, release_time, content, field1,  field2... where  `content_field`(全文索引的字段名称) against  ('查询内容-搜索字符串')  order by id desc limit  10
  • 关键是 这里的 查询条件: where '全文索引字段' against ('搜索内容') 的用法
  • 网页开发中, 只要 把数据 选择/搜查出来后, 显示和 呈现 就比较简单和随心所欲了.

关于编辑器中的字体选择,

  • 可以选择 Courier New 字体. 这个字体也是每个 Windows都会带的,字体很好看,除了o O 0的区别,也是很多人在编程中使用的。
  • 或Bitstream Vera Sans Mono
  • Bitstream Vera Sans Mono,以及他的衍生字体DejaVu Sans Mono——DejaVu扩展了一些Unicode中的字符。 这也是很多开发者推荐的字体,除了完全满足上面说的所有条件之外,又是TTF字体,基本字形是无衬线的,适合屏幕阅读,最重要的还是开源的字体!

字母的宽度一致

或称为等宽字体,由于代码文件是普通文本,不带样式的,所以宽度一致易于排列和对齐,能迅速找到位置,提高可读性。

印刷术中这种等宽字体称之为monospaced字体,他是字体中的一个大分类(family),如常见的Courier和Courier New。由于考虑到现在的多语言环境,在不同的系统中,要将这个字体在不同字符集下映射到不同的具体字体上去,比如,一般我们的系统都会把中文的映射到“宋体”上。

courier: 快递员


tp中的add支持批量写入, 就是一次性写入多条记录, 用数组表示, 数组用 动态添加的方式定义, 方法名是 addAll. 注意是 AddAll , 不是 AddList

$dataList[] = array('name' => 'foo', 'age' => 10);
$datalist[] = array('name' => 'foo2', 'age' => 15);
$Model -> addAll($dataList);
  1. 在 add方法和save方法中, 要过滤字段, 既可以直接在 操作中, 用 field(...) 连贯操作方法来过滤字段, 也可以直接在 模型类中 直接定义 (一般是 类自己的属

性, 不是通用性的属性, 常用 protected 定义 ) protected $insertFields = array (...); 和 protected $updateFields = array(....);

  1. 在php和tp 的 很多操作方法和函数中, 比如find 方法 和 select方法等, 如果查询出错, 则返回false; 如果查询结果为空, 则返回null. 如果有结果, 则返

回字段或数组/数组集. 要清醒地认识到 返回的结果 false 和null的区别,不要搞混了.
**注意, find的结果, 即使满足条件的数据不止一个, find方法也只会返回第一条记录(当然可以用order排序等) **

class Model {
// 操作状态
const MODEL_INSERT = 1; // 插入模型数据
const MODEL_UPDATE = 2; // 更新模型数据
const MODEL_BOTH = 3; // 包含上面两种方式
const MUST_VALIDATE = 1; // 必须验证
const EXISTS_VALIDATE = 0; // 表单存在字段则验证
const VALUE_VALIDATE = 2; // 表单值不为空则验证

// 当前数据库操作对象
protected $db               =   null;
// 数据库对象池
private   $_db				=	array();


public function field($field,$except=false){   ///这里的except是指定是否 进行排除...
    if(true === $field) {// 获取全部字段
        $fields     =  $this->getDbFields();
        $field      =  $fields?:'*';
    }elseif($except) {// 字段排除
        if(is_string($field)) {
            $field  =  explode(',',$field);
        }
        $fields     =  $this->getDbFields();
        $field      =  $fields?array_diff($fields,$field):$field;
    }
    $this->options['field']   =   $field;
    return $this;    ////  这里返回的是 模型对象本身, 连贯操作都返回的是 $this. 
}


在tp中, 几乎所有的函数和方法中的参数, 都同时支持 字符串和数组的 参数形式, 即既可以使用 字符串的参数, 也可以使用 数组的参数 形式.

关于错误/成功/重定向 跳转处理?

  1. 全局的跳转函数: function redirect($url, $time=0, $msg='') {...

  2. 控制器类的 跳转成员:

   $this ->  protected function redirect($url,$params=array(),$delay=0,$msg='') {
        $url    =   U($url,$params);   // 这里就是借助于U方法, 将基本url和额外参数组装成复杂url地址.
        redirect($url,$delay,$msg);	// 然后调用的 全局的redirect方法.
    }
  1. 所以, 两个redirect方法其实没有本质的不同, 参数都是一样的(跳转地址url, 延伸time/delay, 提示消息message), 只是, 成员方法多了一个$vars 后来被U方法组

装.

  1. 关于U方法. 熟练牢固地掌握U方法:
  • U($url, $vars, $suffix, $domain), $url地址本身支持 Module/Controller/Action#所有的锚点都用井号表示@别名的相同的域名? var1=val1&var2=val2... 而且还支持分开的 单独的额外参数$vars, 后面两个参数用来说明地址的开头和结尾, 结尾用$suffix ,开头用@domain来说明...

  • 具体的参数 **很多时候 就是用 U方法 来将 初步的原始的 基本的$url地址和 参数 $vars/ $params 组装成完整的 复杂的url地址,比如 上面的两个 redirect方法. **

/**
 * URL组装 支持不同URL模式
 * @param string $url URL表达式,格式:'[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...'
 * @param string|array $vars 传入的参数,支持数组和字符串
 * @param string|boolean $suffix 伪静态后缀,默认为true表示获取配置值
 * @param boolean $domain 是否显示域名
 * @return string
 */
function U($url='',$vars='',$suffix=true,$domain=false) {

关于tp中的跳转?

  1. $Model->redirect($url, $vars,$delay,$msg)中,如果要设置延时,则必须输入params, 因为delay参数是在第三位
    如果发现跳转后的url有问题, 可以先测试一下 U方法。 U($url, $vars, $suffix, $domain);

如果不想使用U方法生成跳转地址, 也可以直接使用php的header函数或 全局的redirect函数。

  1. $this->redirect方法和success, error的区别是
    redirect 是利用php的header重定向,而success和error是使用的html的meta http-equiv属性。 meta http-equiv='refresh" content="5; url=www.foo.com"
    redirect 无模板页面, 输出的提示信息是直接在函数内echo输出的
    而success和error都有对应的模板输出。
    三者都可以实现页面跳转, 只是redirect可以无延时的重定向, 具体采用哪种情况视具体而定。

  2. success和error 的模板文件可以定制:

  • tp中的分隔符, 是用 depr来表示的 , 不是 dept: 猜测: depr: 是 data/delimiter separator的缩写, 所以 最后那个字符是R不是T.

  • runtime下的 Home目录中的???.php文件 实际上是 从 控制器/操作方法到 生成 模板文件的 中间文件. 每个 {$foo}内容实际上 是转换成了 <?php echo (...); ?>

  • 即使是开启了缓存, 'TMPL_CACHE_ON' =>TRUE, 'TMPL_CACHE_TIME' => 1等设置, 也并不是表示 模板缓存runtime/home/....php文件会随时重新生成新的不同名字的文件, 仍然是同一个 文件名称.

  • strip主要是动词, 表示 "剥夺, 剥掉, 剥皮"等的意思, 而stripe 主要是条带 讲, 没有剥夺的意思.

  • die和exit的区别: 两者实际上是一样的! exit是原函数, die是exit函数的别名alias. 两者可以接受 一个数字或字符串: 具体用法上, 如果是脚本运行多用exit, 如果是web运行, 多用die. 如果传入数值, 表示的是一种 运行结果的状态码 (比如123, 这个状态码数字是不会输出的), 要输出, 得用 字符串方式比如exit('123'), die('123')...

  • success和error 可以使用项目内部的模板文件, 用 TMPL_ACTION_SUCCESS => Public:success 等来定义, 注意, 模板表示文件路径用冒号来表示 , 其中 定义error也是类似的

  • 模板文件中可以使用的 模板标签是: 5个: $msgTitle, $message, $status(1表示成功, 0 表示失败) , $waitSecond, $jumpUrl

  • success和error会自动判断当前请求是否是ajax请求, 如果是ajax请求, 会调用 ajaxReturn方法 返回信息, 返回的数据$data会封装三个变量

$data['info'] = $message;
$data['status'] = $status;
$data['url'] = $jumpUrl;

tp中的查询语言(查询方式)包括很多种,主要有以下这些

  1. 子查询 就是生成$subQuery 语句(子语句), 然后生成的子语句 又用在其他查询语句中.
    子查询有两种方式
    一是在连贯操作后, 使用select(false), false就表示不进行真正的查询结果,而是生产查询子语句;
    二是在连贯操作后, 用 buildSql()方法

  2. 虚拟模型
    是指虽然是模型类, 但是不会进行真正的数据库curd操作,只是借助模型类来封装一些业务逻辑。 实际中几乎没有什么用。
    建立一种思想认识, 就是tp的mysql数据库连接是惰性的: 即只有具有数据库操作: 读写 的时候, 才会去建立数据库连接

  3. 动态查询 这些方法都是通过 __call机制得到的
    就是直接依据表中的某个字段(的值作为查询条件), 返回符合条件的记录(集)或字段的值,主要有两个方法:

  • getBy... 比如根据“name”字段获得记录(集): $User -> getByName('obaa');
  • getFieldBy... 比如根据“name”字段获得字段值: $User -> getFieldByName('foo');
  1. tp中查询条件的表示方法一般、大致有这样几种: $where, $cond, $map.

  2. 在php中,甚至所有的编程语言中, return语句的写法, 后面可以 直接跟 变量,表达式, 甚至直接跟一个复杂的 语句, 比如 return $this->where($where)->getField($args[1]);

  3. 原生sql语句查询

  • 凡是 tp 非原生语句, 都是支持/默认 表前缀的, 比如 think_, 那么凡是 原生语句查询, 都不能支持 表前缀, 那么都要用 表的全名, 或者使用 下划线的方式: 比如: USER, 或 __PREFIX__user.
    tp的模型类也支持 原生的sql语句查询,提供了两个方法:(但是要注意 原生查询就不能使用连贯方法了)
    一个是 query, 只进行查询语句
    另一个是 execute,只进行 增加记录 和 更新记录的操作
    如果设置了 读写分离的话,那么,query始终在读服务器上操作, execute始终在写服务器上操作
  1. 统计查询?
  • **跟上面的 动态查询一样, 统计查询也是使用Model的 __call重载机制实现的, 有 if (in_array(strtolower($method), array('count', 'max', 'min','avg', 'sum'), true表示严格检查类型和大小写匹配)) {... return $this->...} elseif .... **

  • Dejava是法语词, 表示 心灵之境, 似曾相识. Sans Mono 是一种编程中常用的字体

  • php中, else if既可以分开写, 也可以 连起来写: elseif 这样做是为了效率更快

  • in_array函数, 如果是字符串包含检查, 则 最后面不管是false还是true, 都会严格检查字符串字符的 大小写, 如果大小写不符, 都会认为不包含.

  • 统计查询中, count可以有参数 , 常用的是id, 也可以不用参数. 而其他统计 方法必须有参数.

  • 统计查询, 都支持 连贯操作的使用!


1.组合查询
其条件的主体$where还是数组, 但可以组合使用字符串条件_string, 查询_query , 或其他的数组条件_complex
组合查询, 就是多种格式的条件 一起混合使用.
【说明】

  • 但是组合查询中, 除了主体的数组条件外, 其他的特殊查询一次只能定义一个.
  • 由于才用数组索引的方式, 索引/下标相同的特殊查询会被覆盖

关于tp中字段过滤的处理.

首先, 当要插入或更新的data中, 包含了数据表中 没有的字段时, tp会自动过滤掉该字段;
其次, 也有不过滤的情况:

  • 如果你使用了 strict 的连贯操作方法,将严格检查???
  • 如果你开启了 APP_DEBUG 为true的调试模式, 将抛出异常: ??? '_ERROR_QUERY_EXPRESS_' => '错误的查询条件',
  1. tp中的E函数和L函数?
    E函数是 抛出异常, 结尾是 直接是 throw, 不是 return.  在tp中 错误, 叫做" 异常" ??
function E($msg, $code=0) {
    throw new ThinkException($msg, $code);
}

L函数 ,可以获取和设置语言?
L函数中设置的 语言项 是 用下划线 开头和结尾的, 而且是大写

  1. php中的foreach: 有for结构语句, 没有each语句, 所以要使用遍历数组的话,使用的结构是foreach语句.

  2. 分析链式操作的方法名,是在成员函数 protected function _parseOptions($options=array()). 在这个函数中进行了连贯操作的解析. 生成对应的 数据库操作 查询方法或条件

  3. Model类的连贯操作(链操作)方法名,是放在 protected $methods=array('strict','alias', 'table', 'where', 'order','limit'....)数组中的.

  4. 类的成员变量和函数, 除了必须在外部访问的,用 public外, 其他的应该用 protected(本类和子类)和private(只有本类可以访问)都是私有的

  5. 类的常亮, 不能用$符号, 约定使用 全部大写 来表示 常量MEMBER. 只能用类来引用, 在类中 , 如果类目很长, 也可以用self来代替. self$this的区别是, 前者表示类自己, 后者表示类的一个 实例.即 AClass::MEMBER 和 self::MEMBER是一样的. 但是 self只能在类的内部使用, 因为在类的外部self没有上下文的约束, 就无意义了.

  6. 注意 类的常量 const 是 public的,而且, 一般都不用 public去修饰. 因为可以在 类的外部用 AClass::MEMBER 举个例子.

// 可以在类的外部, 比如index.php中访问类的常量: 
print HomeControllerIndexController::INDEX_TYPE;

在IndexController类中, 可以直接用self访问:
   print IndexController::INDEX_TYPE.'<BR>';
   print self::FOO_TYPE;

  1. tp支持区间查询?
    就是针对同一个字段的多个查询条件的组合. $where用数组表示, 其中的条件可以是字符串,数组,表达式等任何形式的. 最后的一个数组元素(参数)表示 条件组合类型,有'OR,XOR,AND', 默认不写的时候表示 AND.
$where['name'] = array( array('like',  '李%'), '张三', array('exp', 'in("李四", "王五")'),'OR');
  1. 在tp中, 配置文件或语言文件中,表示某个意思的单词, 通常用缩写, 或者"基本单词", 后面一般不加后缀的,比如tion, re等...
    比如'BUILD_DIR_SECURE' (不用security), 'ERROR_QUERY_EXPRESS' 不用expression.

php的header函数:

是将html中 meta 标签的 http-equiv 属性值和 content属性值, 放在一起来写的. 但是不要 meta和http-equiv和content,所以显得更加简洁. header('Content-type: text/html; charset=utf-8 ');

使用的L语言配置项要写正确, 特别是最后的下划线, 否则,会按原样显示... 比如: L('_ERROR_QUERY_EXPRESS'); 将会是错误的, 还是按原样输出_ERROR_QUERY_EXPRESS


通常在php中引号用单引号(只有要在字符串中解析$foo变量的时候才用双引号), 但是在操作数据库语句 sql语句中的时候, 要使用双引号,包括在html中的属性时也要使用双引号.

php中的echo和print?

  • 两者几乎是一样的, 凡是echo可以使用的地方, print也可以使用, 反之亦然
  • echo和print都是 语言结构(什么叫语言结构? 就是 关键词, 比如case, if, foreach等之类的...) 所以, 后面不需要 加 括号.
  • 通常还是在php中用echo. 只是如果你熟悉/习惯 了 c/c++ 语言风格的话, 你可以使用print语句.
  • 两者的细微区别是: print 同时/一次 只能输出 一个 字符串, 不能输出多个字符串; echo可以 同时输出多个字符串.
  • echo 不需要括号, 如果加括号, 则只能每个字符串都加括号, 不能把多个字符串放在一个括号中. 否则会 报错! 和print的错误输出一样" 非法的逗号".

  1. tp中的表达式查询?
  • 主要是为了 解决复杂条件查询, 比如 like, 大于等于, not between等之类的条件
    表达式查询, 用数组来表示.

  • 实际上就是将 字段 比较运算符和 比较的具体值 分开来写: 比如 字符串条件 $where = 'age>=10' 中包含三个部分, 一个是数据库字段, 一个是比较运算符 一个是比较值. 表达式查询方式就是: 将字段写在数组的'下标'中, 然后将比较运算符和 比较值分开写, 来放在另外的数组中: $where ['age'] = array('egt', 10);

  • 也可以将 比较运算符和 比较值放在一起写 (像原生的sql), 那么 后面的array, 就用 'exp' 来表示. 比如: $where [age] = array('exp', 'between(10, 20)');

  1. tp中的条件查询?
    可以使用 字符串/字符串预处理/数组/对象 等 方式都是可以的, 但是 tp推荐的是使用 数组方式, 更高效更安全.
    多字段条件的数组方式, 默认的逻辑是and, 但是可以用 $conditon['_logic'] = 'or'; 来改变.
    如果用对象的话, 要初始化一个 用在 条件 $where中的对象, 使用 $where = new stdClass(); 来定义

  2. tp中的快捷查询? 就是 多个字段的条件值 相对应赋值

  • 只支持两种 逻辑运算符, 也就是只有两种情况: & 和 |
  • & 和 | 只能放在 前面的 数组 的 索引字段 中 , 而不能放在后面的条件中, 因为条件是用array(....) 数组来表示的.
  • 而且 & 的话, 后面数组条件的最后一个值 必须是 '_multi' => true $where['a&b&c'] = array(1, '2', 3, '_multi' => true);
  • 对于 | , 只只适用于 多个字段对应同一值的情形, 如果是 同一个字段 对应多个 值的 情形, 请使用 字段的区间查询... $where['foo|bar'] = 'foobar';

tp查询语句中的 like? 特别补充两点

  1. like的array数组, 支持 多个值的情形: 而且支持用and /or等逻辑连接: $where ['name'] = array('like', array('think%', '%foo%', 'other-foo'), 'or' );
  2. like 的字段模糊查询, 你可以手动的写百分号, 也可以在配置中设置模糊查询, 这样在like 查询条件中, 就不用写百分号了. 设置是: 'DB_LIKE_FIELDS' => 'title|content|memo等字段' 那么对应的查询条件就是: $where = array('like', array('think', 'foo', 'other' );

原文地址:https://www.cnblogs.com/bkylee/p/8820409.html