热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Yii良好的架构(schema)设计指南

首先Yii应用程序广泛使用了CActiveRecord,设计的考虑主要围绕优化使用而不是组成复杂的SQL语句.实际上大多的设计是使用友好的SQL模式来解决实践中的问题.

首先 Yii 应用程序广泛使用了 CActiveRecord, 设计的考虑主要围绕优化使用而不是组成复杂的 SQL 语句. 实际上大多的设计是使用友好的 SQL 模式来解决实践中的问题.

最常用的方式是创建易于被人阅读和理解的代码,例如使用命名来传达意思,但是这很难做到.

特别当你在论坛或 '#yii' 频道寻求帮助时,使用奇怪的名字意味着你会有一堆麻烦:解释代码是干什么的。你的问题有时就不会得到有效解决.

一堆一致性问题.

然而这些只是准测而不是规则,你的代码不遵循这些准则也照样会工作,但是如果你遵循这些准则你的代码将更加简单.

使用单数而不是使用复数来命名表名


我们认为 SQL 表 包含很多记录,一个模型(model) 只是其中的一个,在任何地方使用$model = new Comments()来表示再次定义关系时感觉非常奇怪.

命名您的表名为comment而不是comments,invoice而不是invoices等等。对于的模型(model)类名也是一样(Comment,Invoice等等).

如果你不可以改变数据库的模式,但至少在适当的情况下你可以改变 Yii 模型类(model class)的名称,在这种不匹配的情况下你应该在代码中添加一个额外的注释//COMMENT来提醒用户.

不要在字段名前面加上表名


下面的做法是在传统 SQL 设计模式上非常常见的,但是它在于 ActiveRecord 结合时时冗长复杂的。在category表中:

1
2
3
4
5
6
7
8
9
10
11
-- 不可取                           -- 可取
create table category (            create table category(
    category_id    INTEGER ...,        id    INTEGER ...,
    category_name  VARCHAR ...,        name  VARCHAR ...,
    category_value INTEGER             value INTEGER
);                                 );
       
// 不友好的                          // 友好的
$model->category_id               $model->id
$model->category_name             $model->name
$model->category_value            $model->value

虽然使用这种long方式生称的 SQL 语句容易理解一些,但是在 ActiveRecord 中使用就不太方便了.

不要在模型类(model class)的类名中出现表名的前缀

Yii 支持表前缀,表前缀被用在 所有 应用放到共享的主机并且共享一个数据库的环境中. 你的博客表前缀为blog_,计时应用的表前缀为time_等等. 它们存在于同一个数据库中而互相不起冲突.

前缀tbl_在很多教程和例子中经常看到。

但是类不需要包含这些前缀,因为没有必要避免冲突:你的博客应用和你的计时应用时两个不同的应用.

1
2
classTblCommentextendsCActiveRecord {      // 不可取
classCommentextendsCActiveRecord {         // 可取

在代码中看到无处不见的前缀使人们非常反感.

确保每个表的主键为id


大多数表都有一个唯一主机,命名主键为id(而不是commentid、postid) 会使你的工作更加顺手.

虽然无论你是否访问数据库 Yii 都可以通过读取数据结构来得到它的主键,但是系统的其他部分可能不会这样做,并且它们依赖的主键为id.

例子:CArrayDataProvider 默认的主键为id, 虽然你可以重写它的属性 'keyField', 但是把这放到第一位是很不方便的.

显而易见,当使用复合主键时这将不能工作,但是这毕竟是少数.

避免特殊意义的主键名


一个经典的设计错误是创建的表的主键有实际意义. 在下面的列子中 用户(user)表使用的用户名(name)作为主键:

1
2
3
4
5
6
-- 不要这么做!
CREATE TABLE user (
    name   VARCHAR(16) PRIMARY KEY,  -- bad idea
    email  VARCHAR...
    ...
)

这样做引发了两个问题:This presents two difficulties:

  1. 当在其他地方 引用 时,它的效率大大降低,因为它包含16个字符而不是4个字节的整数.当大量的 引用 时性能大大降低。

  2. 当系统中存在外键约束时用户想 修改用户名 是很困难的:表中的字段和引用都必须在同一时间改变,这样做的代价时昂贵的。

最好的解决办法时创建一个整型字段作为主键,并设置name字段为 unique:

1
2
3
4
5
6
7
-- much better
CREATE TABLE user (
   id     INTEGER PRIMARY KEY AUTO_INCREMENT,
   name   VARCHAR(32) NOT NULL UNIQUE,
   email  ...
   ...
);

这种方式在用户更新用户名时只修改了一条记录.

确认在数据库结构中定义的外键关系


大多数的数据支持定义表之间的关系,一个表中的字段指向另一个表的主键。这些外键帮助保证了数据的完整性当有记录执行某条记录时不允许你删除它.

MySQL的InnoDB 强制使用外键约束,而 MyISAM 允许你 定义 它们,但不会 强制 使用. Yii 知道怎么处理这些关系,并且可以使用 Gii或Giix 自动生成关系.

抛开 Yii ,外键是维护数据库完整性的重要部分,在网络上有许多学习它的教程.

使用 "id" 作为外键字段的结尾


通过以上的说明,如果你有一个字段指向一个用户(user),命名这个字段为userid而不是user. 原因是你肯定要为表中的每一个外键定义一个 关系.

在 Yii、类变量、数据字段、虚拟属性、关系共享一个命名空间(namespace), 所以不可能通过$model->user的方式来 同时 访问表的外键 关系.

通过外键userid,$model->user形式的 BELONGS_TO 关系可以轻松自然的使用:

1
2
3
4
5
6
7
8
classPostextendsCActiveRecord {
       
   publicfunctionrelations()
   {
       returnarray(
          'user'=>array(self::BELONGS_TO,'User','userid')
       );
   }

注意: 有很多人喜欢用Id或_id来代替id.这只是个人爱好问题,意义是一样的.

在关系的名称(name)上体现它们的单数或复数的特性


继续我们的主题一致性和代码易于阅读,关系应当在名称上体现它们代表的为单数还是复数.

  • HAS_ONE- 返回一个模型(model): 单数

  • BELONGS_TO- 返回一个模型(model): 单数

  • HAS_MANY- 返回一个由多个模型(model)组成的数组: 复数

  • MANY_MANY- 返回一个由多个模型(model)组成的数组: 复数

注意: 对于返回一个数组的关系,它们可能只包含一个模型,但事实上它们是通过复数名称方式认证来的 数组

你只需要通过看关系的名称就会知道它返回的是一个数组还是一个模型:

1
2
3
4
$model->post
$model->comments
$model->author
$model->members

如果你必须通过查看代码才会知道,那这将会让你的代码更加难以阅读和维护.


推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 在数据分析工作中,我们通常会遇到这样的问题,一个业务部门由若干业务组构成,需要筛选出每个业务组里业绩前N名的业务员。这其实是一个分组排序的 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了Python版Protobuf的安装和使用方法,包括版本选择、编译配置、示例代码等内容。通过学习本教程,您将了解如何在Python中使用Protobuf进行数据序列化和反序列化操作,以及相关的注意事项和技巧。 ... [详细]
author-avatar
书友37715123
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有