redmine可以创建自定义字段,我经常用它来满足不同的管理需求,现在来解读一下,看看这些自定义字段是如何存在mysql表中的。
表issues
用来存放issue的标准字段。
mysql> describe issues;
+----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| tracker_id | int(11) | NO | MUL | NULL | |
| project_id | int(11) | NO | MUL | NULL | |
| subject | varchar(255) | NO | | | |
| description | text | YES | | NULL | |
| due_date | date | YES | | NULL | |
| category_id | int(11) | YES | MUL | NULL | |
| status_id | int(11) | NO | MUL | NULL | |
| assigned_to_id | int(11) | YES | MUL | NULL | |
| priority_id | int(11) | NO | MUL | NULL | |
| fixed_version_id | int(11) | YES | MUL | NULL | |
| author_id | int(11) | NO | MUL | NULL | |
| lock_version | int(11) | NO | | 0 | |
| created_on | datetime | YES | MUL | NULL | |
| updated_on | datetime | YES | | NULL | |
| start_date | date | YES | | NULL | |
| done_ratio | int(11) | NO | | 0 | |
| estimated_hours | float | YES | | NULL | |
| parent_id | int(11) | YES | | NULL | |
| root_id | int(11) | YES | MUL | NULL | |
| lft | int(11) | YES | | NULL | |
| rgt | int(11) | YES | | NULL | |
| is_private | tinyint(1) | NO | | 0 | |
| closed_on | datetime | YES | | NULL | |
| position | int(11) | NO | MUL | NULL | |
| remaining_hours | float | YES | | NULL | |
| release_id | int(11) | YES | MUL | NULL | |
| story_points | float | YES | | NULL | |
| release_relationship | varchar(255) | NO | MUL | auto | |
+----------------------+--------------+------+-----+---------+----------------+
表custom_fields
该表字段都和创建自定义字段的web页面看到的选择项很像。
mysql> describe custom_fields;
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| type | varchar(30) | NO | | | |
| name | varchar(30) | NO | | | |
| field_format | varchar(30) | NO | | | |
| possible_values | text | YES | | NULL | |
| regexp | varchar(255) | YES | | | |
| min_length | int(11) | YES | | NULL | |
| max_length | int(11) | YES | | NULL | |
| is_required | tinyint(1) | NO | | 0 | |
| is_for_all | tinyint(1) | NO | | 0 | |
| is_filter | tinyint(1) | NO | | 0 | |
| position | int(11) | YES | | 1 | |
| searchable | tinyint(1) | YES | | 0 | |
| default_value | text | YES | | NULL | |
| editable | tinyint(1) | YES | | 1 | |
| visible | tinyint(1) | NO | | 1 | |
| multiple | tinyint(1) | YES | | 0 | |
| format_store | text | YES | | NULL | |
| description | text | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
表custom_values
mysql> describe custom_values;
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| customized_type | varchar(30) | NO | MUL | | |
| customized_id | int(11) | NO | | 0 | |
| custom_field_id | int(11) | NO | MUL | 0 | |
| value | text | YES | | NULL | |
+-----------------+-------------+------+-----+---------+----------------+
该表可以用custom_field_id字段和custom_fields表的id关联。
而customized_id 可以和issues表的id相关联
因此三个表issues, custom_fields和custom_values在一起表达了这么个关系。
一个issue的标准字段来自issues表,扩展字段来自custom_fields表,而custom_values和前custom_fields表关联,一起表示一个issue的某个自定义字段的值。
并且,当表示issue的自定义字段时,custom_fields.type的值是 ‘IssueCustomField‘ 而custom_values.customized_type的值是‘Issue‘.
所有issue的自定义字段值
因此可以先将custom_fields表和custom_values表关联,获得如下结果:
mysql> select customized_id as issue_id,custom_field_id,type,name,default_value,value from custom_fields a inner join custom_values b on a.id = b.custom_field_id limit 10;
+----------+-----------------+------------------+--------------+---------------+-----------------------------+
| issue_id | custom_field_id | type | name | default_value | value |
+----------+-----------------+------------------+--------------+---------------+-----------------------------+
| 2 | 1 | IssueCustomField | 关闭原因 | ... | ... |
| 121 | 1 | IssueCustomField | 关闭原因 | ... | 移动逆袭完成 |
| 122 | 1 | IssueCustomField | 关闭原因 | ... | 暂时不做 |
| 123 | 1 | IssueCustomField | 关闭原因 | ... | 人员离职 |
| 124 | 1 | IssueCustomField | 关闭原因 | ... | 人员离职 |
| 125 | 1 | IssueCustomField | 关闭原因 | ... | 人员离职,论坛改版 |
| 126 | 1 | IssueCustomField | 关闭原因 | ... | 重新规划 |
| 127 | 1 | IssueCustomField | 关闭原因 | ... | 暂时不涉及 |
| 128 | 1 | IssueCustomField | 关闭原因 | ... | 暂时不涉及 |
| 129 | 1 | IssueCustomField | 关闭原因 | ... | 暂时不涉及 |
+----------+-----------------+------------------+--------------+---------------+-----------------------------+
通常这个表都会很大,我的系统里面有22个自定义字段,同时有500多个issue,每个issue最多会有22个行表示其自定义字段的值。因此所有issue的自定义字段的值的累计行数超过1万行。
由此可以看出redmine的设计是用记录行数来表示扩展字段的值,所以可以不受mysql表字段的限制。
原文:http://blog.csdn.net/csfreebird/article/details/41950719