Data model is the basic idea in database domain.Data model is a collection which describes the tools such as data,data's relationships,data semantics and consistecy constraints.
Data model can be divided into four types:Relational Model,Entity-Relationship Model,Object-based Data Model,Semi-structured Data Model,Semi-structured Data Model(XML).
Everything in the world can be represented by a group of entities and their relationships.
Click "Tools"->"Model Options" menu,and show the following dialog:
Set Notation's value to E/R+Merise。
1)不要将实体集的PrimaryKey作为联系集的属性
2)两个实体集的关系应该用联系表示,而不是将一个实体集的PrimaryKey作为另一个实体集的属性。联系可以明确的表示出实体集的关系。
3)如果实体的属性较为复杂,可以考虑将该属性升级为实体。比如电话号码。
4)当描述发生在实体集之间的行为时采用联系集。
5)非二元联系总是可以使用一组二元联系来替代。在PowerDesigner的帮助下,我们可以直接设计多元联系,当生成PDM的时候,会自动转换成对应的关系模型。
举例如下:
我使用PowerDesigner12.5来管理我的数据库设计。这个软件很方便,可以创建ER模型,然后根据ER模型自动生成关系模型,根据关系模型自动创建数据库(需要配置odbc的dsn)。可惜Linux版本没有。先建立一个workspace,名字为OA,新建一个Conceptual Data Model(用来设计ER模型)OA,在里面添加一个内嵌文件,文件名为数据库描述.txt。该文件的内容就是我们对系统要存储信息的描述:(一个清晰的描述文档对解释数据库的设计由来非常重要,该文档重点解释了系统存储的信息是什么,不要使用数据库相关术语)
关于PowerDesigner的使用,可以参考: http://hi.baidu.com/shiytower/blog/item/39dbab7b10c82ef00bd18777.html
一个IT公司有员工,部门和项目组:
1)系统要存放员工的信息(工号,姓名,出生年月,性别,学历,职务,部门,电话,email,家庭住址,户口,亲属联系方式等)
同时还要存放key和数据块---为了提高安全性,系统不存放密码,只存放key和数据块。三者的关系是key+密码经过加密算法产生数据块。如果以后用户要登陆,必须提供用户名和密码,系统根据用户名查找到对应的key,然后用同样的加密算法计算出数据块,然后和保存的数据块进行比对,如果符合,则登陆成功。不符合则密码不正确。如果用户忘记了密码,只能申请管理员帮助提供默认密码,登陆后自己再修改密码。
2)系统也要存放部门信息(部门名称,部门负责人,部门描述)。
3)员工和部门之间要建立联系。一个员工只能属于一个部门,一个部门可以有多个员工。
4)员工之间也有联系,有上下级关系。一个员工可以有几个上级(参与不同的项目),一个员工也可以有多个下级。
5)员工分为若干等级--PG(项目程序员),PL(项目小组长),PM(项目经理),TB(担当部长),B(部长),HB(本部部长),CEO等。(按照日本公司的习惯举例)
6)系统要管理项目信息(项目名称,项目负责人,项目描述,项目开始时间,项目结束时间)
7)员工和项目组的联系类似于员工和部门的联系
8)项目组可以细分为Team。每个Team都有PL,也有开始时间和结束时间,还有职责描述和TeamID以及名称。
9)员工日报记录员工每天参与了那些项目,每个项目工作时间从几点到几点,以及相对应的工作内容。(注意,员工日报原来作为员工的一个复杂属性,上升为一个实体)
这是一个简单的例子,我们看看如何用上面的规则来设计一个好的E-R模型。这段描述有点像面向对象分析开始时使用的描述,但是不同之处在于这里的描述关注系统要管理的信息,而面向对象系统分析的描述关注的是系统要完成的业务。因此我们不必在这里描述业务关系。
下图展示了PowerDesigner的画面:
Employee实体代表员工,有如下属性
Property |
Type |
Restriction |
WorkID |
String |
PK,0<10 |
Name |
String |
not null,0<20 |
Birthday |
DateTime |
|
Gender |
Char |
只能是这三种字Male(男),Female(女),X(代表两性人),not null |
EducationBackground | String |
length<200 |
Level |
String,多值属性 |
legnth<50,not null,只能从PG,PL,PM,TB,B,HB,CEO中取值 |
Telephone |
多值属性 |
|
Email |
多值属性 |
|
HomeAddress |
String |
length<200 |
RegisteredPermanentResidence | String |
legnth<50 |
Property |
Type |
Restriction |
Level |
String |
PK,只能从PG,PL,PM,TB,B,HB,CEO中取值 |
Property |
Type |
Restriction |
WorkID |
String |
PK,length<10 |
Name |
String |
not null,length<20 8)项目组可以细分为Team。每个Team都有PL,也有开始时间和结束时间,还有职责描述和TeamID以及名称。 |
Birthday |
Date |
|
Gender |
Char |
只能是这三种字Male(男),Female(女),X(代表两性人),not null |
EducationBackground | String |
length<200 |
HomeAddress |
String |
length<200 |
RegisteredPermanentResidence | String |
legnth<50 |
Property |
Type |
Restriction |
WorkID |
String |
PK,派生属性,值为Empolyee实体WorkID所有值之一 |
Telephone |
String |
PK,0<20 |
Type |
String |
not null,值为Home,Mobile,Bussiness所有值之一 |
Property |
Type |
Restriction |
WorkID |
String |
PK,派生属性,值为Empolyee实体WorkID所有值之一 |
Email |
String |
PK,0<20 |
Type |
String |
not null,值为Home,Business所有值之一 |
Property |
Type |
Restriction |
WorkID |
String |
PK,length<10,派生属性,值为Empolyee实体WorkID所有值之一 |
Date |
String |
PK |
ProjectID |
String |
PK,派生属性,值为Project实体ProjectID所有值之一 |
StartTime |
DateTime |
not null |
FinishTime |
DateTime |
not null |
Description |
String |
not null |
Property |
Type |
Restriction |
BranchID |
String |
PK,0<10,B字母开头 |
Name |
String |
not null,0<20 |
ManagerID |
String |
派生属性,值为Empolyee实体的ProjectWorkID所有值之一 |
Description |
String |
0<400删除异常的情况,读者可自行分析得知。 |
Property |
Type |
Restriction |
ProjectID |
String |
PK,0<10,P字母开头 |
Name |
String |
not null,0<20 |
ManagerID |
String |
派生属性,值为Empolyee实体的WorkID所有值之一 |
Description |
String |
0<400 |
StartTime |
DateTime |
|
FinishTime |
DateTime |
Property |
Type |
Restriction |
TeamID |
String |
PK,0<10,T字母开头 |
Name |
String |
not null,0<20 |
Leader |
String |
派生属性,值为Empolyee实体的WorkID所有值之一 |
Description |
String |
0<400 |
StartTime |
DateTime |
|
FinishTime |
DateTime |
Property | Type | Restriction | |
WorkID |
String |
PK,派生属性,值为Empolyee实体的WorkID所有值之一 | |
BossID |
String |
PK,派生属性,值为Empolyee实体的WorkID所有值之一 | |
StartTime |
DateTime |
||
FinishTime |
DateTime |
Property | Type | Restriction |
WorkID |
String |
PK,派生属性,值为Empolyee实体的WorkID所有值之一 |
BranchID |
String |
派生属性,值为Branch实体的BranchID所有值之一 |
StartTime |
DateTime |
|
FinishTime |
DateTime |
Property | Type | Restriction |
WorkID |
String |
PK,派生属性,值为Empolyee实体的WorkID所有值之一 |
ProjectID |
String |
PK,派生属性,值为Project实体的ProjectID所有值之一 |
StartTime |
DateTime |
|
FinishTime |
DateTime |
Property | Type | Restriction |
WorkID |
String |
PK,派生属性,值为Empolyee实体的WorkID所有值之一 |
TeamID |
String |
PK,派生属性,值为ProjectTeam实体的TeamID所有值之一 |
StartTime |
DateTime |
|
FinishTime |
DateTime |
E-R模型转换为关系数据模型的方法
1.实体集合转换成关系。实体集合的属性作为关系集合的属性。实体集合的关键字作为关系集合的关键字
2.联系转换为关系。所有参加联系的实体集合的关键字作为关系的属性,关系的关键字由联系类型决定
3.合并关系,把具有共同关键字的关系合并,属性并作为新关系的属性
4.不能表示"is a"关系。处理办法:在实体的集合增加属性来表示他们的层次关系。
E-R模型向关系模型转换的原则
1.将每个实体转换为一个关系
2.所有主码必须定义为非空
3.一个1:1的联系可以转换位一个独立的关系也可以与任意一端对应的关系合并
4.一个1:n的联系可以转换为一个独立的关系,也可以与n端对应的关系合并
5.一个m:n的联系转换为一个关系
6.三个或三个以上实体间的一个多元联系可以转换为一个关系
7.将超类和子类分别转换为一个关系,超类转换的关系为父表,子类转换的关系为子表,然后将父表的主码作为子表的外码,实现父表与子表的联系
Property | Type | Restriction |
WorkID |
String |
PK,派生属性,值为Empolyee实体的WorkID所有值之一 |
FamilyName |
String |
PK,0<20 |
Relation |
String |
PK,0<20 |
Telephone |
String |
0<20 |
Email |
String |
0<20PK,派生属性,值为Empolyee实体的WorkID所有值之一 |
Property |
Type |
Restriction |
WorkID |
String |
PK,派生属性,值为Empolyee实体的WorkID所有值之一 |
Name |
String |
not null,0<20 8)项目组可以细分为Team。每个Team都有PL,也有开始时间和结束时间,还有职责描述和TeamID以及名称。 |
Birthday |
DateTime |
|
Gender |
Char |
只能是这三种字M(男),W(女),X(代表两性人),not null |
EducationBackground | String |
length<200 |
Level |
String |
legnth<50,not null,只能是PG,PL,PM,TB,B,HB,CEO之一 |
BranchID |
String |
not null,0<10,派生属性,值为Branch实体的BranchID的所有值之一 |
HomeAddress |
String |
length<200 |
RegisteredPermanentResidence | String |
length<50 |
1)由于powerdesigner有一些问题,所以每次重新设计数据库后生成数据库时要先把mysql中的数据库删除,再建立
2)一般来讲,Entity的primary key应该根据逻辑设计,不一定非要都制定一个ID属性作为PK,但是在mysql运用过程中,如果有些pk长度较大,会导致索引长度溢出错误,这是mysql的bug,这种情况下,只能用ID来作为pk,程序员自己需要保证真正的pk的唯一性。