dbschema 数据库表定义文件


在ecos框架前,我们使用PowerDesigner来管理这些表结构,但是在一些项目的版本管理过程中,有时需要维护多个版本。 powerdesigner的储存文件为一个单一的巨大的xml格式pdm文件。 这在进行版本的合并分支时几乎无法处理。 而在ecos,我们使用php去描述表结构有了以下几个优势:

  • 数据库定义具有版本管理特性
    • 各分支开发互不干扰
    • 协同更改时,可以进行合并操作
    • 针对单表的版本还原与操作日志
    • 容易做自动化的表结构对比
  • 按照用途来定义字段类型,不会出现同一种数据类型而字段定义不一致的情况
  • 简单的外键实现,方便的统计表的依赖关系,使得外键字段定义完全一致
  • 作为数据抽象层, 我们可以更用以
  • app 更容易扩展独立的表
  • 将数据库特性进行包装, 可以统一设定, 数据库版本 type = MyISAM DEFAULT CHARACTER SET语法 等

dbschema 是什么

我们先看一下base/dbschema/apps.php 文件

可以将注释中间的代码去掉 注释中间的代码和desktop app相关

<?php 
$db
['apps']=array ( 
    
'columns' =>  
        array ( 
            
'app_id' => array( 
                
'type' => 'varchar(32)', 
                
'required' => true, 
                
'default' => '', 
                
'pkey' => true, 
                
// begin 和desktop相关 ---------------------- 
                
'width' => 100, 
                
'label' => app::get('base')->_('程序目录'), 
                
'hidden' => 1, 
                
'editable' => false, 
                
'in_list' => true, 
                
'default_in_list' => false, 
                
// end -------------------------------------- 
            
), 
            
'app_name' => array( 
                
'type' => 'varchar(50)', 
                
// begin 和desktop相关 ---------------------- 
                
'width' => 150, 
                
'label' => app::get('base')->_('应用程序'), 
                
'is_title'=>1//在链接表中显示的字段 
                
'in_list' => true, 
                
'default_in_list' => 1 
                
// end -------------------------------------- 
            
), 
            
'debug_mode' => array( 
                
'type' => 'bool', 
                
'default' => 'false', 
                 
// begin 和desktop相关 ---------------------- 
                
'width' => 100, 
                
'label' => app::get('base')->_('调试模式'), 
                
'in_list' => true, 
                
'default_in_list' => false 
                
// end -------------------------------------- 
            
), 
            
'app_config' => array( 
                
'type' => 'text' 
            
), 
            
'status' =>  array( 
                
'type' => array ( 
                    
'installed' => app::get('base')->_('已安装, 未启动'), 
                    
'resolved' => app::get('base')->_('已配置'), 
                    
'starting' => app::get('base')->_('正在启动'), 
                    
'active' => app::get('base')->_('运行中'), 
                    
'stopping' => app::get('base')->_('正在关闭'), 
                    
'uninstalled' => app::get('base')->_('尚未安装'), 
                    
'broken' => app::get('base')->_('已损坏'), 
                ), 
                
// begin 和desktop相关 ---------------------- 
                
'label' => app::get('base')->_('状态'), 
                
'width' => 100, 
                
'default' => 'uninstalled', 
                
'in_list' => true, 
                
'default_in_list' => true, 
                
// end -------------------------------------- 
            
), 
            
'webpath'=> array( 
                
'type'=>'varchar(20)' 
            
), 
            
'description'=> array( 
                
'type'=>'varchar(255)', 
                
// begin 和desktop相关 ---------------------- 
                
'width' => 300, 
                
'label' => app::get('base')->_('说明'), 
                
'in_list' => true, 
                
'default_in_list' => 1 
                
// end -------------------------------------- 
            
), 
            
'local_ver'=> array( 
                
'type'=>'varchar(20)', 
                
// begin 和desktop相关 ---------------------- 
                
'width' => 100, 
                
'label' => app::get('base')->_('当前版本'), 
                
'in_list' => true, 
                
'default_in_list' => 1 
                
// end -------------------------------------- 
            
), 
            
'remote_ver'=> array( 
                
'type'=>'varchar(20)', 
                
// begin 和desktop相关 ---------------------- 
                
'width' => 100, 
                
'label' => app::get('base')->_('最新版本'), 
                
'in_list' => true, 
                
'default_in_list' => false 
                
// end -------------------------------------- 
            
), 
            
'author_name'=> array( 
                
'type'=>'varchar(100)' 
            
), 
            
'author_url'=> array( 
                
'type'=>'varchar(100)' 
            
), 
            
'author_email'=> array( 
                
'type'=>'varchar(100)' 
            
), 
            
'dbver'=> array( 
                
'type'=>'varchar(32)' 
            
), 
            
'remote_config'=> array( 
                
'type'=>'serialize' 
            
) 
        ), 
    
'version' => '$Rev: 44008 $', 
    
'unbackup' => true, 
); 
?> 

