请问数据库在创建表的时候如何设计表关系,一对一,一对多,多对多 请高手举例说明。谢谢!!!

请问数据库在创建表的时候如何设计表关系,一对一,一对多,多对多 请高手举例说明。谢谢!!!,第1张

多对多关系至少需要3个表,我们把一个表叫做主表,一个叫做关系表,另外一个叫做字典表或者副表(字典表是纪录比较少,而且基本稳定的,例如:版块名称;副表是内容比较多,内容变化的,例如)。

按照数据库的增删查改 *** 作,多对多关系的查找都可以用inner join或者

select * from 主表 where id in (select 主表id from 关系表)

1,角色任命型

特点:关系表两外键组合无重复纪录,关系表一般不需要时间字段和主键,有一个表是字典类型的表。

界面特点:显示主表,用checkbox或多选select设置多选关系。

例如:任命版主(用户表-关系表-版块名称表),角色权限控制等,用户是5个版块版主,只要关系表5行纪录就可以确立,关系表的两个外键具有联合主键性质。

增加关系:如果没有组合纪录,insert之。

删除关系:如果有组合纪录,删除之。

2,集合分组型

特点:同角色任命型类似,关系表两外键组合无重复纪录,关系表一般不需要时间字段和主键。区别是主副表都不是字典表,可能都很大不固定。

界面特点:显示主表,用搜索代替简单的checkbox或多选select,或者一条一条的添加。

例如:歌曲专集(专集表-关系表-歌曲表)。手机分组(分组表-关系表-手机表)。用户圈子(圈子表-关系表-用户表)。文章标签(文章表-关系表-标签表)

增加关系:同版主任命型。

删除关系:同版主任命型。

3,明细帐型

特点:关系表可以有重复纪录,关系表一般有时间字段,有主键,可能还有文字型的字段用来说明每次发生关系的原因(消费)。

界面特点:显示关系表,用radio或下拉设置单选关系。

例如:现金消费明细帐或订单(用户表-订单表-消费原因表),用户可能多次在同一事情上重复消费。积分变化纪录也属于这类。

增加关系:不管有没有组合纪录,insert之,纪录时间。

删除关系:根据关系表PK删除。

4,评论回复型

特点:同明细帐型关系表一般有时间字段,有主键,区别是重点在文字型的字段用来说明每次发生关系的内容(评论回复)。

界面特点:回复文本框。

例如:论坛回复(用户表-回复表-帖子表),用户可能多次在不同帖子上评论回复费。

增加关系:不管有没有组合纪录,insert之,纪录时间和文字。

删除关系:根据关系表(回复表)PK删除。

5,站内短信型

特点:主副表是同一个,关系表一般有时间字段,有主键,重点在关系表文字型的字段用来说明每次发生关系的内容(消息)或者其他标记位来表示文字已读状态时间等。

界面特点:回复文本框。

例如:站内短信(用户表-短信表-用户表),用户可能给用户群发或者单发,有标记位来表示文字已读状态时间等。

增加关系:不管有没有组合纪录,insert之,纪录时间和文字。

删除关系:根据关系表(回复表)PK删除。

6,用户好友型

特点:主副表是同一个,同集合分组型,关系表两外键组合无重复纪录,关系表一般不需要时间字段和主键。

界面特点:同集合分组型,显示主表,用搜索代替简单的checkbox或多选select,或者一条一条的添加。

例如:下载站点的文件,(文件表-关系表-文件表)可以被软件工具打开,软件工具本身也是一种文件,可以被下载。用户的好友,也是用户(用户表-好友关系表-用户表)

增加关系:同版主任命型。

删除关系:同版主任命型

Hibernate <>的一对多和多对一 *** 作真的很方便 如果系统采用Hibernate作为持久层 完全可以把对应的一对多和多对一逻辑关系放在Hibernate里面控制 减少数据库的负担 而且也更清晰

多对一和一对多概念

其实这个概念上来说很简单 比如一个客户可以有多个订单 多个订单属于同一个客户 就是最基本的一对多 和多对一 数据库使用中 感觉多对一和一对多算是比较常见的逻辑关系了

我曾经做过一些数据库 比如某些 *** 部门的 其表单很设计的很简单粗糙 甚至连主键都没有 完全靠在事务层补全这些关系 其实通过Hibernate持久层来实现逻辑关系也是很不错的方法 下面的例子 就是数据库逻辑上基本没有定义 主要放在持久层里面 这个也主要是我对数据库 *** 作属于半通水的原因

数据库层

这里面有两个表单 一个CUSTOMER 客户表单 一个是ORDERS 订单表单 生成客户表单 这个是在SQLServer里面做的 其实其他都一样 因为逻辑关系在Hibernate上面 id是主键非空 其他可以为空

CREATETABLE[dbo] [CUSTOMER](

[id][numeric]( )NOTNULL

[name][varchar]( )NULL

[age][int]NULL

CONSTRAINT[PK_CUSTOMER]PRIMARYKEY)

订单表单

id为主键非空 CUSTOMER_id是对应客户主键 也非空 这里不做外键设置

CREATETABLE[dbo] [ORDERS](

[id][numeric]( )NULLPRIMARYKEY

[CUSTOMER_id][numeric]( )NOTNULL

[ORDER_NUMBER][varchar]( )NULL

[PRICE][numeric]( )NULL

)

Hibernate设定

HIbernate里面 一对多的对象体现 是客户有一个集合set set里面放著对应订单 而多对一体现 是订单里面有一个CUSTOMER对象 表明该订单所属的客户 其中 CUSTOMER类为

