发表于: 2017-07-24 16:13:36

2 984


今天完成的:

设计项目DB,通过复盘评审

收获:

1.子查询和表关联查询的效率问题

   ①表关联的效率要高于子查询,因为子查询走的是笛卡尔积

   ②表关联可能有多条记录,子查询只有一条记录,如果需要唯一的列,最好走子查询

select里子查询一个字段的话没问题,但如果子查询中有多个字段,会后成一种类似嵌套循环的查询,外表查询一次,子表就要进行多次查询。另外还有一种查询,使用in关键字,in后面的字段如果没建索引,会需要全表查询。因此最好使用联表查询以提高性能。

2.单表查询和表关联查询的效率问题

【强制】 超过三个表禁止 join。需要 join 的字段,数据类型必须绝对一致;多表关联查询 时,保证被关联的字段需要有索引。 说明:即使双表 join 也要注意表索引、SQL 性能----alibaba规约

单表查询相对于关联查询的优点:

大多数情况下可以使用关联查询提高效率,但最好在关联关键字段加索引优化。如果表连接数超过3张就要考虑单表了。萝卜多项目里数据量太少了,甚至加不加索引都不会影响效率,所以没什么影响。

3.多对多表关系设计方案

复盘项目中公司和标签是多对多关系。

①建立第三个表--公司/标签关系表,用一张关系表连接两张信息表。

关系表中保存公司id和标签id。便于表的维护与重复利用。类似:

由于标签tag和公司的变动较多,这部分使用外键来约束数据的完整性。外键是数据库一级的一个完整性约束,就是数据库基础理论书中所说的“参照完整性”的数据库实现方式。  

在关系表中建立公司表和tag表的外键,并建立索引。

好处:1.当公司或tag的id变动时,关系表自动调整关系

            2.当公司或tag被删除时,关系表同步删除关系。

问题:复盘项目可以使用一堆外键,级联删除或更新很方便。但外键的约束性太强,对性能也有影响。而且一般公司在删除数据时并不是真正的删除数据,而是设置该数据失效。

4.索引的建立原则

1、表的主键、外键必须有索引; 
2、数据量超过300的表应该有索引;
3、经常与其他表进行连接的表,在连接字段上应该建立索引
4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
5、索引应该建在选择性高的字段上;
6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;
7、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替: A、正确选择复合索引中的主列字段,一般是选择性较好的字段; B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引; C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引; D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段; E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
8、频繁进行数据操作的表,不要建立太多的索引;
9、删除无用的索引,避免对执行计划造成负面影响; 以上是一些普遍的建立索引时的判断依据。一言以蔽之,索引的建立必须慎重,对每个索引的必要性都应该经过仔细分析,要有建立的依据。因为太多的索引与不充分、不正确的索引对性能都毫无益处:在表上建立的每个索引都会增加存储开销索引对于插入、删除、更新操作也会增加处理上的开销。另外,过多的复合索引,在有单字段索引的情况下,一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大

感觉项目里数据量太低,完全不需要建立索引。但根据上面的原则,可以在连接字段上建立索引,连接字段一方为主键,另一方加普通索引

5.DB设计,还需改动

