`
helpbs
  • 浏览: 1171019 次
文章分类
社区版块
存档分类
最新评论

第二天--设置一个数据模型

 
阅读更多

第二天--设置一个数据模型

Symfony回顾

在这份长长的但是却十分有趣的指南的第一天内容中,我们了解了如何安装Symfony框架,设置一个新程序以及开发环境,并且使用了源码版本控制安全的存放源码。顺便说一句,在第一天所生成的程序源码可以在askeet的源码仓库得到:
http://svn.askeet.com/

第二天的目标是从功能的角度来定义最终的结果应是什么样子的,设计数据模型以及编码。这包括生成一个对象关系映射,并且使用他们来创建,取出以及更新程序框架数据中的记录。

这确实是相当多的内容。让我们开始吧。

揭开程序面纱

我们希望了解什么呢?这是一个有趣的问题。对于这个问题有许多有趣的答案,如:

如何带来我的blog的流量?
什么是最好的web程序框架?

所有这些问题不只有一个答案,而最好的答案在于我们的观点。实际上,只有一个答案的问题通常是最无趣的,但是在web上要解决的只有一个。这不公平。

来askeet 吧。这是一个帮助人们查找问题答案的网站。谁会回答这些问题呢?所有人。而每一个人都可以评价其他人的答案,所以最受欢迎的答案会更可见。随着问题数量的 增加,使用类与子类的方式来组织就变得不可行了,所以问题的提出者就可以使用他希望的任何单词来进行标签化。当然,标签的流行程序是由一个标签集合来表示 的。如果一个希望跟随一个答案来找到一个问题,他可以订阅这个问题RSS反馈。所有这些功能都必须是优雅和轻量级的,从而所有这些交互不必需要一个 AJAX类型式的新页。事实上,需要一个后端来组织问题与答案,或是手工添加一个管理员认为有意义的问题。

也许你会问:我还没有在web 上见到过这样的网站吗?当然,如果你确实是这样,那么我们正好,但是如果你见过如faqts,eHow,Ask leeves或是相似的内容,没有聚合答案,没有AJAX,没有RSS,没有标签,那么这些与我们的网站并不一样。我们这里在讨论一个web2.0的程 序。

askeet的目录不只是一个网站,他是一个程序,任何人都可以下载,在家里或是在公司的网站上安全,修改或是添加新的特性。源码将 会以开放源码许可证的形式发布。你的HR经理正是寻找一个知识管理系统?你希望记录你学到的关于修理汽车的技艺?你并不希望为你的网站开发一个FAQ部 分?不必再寻找了,因为有askeet。当然,他将会存在,那是我们的圣诞礼物。

从哪里开始?

那么你如何开始一个Symfony程序呢?这取决于你自己。如果你是一个XP能手,你可以写一个故事,计划一个游戏,并且找到一个合作者来进行结对编程,或者如果你是一个UML迷,你可以编写一个详细的网站需要说明,附带一个所有对象,状态以及交互的框架。

但 是这个教程并不是关于通常的程序开发的,所以我们从一个基本的关系数据模型开始,并且一步一步的添加工作特性。我们所需要的只是一个在每天结束时可用的程 序,而不是一个不会输出任何内容的巨大的程序代码。在理想的情况下,我们应为我们添加的每一个新特性编写单元测试,但是实际上我们并没有时间来这样做。如 果要进行单元测试,则需要一天的时间。所以我们还是继续阅读吧。

对于这个工程,我们将使用一个带有InonoDB表类型的MySQL数据 库,这样可以充发利用集中控制与事务支持。在前面的步骤中,我们将会使用一个SQLite数据库,来避免设计一个实际的数据库。这需要 databases.yml文件中时行一些小的修改,我们会将这些工作作为探索的练习留给你。

数据模型

关系模型

很明显,需要有一个'question'与一个'answer'数据表。我们需要一个'user'数据表,并且我们需要一个'interest'数据表来存储对一个问题感兴趣的用户,以及在一个'relevancy'数据表中记录一个用户对于一个答案所做出的中肯的评价。

用 户需要进行确认来添加一个问题,评价答案,或者是删除对于一个问题的兴趣。用户添加答案并不需要进行确认,但是一个答案总是会链接到一个用户,这样给出最 受欢迎答案的用户可以进行区分。没有经过确认而发布的答案将会显示为一个通常用户的贡献,称之为'Anonymous Coward'。很容易理解整个关系数据表:
ERD

注意,对于每一个数据表,我们都声明了一个created_at域。Symfony会识别这样的域,并且在记录创建时会将其设置当前的系统时间。这也updated_at域相似:当记录更新时会将其设置为系统时间。

schema.xml

关系模型已经转换为一个Symfony可以理解的配置文件。这也就是schema.xml或是schema.yml文件的目的,这个文件位于askeet/config/目录下。Symfony支持XML或是YAML的格式语法。

有两种方法来编写这个文件:手写,这也我们喜欢的方法,或者由一个已存在的数据库生成。让我们看一下第一种解决方法。

首先,我们需要移除默认安装的YAML样式文件:

$ svn delete config/schema.yml

schema.yml 文件的语法是相当简单:他是一个XML文件,在其中<table>标记包含<column>,<foreign- key>以及<index>标记。一旦我们编写了一个,我们就可以编写所有的。下面是我们在前面所描述的关系模型的对应 schema.yml文件:

<?xml version="1.0" encoding="UTF-8"?>
<database name="propel" defaultIdMethod="native" noxsd="true">
<table name="ask_question" phpName="Question">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="user_id" type="integer" />
<foreign-key foreignTable="ask_user">
<reference local="user_id" foreign="id"/>
</foreign-key>
<column name="title" type="longvarchar" />
<column name="body" type="longvarchar" />
<column name="created_at" type="timestamp" />
<column name="updated_at" type="timestamp" />
</table>

<table name="ask_answer" phpName="Answer">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="question_id" type="integer" />
<foreign-key foreignTable="ask_question">
<reference local="question_id" foreign="id"/>
</foreign-key>
<column name="user_id" type="integer" />
<foreign-key foreignTable="ask_user">
<reference local="user_id" foreign="id"/>
</foreign-key>
<column name="body" type="longvarchar" />
<column name="created_at" type="timestamp" />
</table>

<table name="ask_user" phpName="User">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="nickname" type="varchar" size="50" />
<column name="first_name" type="varchar" size="100" />
<column name="last_name" type="varchar" size="100" />
<column name="created_at" type="timestamp" />
</table>

<table name="ask_interest" phpName="Interest">
<column name="question_id" type="integer" primaryKey="true" />
<foreign-key foreignTable="ask_question">
<reference local="question_id" foreign="id"/>
</foreign-key>
<column name="user_id" type="integer" primaryKey="true" />
<foreign-key foreignTable="ask_user">
<reference local="user_id" foreign="id"/>
</foreign-key>
<column name="created_at" type="timestamp" />
</table>

<table name="ask_relevancy" phpName="Relevancy">
<column name="answer_id" type="integer" primaryKey="true" />
<foreign-key foreignTable="ask_answer">
<reference local="answer_id" foreign="id"/>
</foreign-key>
<column name="user_id" type="integer" primaryKey="true" />
<foreign-key foreignTable="ask_user">
<reference local="user_id" foreign="id"/>
</foreign-key>
<column name="score" type="integer" />
<column name="created_at" type="timestamp" />
</table>

</database>

注意,在这个文件中将数据名字设置为propel,而无论实际的数据库名字是什么。这个是一个用来连接Propel层与Symfony框架的参数。数据库的实际名字将会在databases.yml配置文件中定义。

如 果我们有一个数据库,我们还有另外的一个方法来创建schema.yml文件。也就是说,如果我们熟悉一个图形化的数据库设计工具,我们会更喜欢由生成的 MySQL数据库来构建schema。在我们做这项工作之前,我们只需要编辑位于askeet/config/目录下的propel.ini文件,输入到 我们数据库的连接字符串:

propel.database.url = mysql://username:password@localhost/databasename

这里的username,password,localhost以及databasename是我们数据库的实际连接设置。现在我们可以调用propel-build-schema命令(在askeet/目录下)来由数据库生成schema.xml:

$ symfony propel-build-schema

除了创建一个schema.xml文件,我们也可以使用YAML的语法格式来创建一个schema.yml文件:

[yml] propel: _attributes: { noXsd: false, defaultIdMethod: none, package: lib.model }

ask_question:
_attributes: { phpName: Question, idMethod: native }
id: { type: integer, required: true, primaryKey: true, autoIncrement: true }
user_id: { type: integer, foreignTable: ask_user, foreignReference: id }
title: { type: longvarchar }
body: { type: longvarchar }
created_at: ~
updated_at: ~

ask_answer:
_attributes: { phpName: Answer, idMethod: native }
id: { type: integer, required: true, primaryKey: true, autoIncrement: true }
question_id: { type: integer, foreignTable: ask_question, foreignReference: id }
user_id: { type: integer, foreignTable: ask_user, foreignReference: id }
body: { type: longvarchar }
created_at: ~

ask_user:
_attributes: { phpName: User, idMethod: native }
id: { type: integer, required: true, primaryKey: true, autoIncrement: true }
nickname: { type: varchar(50), required: true, index: true }
first_name: varchar(100)
last_name: varchar(100)
created_at: ~

ask_interest:
_attributes: { phpName: Interest, idMethod: native }
question_id: { type: integer, foreignTable: ask_question, foreignReference: id }
user_id: { type: integer, foreignTable: ask_user, foreignReference: id }
created_at: ~

ask_relevancy:
_attributes: { phpName: Relevancy, idMethod: native }
answer_id: { type: integer, foreignTable: ask_answer, foreignReference: id }
user_id: { type: integer, foreignTable: ask_user, foreignReference: id }
score: { type: integer }
created_at: ~

构建对象模型

要使用InonoDB引擎,必须在askeet/config/目录下的propel.ini文件中加入下面一行:

propel.mysql.tableType = InnoDB

一旦构建了schema.xml文件,我们可以基于这个关系模型生成一个对象模型。在Symfony中,对像关系映射是由Propel来处理的,但是封装到Symfony命令中:

$ symfony propel-build-model

这 个命令生成(我们需要在askeet工程的根目录下调用)与schema中定义的表相对应的类,并带有标准的访问方法(->get()与-> set()方法)。我们可以在askeet/lib/model/om/目录下查看这些生成的代码。如果我们想知道对于每一个数据表为什么需要两个类,我 们可以查看Symfony一书的model一章。每次我们执行build-model时,这些类就会被覆盖,而这在这个工程中是经常发生的。所以如果我们 需要在模型对象添加方法,我们必须修改位于askeet/lib/model/目录下的类--他们由/om继承来的。

数据库

连接

现在数据库拥有一个数据库模型,现在我们要将工程连接到MySQL数据库。首先,我们需要在MySQL中创建一个数据库:

$ mysqladmin -u youruser -p create askeet

现 在打开askeet/config/databases.yml配置文件。如果这是我们第一次使用Symfony,我们就会发现Symfony的配置文件 是使用YAML语法编写的。这个语法非常简单,但是却有一个约定:不可以使用tab,只可以使用空格。我们知道了这些,我们就可以编写文件,在all:类 别下添加到我们数据库的连接设置:
all:
propel:
class: sfPropelDatabase
param:
phptype: mysql
host: localhost
database: askeet
username: youruser
password: yourpasswd

如果我们希望了解更多的关于Symfony配置与YAML文件的内容,我们可以查看Symfony一书实际配置一章。

构建

如果我们没有手工编写schema.yml文件,而在我们的数据库中已有相应的数据表,我们可以跳过这一部分。

对于键盘迷的我们来说,这里是一个叫人惊奇的地方:我们并不需要在MySQL数据库创建数据表与相应的数据列。我们已经在schema.xml中完成了工作,所以Symfony会为我们创建所有的SQL构建语句:

$ symfony propel-build-sql

这个命令会在askeet/data/sql/目录下创建一个lib.model.schema.sql文件。在MySQL中将其作为一条SQL命令:

$ mysql -u youruser -p askeet < data/sql/lib.model.schema.sql

相应的,我们也可以使用propel-insert-sql任务:

$ symfony propel-insert-sql

通过CRUD测试数据访问

现在可以测试这些工作是否可以正常工作了。到现在为止,我们的浏览器还没有任何作用,而我们还在希望创建一个web程序。所以让我们来创建一个基本的Symfony模板与动作集合来处理'question'数据表的数据。这可以允许我们创建一些问题一些问题并进行显示。

在askeet/目录下,输入下面命令:

$ symfony propel-generate-crud frontend question Question

这 会在frontend程序中为一个question模块生成一个框架,这个框架基于Question Propel对象模型,并且具有基本的创建,取出,更新与删除动作。不要感到迷惑:一个框架并不是一个完成的程序,而只是一个基本结构,在其上我们可以开 发新的特性,添加业务规则,自定义显示等。

由一个CRUD生成器创建的动作列表如下:

名字 描述
list 显示一个数据表的所有记录
index 转向到list
show 显示一个指定记录的所有数据域
edit 显示一个表单来创建一个新的记录或是编辑一个已存在的记录
update 通过在请求中指定的参数来修改一个记录,然后转向到show
delete 从数据表中删除一个指定的记录

我们可以在Symfony一书的框架一节了解到更多的关于生成的动作的内容。

无论何时当我们添加一个需要自动装入的新类时,不要忘记清除配置缓存(来重新装入自动载入缓存):
$ symfony cc frontend config

现在我们可以通过下面的URL来进行在线测试了:
http://askeet/question

现在我们可以执行一些操作。添加一些问题,编辑他们,删除他们。如果可以正常工作,这就意味着对象模型是正确的,也就是说到数据库的连接是正确的,数据库的关系模型到数据库的对象模型是正确的。这就是一个良好的功能测试。

明天见

我们并没有编写一行PHP代码,而我们已经有了一个可用的基本程序。这对于第二天并不坏。明天,我们将会编写一些代码来创建一个来显示问题列表的欢迎首页。我们也可以使用一个处理操作来向我们的数据库添加数据,并且学习如何扩展模块。

原文地址 http://www.symfony-project.com
分享到:
评论

相关推荐

    基于VMD-Attention-LSTM的时间序列预测模型python源码+模型+数据集+详细代码注释+报告.zip

    基于VMD-Attention-LSTM的时间序列预测模型(代码仅使用了一个较小数据集的训练及预测,内含使用使用逻辑,适合初学者观看,模型结构是可行的,有能力的请尝试使用更大的数据集训练) 根据LSTM层的需求,输入的数据...

    天气预报 :天气数据集爬取 + 可视化 + 13种模型预测

    本文就是利用前几天学到的爬虫知识使用 Python 爬取天气数据集,并做的一期讨论日期与最低气温能是否是最高气温的影响因素,进而判断能否精确预测第二天的天气情况。 由于本文开始写作与5月9日,当天想预测第二天也...

    数据库课程设计--图书管理系统.doc

    软件工程与数据库 课程设计 任务书 学院名称: 数学与计算机学院 课程代码:_6014419_ 专 业: 年 级: 一、设计题目 图书管理系统 二、主要内容 一个简单的图书管理系统包括图书馆内书籍的信息、学校在校学生的信息...

    R语言结课分析报告: 最高和最低气温估计

    此数据中有两个输出(即第二天最高和最低空气温度)。Hindcast 验证于 2015 年至 2017 年期间进行。 (二)变量说明 1. 对变量进行说明 Present_Tmax - 当日(°C)最高气温在0至21小时之间:20至37.64度。Present_...

    北京中科信软数据仓库培训

    第二天上午 元数据简介 数据仓库元数据定义、类型以及在数据仓库环境中的角色 数据仓库元数据的类型 开发元数据的策略等 中间休息十分钟 数据仓库基本概念介绍 数据仓库的基本元素 数据仓库的基本形式 数据仓库...

    体验了刚发布的 GPT-4 之后,聊聊 GPT 为何成为了火遍全网的 AI 模型

    我从 ChatGPT Plus 发布第一天就开始重度使用,刚刚和新发布的 GPT-4 进行了 20 多轮对话,来简单介绍下这几个模型背后的技术,并且分享下感受。...第二代模型 GPT-2,OpenAI 手头拿着学会了语言模型,但

    原创时序分析timeserieanalysis模型的应用parte1-TimeSerie_Concha.rar

    前提假设:一周的每天都有自己的独立的模型,因此需要将现有数据中的每一个周一,周二只到周末都提取出来,然后对它们分别进行模型建立。 这里我们以周三为例: 1. 原始周三信号为X,提取出X的趋势Trend。 关于...

    业绩大数据分析报告模型.doc

    营销总经理的业绩数据分析模型--营销总经理的工作模型(一) 前言 营销总经理这个职位压力大而且没有安全感——天气变化、竞品动态、本品产品质量 、公司的战略方向、费用投入、经销商的突然变化、行业动荡、上游...

    BigQueryML-AUSRainPrediction:数据集和BigQuery ML代码可预测澳大利亚第二天的降雨

    BigQueryML-如何训练模型来预测澳大利亚的第二天降雨 问题陈述 鉴于今天对风向,降雨,最低温度,最高温度,云量等的观察,我们能否预测明天是否会下雨? 动机 学习如何预测第二天的降雨是使用Google BigQuery探索...

    2012年美国数学建模一等奖获奖模型代码 mcm B题 the big long river matlab代码模型2

    在上一个模型中我们假设了所有船均以...对于循环中的第二天以后部分,程序的效果为处于最远的宿营地的团队先出发。对于6-18天的条件如何考虑进去,我们觉得已经隐含在前面一开始定义的人们每天所能持续最大时间之中。

    澳大利亚降雨预测代码和数据集.zip

    该数据集的主要任务目标是根据今日的气象信息训练分类模型,根据该模型预测澳大利亚第二天的降雨。数据总量为142194行,24列。 目标:1. 基于澳大利亚气象数据集探索数据特征信息;2. 基于澳大利亚气象数据集处理...

    7建筑能耗分析用逐时气象模型.pptx

    在逐日数据充足的有利条件下,就无需再用复杂繁琐的方法模拟逐日参数,也就是说,可以越过气象模型建立的第一步,直接进行第二步——模拟逐时参数。 研究目的和主要内容是:在逐日实测数据的基础上,建立一套完备...

    数据结构算法

    8天玩转并行开发——第六天 异步编程模型 8天玩转并行开发——第五天 同步机制(下) 8天玩转并行开发——第四天 同步机制(上) 8天玩转并行开发——第三天 plinq的使用 8天玩转并行开发——第二天 Task的使用 8天...

    数据分析课程设计---NBA球员技术统计分析报告.doc

    " " " " " "工作方案与进度安排: " " " "第一天——第二天 学习使用SPSS软件并选题 " "第三天——第四天 查阅资料 " "第五天——第六天 建立数学模型 " "第七天——第九天 上机求解并完成论文 " "第十天 辩论 " ...

    数据挖掘-大数据选址问题(PPT+论文).pptx

    水滴标记是初算的地址,小圆点是第二、三步复算出的地址,大圆点是最终的建议选址 数据挖掘-大数据选址问题(PPT+论文)全文共22页,当前为第12页。 慧选址 实地考察的兴趣点、网民行为、消费能力、消费习惯、人口、...

    sqlserver5天培训课程资料

    第二天: SQLSERVER的管理与安全、Transact-SQL基础 第三天: SQLSERVER的备份、SQLSERVER的视图、高级-SQL介绍。 第四天: 数据完整性的设计及实现、存储过程与触发器、SQLSERVER的数据传输服务。 第五天: SQL...

    H3BPM 试用系统操作手册

     在同一个流程包中有唯一的数据模型,但是可以新增多个流程&表单;  在设计流程时,可以使用同一个流程包下面的流程,作为子流程;  表单控件,在默认表单页面中,即可配置出来; 演示过程 1. 在Portal门户...

    2019数据运营思维导图

    行为分组 按照功能点使用/未使用分组 第二步:对比 根据用户行为进行分组 例子 看贴功能内浏览了3篇贴子的新用户和仅浏览1篇贴子的新用户进行分析 来自A渠道的新用户进行(有使用看贴/未使用看贴)行为分组比较 渠道...

Global site tag (gtag.js) - Google Analytics