这个就是以上代码经过解析后生成的sql语句

CREATE TABLE `sdb_base_apps` (
	`app_id` varchar(32) not null default '',
	`app_name` varchar(50),
	`debug_mode` enum('true','false') default 'false',
	`app_config` text,
	`status` enum('installed','resolved','starting','active','stopping','uninstalled','broken') default 'uninstalled',
	`webpath` varchar(20),
	`description` varchar(255),
	`local_ver` varchar(20),
	`remote_ver` varchar(20),
	`author_name` varchar(100),
	`author_url` varchar(100),
	`author_email` varchar(100),
	`dbver` varchar(32),
	`remote_config` longtext,
	primary key (app_id)
)ENGINE = MyISAM DEFAULT CHARACTER SET utf8;

dbschema文件有几个重要的功能

1. 描述表结构

2. 定义desktop app的列表项

用dbschema来描述表结构

ecos安装时,会扫描相关app中的dbschema中的文件,用这个文件生成相应的表结构并创建

约定:

    文件名 apps.php 对应于 $db['apps'] 生成的表名为 [prefix]_[appname]_apps
       如: 表前缀: sdb
           文件: base/dbschemma/apps.php 
           生成的表名为 sdb_base_apps
           与之对应的model为  base_mdl_apps

columns

表字段

<?php 
'columns' => array( 
    
'ref_id' => array(          // 字段名称 
        
'type' => 'int(8)',     // 字段类型 
        
'required' => true,     // 不能为空 默认为false 
        
'pkey' => true,         // 是否是主键 默认为false 
        
'label' => 'id', 
        
'editable' => false, 
        
'extra' => 'auto_increment'// 自增 
    
), 
    
'goods_id' => array( 
        
'type' => 'table:goods',  // 对应用于同一app下goods表中的主键类型 
        
'default' => 0,           // 默认值 
        
'required' => true 
        
'editable' => false, 
    ), 
    
'status' =>  array( 
        
'default' => 'uninstalled', 
        
'type' => array (  // 生成枚举类型 enum('installed','resolved','starting'....) 
            
'installed' => app::get('base')->_('已安装, 未启动'),  
            
'resolved' => app::get('base')->_('已配置'),  
            
'starting' => app::get('base')->_('正在启动'),  
            
'active' => app::get('base')->_('运行中'),  
            
'stopping' => app::get('base')->_('正在关闭'),  
            
'uninstalled' => app::get('base')->_('尚未安装'),  
            
'broken' => app::get('base')->_('已损坏'),  
        ), 
        
'label' => app::get('base')->_('状态'),  
        
'width' => 100, 
        
'in_list' => true 
        
'default_in_list' => true 
   ) 
) 
?> 

字段名称

字段名称就是键值
<?php 
'columns' => array( 
    
'goods_id' => array(), 
) 

sdf

type

1 mysql字段类型

<?php 
'author_name'=> array( 
    
'type'=>'varchar(100)' 
) 
?> 
生成的语句是 `author_name` varchar(100),

还有 int(n),varchar(n),text,等mysql字段的类型

2 枚举类型