公司表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
公司idco_idbigInt     —主键非空无需索引,主键自带索引
公司名称co_namevarchar50非空
公司标语co_sloganvarchar50非空
公司人数co_numberint10非空
公司介绍co_descriptionvarchar255非空
公司logoco_logovarchar120非空
省级所属地区1co_areaProvincevarchar10非空
地级所属地区2co_areaCityvarchar10非空
所属行业co_professionvarchar20非空
融资规模co_financingvarchar10非空
认证状态co_accreditationtinyInt     —非空mysql使用tinyint替代boolean,1表示true,0为false
冻结状态co_frozenStatustinyInt     —非空mysql使用tinyint替代boolean,1表示true,0为false
手机号co_telephoneint20非空
公司邮箱co_emailvarchar50非空
公司详细地址co_addressvarchar50非空
公司地图co_mapvarchar120非空
创建时间co_createAtbigInt     —非空
更新时间co_updateAtbigInt     —非空
职位表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
职位idposition_idbigint     —主键非空
公司idposition_coIdbigint     —索引非空关联公司表,需要根据职位查询公司或反过来查询
职业idposition_industryIdbigInt     —索引非空
职位名称position_namevarchar20非空
学历要求position_eduLimitvarchar20非空
工作经验position_experiencevarchar20非空
薪资待遇position_salaryvarchar20非空
岗位职责position_dutyvarchar120非空
必备条件position_conditionvarchar120非空
公司福利position_welfarevarchar120非空
是否推荐position_recommendtinyInt     —非空mysql使用tinyint替代boolean,1表示true,0为false
职业类别position_category int     —非空
创建时间pository_createAtbigInt     —非空
更新时间pository_updateAtbigInt     —非空
职位类别表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
职业idindustry_idbigint     —主键非空数据量过小,不建索引
职业类别industry_itemvarchar20非空
创建时间industry_createAtbigInt     —非空
更新时间industry_updateAtbigInt     —非空
产品表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
产品idproduct_idbigInt     —主键非空
公司idproduct_coIdbigInt     —索引非空关联公司表,仅需要根据公司查产品
产品名称product_namevarchar20非空
产品标语product_sloganvarchar50非空
产品logoproduct_logovarchar120非空
产品简介product_descriptionvarchar255非空
创建时间product_createAtbigInt     —非空
更新时间product_updateAtbigInt     —非空
标签表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
标签idtag_idbigInt     —主键非空数据量过小,不建索引
标签内容tag_contentvarchar20非空
公司/标签关系表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
关系表id relation_idbigInt     —主键非空数据量过小,不建索引
公司id relation_coIdbigInt     —外键非空指向company_id
标签id relation_tagIdbigInt     —外键非空指向tag_id
article表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
文章idarticle_idbigInt     —主键非空
文章标题article_titlevarchar20非空
文章创建者article_buildervarchar20非空
文章状态article_statustinyInt     —非空
文章类型article_typevarchar20非空
文章图片article_picturevarchar120非空
跳转链接article_urlvarchar120非空
创建时间article_createAtbigInt     —非空
修改时间article_updateAtbigInt     —非空
后台账户表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
账户idaccount_idbigInt     —主键非空
账户名account_namevarchar20非空
账户密码account_passwordvarchar20非空
账户角色account_roleint     —非空
创建时间account_createAtbigInt     —非空
更新时间account_updateAtbigInt     —非空
***********************************************************************************************************************************************************************
角色表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
角色idrole_idbigInt     —主键
角色名role_namevarchar20
角色权限role_authorityint     —
创建时间role_createAtbigInt     —
更新时间role_updateAtbigInt     —
角色权限主表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
主权限idauthority_idbigInt     —主键
主权限名authority_namevarchar20
创建时间authority_createAtbigInt     —
更新时间authority_updateAtbigInt     —
角色权限子表
描述DB字段名DB类型DB长度java字段名java类型约束索引非空默认值注释
子权限idauthority2_idbigInt     —主键
子权限名authority2_namevarchar20
创建时间authority2_createAtbigInt     —

遇到的问题:

1.在考虑要不要使用公司的DAL,优点是提供了用hibernate封装起来的大量api,不需要自己写太多sql语句,类似mybatis提供的mybatis gererator,代码生成功能很强大。但离开公司之后就永远用不到了,如果是手写mybatis的话,大量接口会很浪费时间,而且会用到联表查询和动态查询,sql较为复杂。而且不用dal的话,似乎后面自动生成的比如rmi全部都要自己写。还需考虑。

2.没有前端的话怎么约定接口?不能一直等他吧

明天的计划:

读原型,定义接口,确定原型中元素的关系


返回列表 返回列表
评论

    分享到