publicclassCustomerimplementsjava io Serializable{

privateLongid

privateStringname

privateIntegerage

privateSetrderses=newHashSet()

后面的getXXX和setXXX方法就省去了 同样订单类就是

publicclassOrdersimplementsjava io Serializable{

privateLongid

privateCustomercustomer

privateStringorderNumber

privateDoubleprice

而对应hbm文档 就是map文档如下

CUSTOMER hbm xml

<!DOCTYPEhibernate mappingPUBLIC //Hibernate/HibernateMappingDTD //EN

mapping dtd >

<!

MappingfileautogeneratedbyMyEclipsePersistenceTools

>

<hibernate mapping>

<classnameclassname= onetomany Customer table= CUSTOMER schema= dbo catalog= DBTEST >

<idnameidname= id type= java lang Long >

<columnnamecolumnname= id precision= scale= />

<generatorclassgeneratorclass= increment />

</id>

<propertynamepropertyname= name type= java lang String >

<columnnamecolumnname= name length= />

</property>

<propertynamepropertyname= age type= java lang Integer >

<columnnamecolumnname= age />

</property>

<setnamesetname= orderses inverse= true lazy= true cascade= all >

<key>

<columnnamecolumnname= CUSTOMER_id precision= scale= not null= true />

</key>

<one to manyclassone to manyclass= onetomany Orders />

</set>

</class>

</hibernate mapping>

这个里面 其他都很简答了 其中<generatorclass= increment />表示主键值自动增加 这个主要针对字符串对应的 主要体现多对以的是

<setnamesetname= orderses inverse= true lazy= true cascade= all >

<key>

<columnnamecolumnname= CUSTOMER_id precision= scale= not null= true />

</key>

<one to manyclassone to manyclass= onetomany Orders />

</set>

其中 set表示 对应集合 fetch和lazy主要是用来级联查询的 而cascade和inverse主要是用来级联插入和修改的 这几个主要包括对集合的控制 <one to manyclass= onetomany Orders />表示对应类 即set里面包含的类 而key主要是用于确定set里面对应表单列

ORDERS的hbm

<?xmlversionxmlversion= encoding= utf ?>

<!DOCTYPEhibernate mappingPUBLIC //Hibernate/HibernateMappingDTD //EN

mapping dtd >

<!

MappingfileautogeneratedbyMyEclipsePersistenceTools

>

<hibernate mapping>

<classcatalogclasscatalog= DBTEST name= onetomany Orders schema= dbo table= ORDERS >

<idnameidname= id type= java lang Long >

<columnnamecolumnname= id precision= scale= />

<generatorclassgeneratorclass= increment />

</id>

<many to oneclas *** any to oneclass= onetomany Customer fetch= select name= customer >

<columnnamecolumnname= CUSTOMER_id precision= scale= />

</many to one>

<propertygeneratedpropertygenerated= never lazy= false name= orderNumber type= java lang String >

<columnlengthcolumnlength= name= ORDER_NUMBER />

</property>

<propertygeneratedpropertygenerated= never lazy= false name= price type= java lang Double >

<columnnamecolumnname= PRICE precision= scale= />

</property>

</class>

</hibernate mapping>

<many to oneclas *** any to oneclass= onetomany Customer fetch= select name= customer >

<columnnamecolumnname= CUSTOMER_id precision= scale= />

</many to one>

表示CUSTOMER熟悉对应的类 和其作为key的列名 上面这些都可以在MyEclipse里面自动生成 另外注意的一点是 在生成的DAO里面 涉及表单 *** 作的save()和delete()方法 必须要事件提交 数据库才有反映 可以就该Hibernate xml 或者用下面这样代码来实现

Sessionse=getSession()

Transactiontx=se beginTransaction()

se delete(persistentInstance)

//se save(instance)

mit()

验证效果

新增用户

如果新增一个用户 该用户里面包含有两个表单 那么 由于持久层已经实现了逻辑关系 只要用户类里面的set包含了表单 则表单可以自动增加 实现代码

CustomerDAOcd=newCustomerDAO()

Customerxd=newCustomer( 王小虎 null)

Ordersord =newOrders()

ord setCustomer(xd)

ord setOrderNumber( 王小虎的买单 )

Ordersord =newOrders()

ord setCustomer(xd)

ord setOrderNumber( 王小虎的买单 )

Setrderses=newHashSet()

orderses add(ord )

orderses add(ord )

xd setOrderses(orderses)

cd save(xd)

代码里面 加入一个王小虎用户 两个订单 通过setOrderses加入 只使用cd save这一个对持久层 *** 作 完成后查询

王小虎

=================================

王小虎的买单

王小虎的买单

显示 CUSTOMER里面加入了王小虎 ORDERS里面也加入他的订单

删除 *** 作

List<Customer>csList=cd findByProperty( name 王小虎 )

for(Customercs:csList){

cd delete(cs)

}

这个很简单了 通过其中findByProperty( name 王小虎 )对应SQL为deletefromtableCUSTOMERwherename= 王小虎 删除了王小虎 而ORDERS里面 王小虎对应的表单也同时被删除

小小总结

lishixinzhi/Article/program/Java/ky/201311/28543

一对多,其实并不一定要做约束,我更倾向于业务上的一对多。\x0d\x0a一对多的基本概念是。子表依赖于主表的主键。每条主表的记录,会对应子表上一到多条记录。\x0d\x0a\x0d\x0a主键是基于本表字段的约束,是唯一约束。\x0d\x0a外键是子表基于主表主键的约束,不是唯一约束,但要求必须主表有相应的记录,子表才可以插入数据。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9364329.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存