<?php 
'status' =>  array( 
    
'default' => 'uninstalled', 
    
'type' => array (  // 生成枚举类型 enum('installed','resolved','starting'....) 
        
'installed' => app::get('base')->_('已安装, 未启动'),  
        
'resolved' => app::get('base')->_('已配置'),  
        
'starting' => app::get('base')->_('正在启动'),  
        
'active' => app::get('base')->_('运行中'),  
        
'stopping' => app::get('base')->_('正在关闭'),  
        
'uninstalled' => app::get('base')->_('尚未安装'),  
        
'broken' => app::get('base')->_('已损坏'),  
) 
?> 
将生成的sql语句 `status` enum('installed','resolved','starting','active','stopping','uninstalled','broken') default 'uninstalled',

desktop中的高级搜索将产生一个select选项可以进行选择

3 money

<?php 
'price' =>  array( 
    
'default' => '0.00', 
    
'type' => 'money' 
) 
?> 
将生成的sql语句 'price' decimal(20,3) default 0.00

涉及到金额类的可以直接使用这个,你还在犹豫什么呢

使用dbeav的save时会验证是否是money类型的数据 如果不是将抛出异常

4 email

<?php 
'email' =>  array( 
    
'type' => 'email' 
) 
?> 
将生成的sql语句 'email' varchar(255)

使用dbeav的save时会验证是否是email类型的数据 如果不是将抛出异常

5 bn

<?php 
'bn' =>  array( 
    
'type' => 'bn' 
) 
?> 
将生成的sql语句 'bn' varchar(255)

商品的货号 货品的货号,订单项的货号等等是使用的这个 便于理解

6 html

<?php 
'content' =>  array( 
    
'type' => 'html' 
) 
?> 
将生成的sql语句 'content' text

商品详情 文章内容等等是使用的这个 一下就知道这个是使用编辑器处理的数据 便于理解

7 bool

<?php 
'disabled' =>  array( 
    
'default'=>'false' 
    'type' 
=> 'bool' 
) 
?> 
将生成的sql语句 'disabled' enum('true','false') default 'false'

一般一些开关类型的字段可以选这种类型

8 time

<?php 
'create_time' =>  array( 
    
'type' => 'time' 
) 
?> 
将生成的sql语句 'create_time' int(10) unsigned

存储时间类的类型 在desktop的高级搜索里绑定日历

9 cdate

<?php 
'create_time' =>  array( 
    
'type' => 'cdate' 
) 
?> 
将生成的sql语句 'create_time' int(10) unsigned

和 time的区别在于 在desktop的高级搜索里没有绑定日历,一般不用于高级搜索

10 intbool

<?php 
'is_open' =>  array( 
    
'default'=>'0' 
    'type' 
=> 'intbool' 
) 
?> 
将生成的sql语句 'is_open' enum('0','1') default '0'

和bool类型区别不大 个人习惯问题 一般一些开关类型的字段可以选这种类型

11 region

<?php 
'area' =>  array( 
    
'type' => 'region' 
) 
?> 
将生成的sql语句 'area' varchar(255)

12 password

<?php 
'passwd' =>  array( 
    
'type' => 'password' 
) 
?> 
将生成的sql语句 'passwd' varchar(32)

一般存储密码的字段 一般是md5加密后的字符 便于理解

13 tinybool

<?php 
'is_open' =>  array( 
    
'default'=>'N' 
    'type' 
=> 'tinybool' 
) 
?> 
将生成的sql语句 'is_open' enum('N','Y') default 'N'

和intbool,bool类型区别不大 个人习惯问题 一般一些开关类型的字段可以选这种类型

14 number

<?php 
'nums' =>  array( 
    
'type' => 'number' 
) 
?> 
将生成的sql语句 'nums' mediumint unsigned

一般用于数量等类型

15 float

<?php 
'rate' =>  array( 
    
'type' => 'float' 
) 
?> 
将生成的sql语句 'rate' float

16 gender

<?php 
'sex' =>  array( 
    
'type' => 'gender' 
) 
?> 
将生成的sql语句 'sex' enum('male','false') NULL

用于会员性别

17 ipaddr

<?php 
'ip' =>  array( 
    
'type' => 'ipaddr' 
) 
?> 
将生成的sql语句 'ip' varchar(20)

ip地址 便于理解

18 serialize

<?php 
'config' =>  array( 
    
'type' => 'serialize' 
) 
?> 
将生成的sql语句 'config' longtext

一般使用此类型的字段 在使用dbeav的save 时传入的数据是一个数组保存时将以系列化形式保存入库在使用dbeav的dump时此类型字段将从数据库取出后反系列化后返回

19 last_modify

<?php 
'update_time' =>  array( 
    
'type' => 'last_modify' 
) 
?> 
将生成的sql语句 'update_time' int(10) unsigned

和time类型相似 只是名称可以理解成 最后更新时间

20 关联表主键

<?php 
'type_id' =>  array( 
    
'type' => 'table:table_name' 
) 
?> 
将本app下的table_name这个表的关键字作为关联关系

在desktop的高级搜索里这个字段会取出所有相关的数据

required

是否必填 必填:true, 可以不填:false(默认)mysql中的" not null "

default

默认值mysql中的" default null "

pkey

是否是主键 是:true, 否:false(默认)mysql中的" primary key (app_id) "

extra

扩展值(可以这什么说吧)

'extra' => 'auto_increment' mysql中的 " AUTO_INCREMENT "

'extra' => 'CHARACTER SET "utf8"' mysql中的 " CHARACTER SET 'utf8' "

index

索引 默认为空

以下是mysql创建索引的语法说明

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
    [index_type]
    ON tbl_name (index_col_name,...)
[index_type]
 
index_col_name:
    col_name [(length)] [ASC | DESC]
 
index_type:
    USING {BTREE | HASH | RTREE}
在dbschema上的设置索引
<?php 
'index' => array ( 
    
'ind_prefix' => array( // 索引名称 
        
'columns' => array( // 要创建索引的数据库字段名 
            
=> 'prefix', 
        ), 
        
'prefix' => '' // 索引的类型 UNIQUE|FULLTEXT|SPATIAL 如果为空 为一般的索引 
        
'type' => '' // 指定索引算法 BTREE | HASH | RTREE 
    
) 
) 
?> 

version

版本号
<?php 
'version' => '$Rev: 44008 $' 
?> 

unbackup

是否备份 true:不备份, false:备份(默认)
<?php 
'unbackup' => true 
?> 

ignore_cache

是否缓存 true:不缓存, false:缓存(默认)
<?php 
'ignore_cache' => true 
?> 

engine

mysql引擎 如果没有指定 为mysql默认设置
<?php 
'engine' => 'innodb' 
?> 

comment

表描述
<?php 
'comment' => app::get('b2c')->_('商品规格索引表') 
?> 

用dbschema来定义 desktop的列表

1 label

<?php 
'label' => app::get('b2c')->_('分类') 
?> 


2 width

<?php 
'width' => "150" 
?> 

定义desktop列表中本列的初始宽度

3 editable(已弃用)

<?php 
'editable' => true 
?> 

定义在desktop列表中本列数据数据是否能进行编辑

是否在列表上进行编辑 true:可以 false:不可以(默认)

4 in_list

<?php 
'in_list' => true 
?> 

定义在desktop列表中是否显示 true:是 false:否(默认)

5 default_in_list

<?php 
'default_in_list' => true 
?> 

默认在desktop列表中是否显示 true:是 false:否(默认)如果有相关列表项配置 按配置显示

6 filterdefault

<?php 
'filterdefault' => true 
?> 

默认在desktop高级搜索中是否默认显示 true:是 false:否(默认)如果有相关搜索项配置 按配置显示

7 filtertype,filtercustom

<?php 
'filtertype' => 'normal' // normal按type的来生成过滤  custom 按dbschema中设定的filtercustom 设置过滤 
?> 

8 searchtype

列表页中简单搜索的处理方式,如果dbschema中存在searchtype则会在desktop列表上显示相关的简单搜索

如果searchtype=> 则默认为'nequal'

以下是相关代码段自己慢慢理解

<?php 
'than'=>' > '.$var, 
'lthan'=>' < '.$var, 
'nequal'=>' = \''.$var.'\'', 
'noequal'=>' <> \''.$var.'\'', 
'tequal'=>' = \''.$var.'\'', 
'sthan'=>' <= '.$var, 
'bthan'=>' >= '.$var, 
'has'=>' like \'%'.$var.'%\'', 
'head'=>' like \''.$var.'%\'', 
'foot'=>' like \'%'.$var.'\'', 
'nohas'=>' not like \'%'.$var.'%\'', 
'between'=>' {field}>='.$var[0].' and '.' {field}<'.$var[1], 
'in' =>" in ('".implode("','",(array)$var)."') ", 
?> 

9 is_title(2011-04-28:sunjinrong)

该属性的意义为是否为链接显示字段,true(是) false(否),不设置该属性默认为false。注意:该属性为唯一性属性,将多个字段设置为该属性时,会默认显示第一个设置字段。如果被链接的表没有一个字段被设置为,'is_title'=>true,则默认情况会显示该表主键的下一个字段。

bryant写的部分

数据库抽象层dbschema(bryant)

在 ecos框架前,我们使用powerdesigner来管理这些表结构,但是在一些项目的版本管理过程中,有时需要维护多个版本。 powerdesigner的储存文件为一个单一的巨大的xml格式pdm文件。 这在进行版本的合并分支时几乎无法处理。 而在ecos,我们使用php去描述表结构有了以下几个优势:

<?php 
$db
['table_name'] = array( 
    
'columns'=>array( 
        
'col_1'=>array( 
        
'type'=>'int', 
            
'pkey'=>true,'comment'=>'id字段'), //主键 
        
'col_p1'=>array('type'=>'int', 
            
'pkey'=>true,'comment'=>'主键2'),   //联合主键 
        
'col_33'=>array('type'=>'mediumint unsigned'),  
        
//当然也支持通常的type 
        
'col_2'=>array('type'=>'email', 
            
'comment'=>'id字段'),  //email = varchar(255) 
        
'col_3'=>array('type'=>'money', 
            
'notnull'=>true,'default'=>3),  
        
//money = decimal(20,3), 非空字段,默认为3.000 
        
'col_4'=>array('type'=>'html', 
            
'comment'=>'id字段'),   //html = text 
        
'col_4'=>array('type'=>'bool', 
            
'comment'=>'id字段'),   //bool = enum('true','false') 
        
'table2_c1'=>array('type'=>'table_2:c1', 
            
'comment'=>'表table_2的c1字段'),  
        
//类型和table_2的c1字段相同, 当外键处理,自动加索引 
    
), 
    
'index'=>array( 
        
'...',//再定义 
    
) 
    
'engine'=>'heap'//可不填,默认为myisam 
    
'option'=>''//其他扩展语法 
);

有话要说