Jun 24

这是我给部门同事做的技术分享.

当今绝大部分的软件系统都用到了关系数据库, 所以, 作为软件开发工程师, 必须掌握关系数据库应用设计能力.

Written by ideawu at 2011-06-24 18:02:57 | tags:

May 21

最近做了一次MySQL所谓的”海量数据”查询性能分析.

表结构

dt dt2 dt3 it it2 it3
id id id id id id int PK
ext1 ext1 varchar(256)
time time time time time time int/datetime KEY
ext2 ext2 ext2 ext2 varchar(128)

说明, MyISAM引擎, dt表示时间字段使用datetime类型, it表示时间字段使用int类型.

初始数据

首先生成100K个UNIX时间戳(int), 然后随机选取10M次, 每一次往6个表里插入一条记录(当time字段是datetime类型时, 做类型转换). 所以每一个表都有10M条记录. ext1和ext2字段会用随机的字符串填充.

Continue reading »

Written by ideawu at 2011-05-21 10:18:05 | tags:

Dec 29

使用Ubuntu Linux, 编译过程提示缺啥补啥即可.

Apache:

./configure --prefix=/home/work/httpd --enable-so --enable-rewrite --enable-vhost-alias

配置文件:

LoadModule php5_module        modules/libphp5.so
AddType application/x-httpd-php .php
# PhpIniDir /home/work/php/php.ini

MYSQL:

Continue reading »

Written by ideawu at 2009-12-29 11:32:25 | tags: ,

Nov 23

Yii的AR类, 可以在rules()函数中声明验证规则. 但指定了验证规则, 也可以不使用. 在调用save()方法时, 如何第一个参数为false(默认为true), 则不进行验证. 一旦验证失败, 将立即返回, 不保存数据. Yii提供的工具可以根据数据库表定义自动生成验证规则. AR类的验证规则的另一个功能是用于自动生成HTML页面表单. 但是, 根据实际使用情况, Yii所提供的这个功能在XXX项目中几乎已经成为鸡肋, 都是在开发者不知情的情况下使用了.

Yii的这个特性, 加上数据库表设计的失误, 以及代码逻辑问题, 导致某个功能出现BUG.

代码的功能是这样的: 调用AR类的save()方法保存一条记录, 然后跳转到该记录的详细信息页面. 实际操作时, 偶尔出现记录未保存, 然后跳转URL里的id参数为空. 代码逻辑如下:

if($ar->save()){
    // do something
}
redirect($ar->id);

显然, 代码逻辑没有错误处理, 无论成功与否, 都跳转. 下面再分析保存失败的原因.

数据库表定义中, 备注字段的类型为VARCHAR(255), 如何短的字符串类型的应用范围一般很窄, 再加上所对应的业务字段是备注信息, 往往是大段的文本, 所以, 数据库设计已经失败, 出错是必然的. 另外, 程序逻辑无论是客户端还是服务器端, 都没有再做业务层的验证给出错误提示, 而是无意地使用了Yii框架的AR类的验证机制. 综合上述原因, BUG的查找花费了不少的时间.

总结:

1. 数据库设计

通过对数据库表字段的仔细选择来获取性能, 对于XXX系统, 这种方式已经过时. 一般只有如下几种数据类型: 数字, 字符串(varchar), 文本(长字符串, text), 时间.

结合 MySQL, 数字主要使用int, 像tiny int, middle int之类的整数类型, 只是节省空间考虑, 速度上反而比int类型要慢, 当数值较大时, 使用bigint. 对XXX, 除了int和bigint, 其它的整数类型都没有必要.

对于字符串和文本类型, 如果不建立索引作为查询条件, 一般使用text, 不要使用varchar, 如果文本较长, 则使用longtext. 如果字段对应的输入框是多行文本框, 那么就没有使用varchar的必要了. 建议原则是: 不建立索引的字符串使用text, 格式化输入框(HTML编辑控件)对应的字段使用longtext, 只有建立索引的字符串才使用varchar.

2. AR类设计

把AR类中的rules()函数删除.

3. 客户端验证

在客户端也做验证, 并在出错时提示用户. 如用户输入的文本过长, 等等.

Written by ideawu at 2009-11-23 16:58:12 | tags:

Aug 25

MySQL 建立外键约束的语法太晦涩难懂了, 不得不记下笔记.

1. 在建表时建立外键

CREATE TABLE table_s (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `column_name_from` int(11) NOT NULL,
  `name` varchar(256) NOT NULL,
  PRIMARY KEY (`id`),
  INDEX k_name (`column_name_from`),
  CONSTRAINT fk_name FOREIGN KEY(column_name_from) REFERENCES other_table_name(column_name_to) ON UPDATE CASCADE
) engine=innodb;

2. 对已有的表增加外键

alter table table_name add constraint fk_name foreign key (column_name_from) references other_table_name(column_name_to) on update cascade;

外键是”fk_name”, 如果 column_name_to 没有索引, 则会建立一个名为”fk_name”的索引;

3. 删除外键

先删除外键, 再删除索引.

alter table table_name drop foreign key fk_name;
alter table table_name drop key fk_name;

如果在删除外键之前删除索引, 会提示 #1025 – Error on rename of ‘./abc/#sql-fa9_2a9a1′ to ‘./abc/table_name’ (errno: 150)

4. 查看外键的名字

show create table table_name;

5. 建立索引

create index index_name on table_name (column_name);

alter table table_name add index index_name (column_name);

Written by ideawu at 2009-08-25 19:13:11 | tags: