【问题标题】:Web application architecture design网页应用架构设计
【发布时间】:2011-03-17 16:27:30
【问题描述】:

我正在开始一个新项目,试图为电视电子节目指南创建一个 Web 应用程序。这不会是一个大型项目,而只是我可以用来学习 Web 应用程序编程的东西。我将为此使用 PHP。

在开始为应用程序编码之前,有一个关键问题困扰着我。由于该应用程序将涉及大量使用数据库和/或 XML 文件来存储数据,因此我对如何实现该应用程序的体系结构感到困惑。请耐心等待这个初学者的问题。

我应该如何实现应用程序的架构?

例如,大约有 50 个频道,节目数量为 (50 * N)。我的想法是:

  • 将节目描述放入 XML 文件中。
  • 将频道名称放入数据库的表中。
  • 将节目名称和 ID 放在另一个表中,并从 XML 文档中获取节目说明。

上述架构缺乏的是如何实际实现时间跟踪。我的意思是我知道特定节目的开始和结束时间,但我在哪里“最好”存储这些信息?在数据库中还是在 XML 文件中?以及如何“最好”地显示信息?

你有比上述架构更好的建议吗?

【问题讨论】:

  • 为什么要将任何内容存储在 xml 文件中?我今天发现了一个关于这个主题的好视频:vimeo.com/10506751
  • 可能是因为xml的酷炫因素吧

标签: php javascript architecture web-applications


【解决方案1】:

从我假设电视节目指南存储的那种数据来看,看起来您真的可以将所有内容存储在关系数据库中。我认为使用文件系统或 XML 文件没有任何优势。

时间跟踪查询在 SQL 中应该非常简单。

您可以考虑使用如下架构(在本例中使用 MySQL):

CREATE TABLE shows (
   show_id int NOT NULL PRIMARY KEY,
   name varchar(100),
   description text
) ENGINE=InnoDB;

CREATE TABLE channels (
   channel_id int NOT NULL PRIMARY KEY,
   name varchar(100)
) ENGINE=InnoDB;

CREATE TABLE channel_slots (
   slot_id int NOT NULL PRIMARY KEY,
   channel_id int NOT NULL,
   day date NOT NULL,
   show_id int NOT NULL,
   start datetime,
   end datetime,
   FOREIGN KEY (channel_id) REFERENCES channels(channel_id),
   FOREIGN KEY (show_id) REFERENCES shows(show_id)
) ENGINE=InnoDB;

shows 表应该定义每个节目。 show_idsurrogate key,您甚至可以将其设为 generate a unique serial number automaticallyname 字段只是名称字段,description 字段具有text 数据类型,可以存储可变数量的文本。

channels 表应该非常简单。我们再次使用代理键作为channel_id。我不确定频道是否有一些可以用作natural key 的唯一标准代码,但使用代理键应该是安全的。

然后channel_slots 表将节目时段分配给每个频道的每一天。

我可能是错的,但我认为大多数电视节目指南并没有将一天严格定义为午夜开始和结束。有时这一天可能在第二天凌晨 2:00,而从凌晨 1.30 开始到凌晨 2:00 结束的节目将成为当天的一部分。如果是这种情况,这就是在此表中使用 day 字段的原因。在该字段中,我们可以根据“节目指南日”来定义该节目所属的日期。

slot_id 又是一个代理键,channel_idshow_id 字段是相关表的foreign keysstartend 字段仅定义了节目的准确开始和结束时间。如果您要在尚未定义演出时间的地方插入节目,您可能需要在这些字段中插入NULL。另一种选择是使用另一个字段作为标志来标记是否确认放映时间。

如果您打算使用 MySQL 作为您的 DBMS,请注意 InnoDB 存储引擎支持外键约束,而默认的 MyISAM 引擎不支持。但是,只有 MyISAM 引擎支持full text indexing。如果您打算允许您的用户在节目说明中搜索文本,这可能会很有用。

为了给你一个上述模式的例子,让我们在其中填充一些数据:

INSERT INTO shows VALUES (1, 'Breakfast Show', 'The everyday morning show');
INSERT INTO shows VALUES (2, 'Who wants to be a Millionaire?', 'Who does not?');
INSERT INTO shows VALUES (3, 'Saturday Night Live', 'Only on Saturdays');

INSERT INTO channels VALUES (1, 'Channel 1');

INSERT INTO channel_slots VALUES(
   1, 1, '2010-07-17', 1, '2010-07-17 07:00:00', '2010-07-17 09:00:00');

INSERT INTO channel_slots VALUES(
   2, 1, '2010-07-17', 2, '2010-07-17 18:00:00', '2010-07-17 19:00:00');

INSERT INTO channel_slots VALUES(
   3, 1, '2010-07-17', 3, '2010-07-17 23:30:00', '2010-07-18 01:00:00');

这就是我们的表格现在的样子:

mysql> SELECT * FROM channels;
+------------+-----------+
| channel_id | name      |
+------------+-----------+
|          1 | Channel 1 |
+------------+-----------+
1 row in set (0.00 sec)

mysql> SELECT * FROM shows;
+---------+--------------------------------+---------------------------+
| show_id | name                           | description               |
+---------+--------------------------------+---------------------------+
|       1 | Breakfast Show                 | The everyday morning show |
|       2 | Who wants to be a Millionaire? | Who does not?             |
|       3 | Saturday Night Live            | Only on Saturdays         |
+---------+--------------------------------+---------------------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM channel_slots;
+---------+------------+------------+---------+---------------------+---------------------+
| slot_id | channel_id | day        | show_id | start               | end                 |
+---------+------------+------------+---------+---------------------+---------------------+
|       1 |          1 | 2010-07-17 |       1 | 2010-07-17 07:00:00 | 2010-07-17 09:00:00 |
|       2 |          1 | 2010-07-17 |       2 | 2010-07-17 18:00:00 | 2010-07-17 19:00:00 |
|       3 |          1 | 2010-07-17 |       3 | 2010-07-17 23:30:00 | 2010-07-18 01:00:00 |
+---------+------------+------------+---------+---------------------+---------------------+
3 rows in set (0.00 sec)

现在假设现在时间是2010-07-17 17:45:00,并且您想在频道 1 上显示下一个节目是什么:

SELECT    s.name, cs.start, cs.end 
FROM      channel_slots cs
JOIN      shows s ON (s.show_id = cs.show_id)
WHERE     cs.start > NOW()
ORDER BY  cs.start
LIMIT     1;

结果:

+--------------------------------+---------------------+---------------------+
| name                           | start               | end                 |
+--------------------------------+---------------------+---------------------+
| Who wants to be a Millionaire? | 2010-07-17 18:00:00 | 2010-07-17 19:00:00 |
+--------------------------------+---------------------+---------------------+
1 row in set (0.00 sec)

然后以下查询显示频道 1 当天的剩余时间表:

SELECT    s.name, cs.start, cs.end 
FROM      channel_slots cs
JOIN      shows s ON (s.show_id = cs.show_id)
WHERE     cs.start > NOW() AND
          cs.day = '2010-07-17'
ORDER BY  cs.start;

结果:

+--------------------------------+---------------------+---------------------+
| name                           | start               | end                 |
+--------------------------------+---------------------+---------------------+
| Who wants to be a Millionaire? | 2010-07-17 18:00:00 | 2010-07-17 19:00:00 |
| Saturday Night Live            | 2010-07-17 23:30:00 | 2010-07-18 01:00:00 |
+--------------------------------+---------------------+---------------------+
2 rows in set (0.00 sec)

等等。我希望这能让你朝着正确的方向前进。您还应该确保研究database indexes,这是我的答案未涵盖的重要主题。

【讨论】:

  • 确实,唯一不这样做的原因是担心从数据库中获取相关数据的压力,在这种情况下,只需将根据数据库信息构建的更复杂的对象缓存在 memcache 或 apc 之类的东西中。
【解决方案2】:

您需要牢记几个“思路”:

  • “业务问题”(如何制作出色的电视网络应用 - 专注于业务价值)
  • “架构问题” - 如何构建应用程序/酷技术。
  • “编程问题” - 要编写哪些代码/使用哪些酷技术。 (如何制作出色的网络应用 - 专注于技术自学)

首先,按优先级排序。如果这只是为了学习 PHP,那么(在短期内)它是否是一个好的“电视网络应用程序”并不重要。

如果业务方面很重要(出于任何原因),那么您需要尽职尽责,在这种情况下,我会首先考虑数据是如何连接在一起的。在纸上画一些简单的概念模型,然后把它们钉在你工作的墙上(或者,在白板上做它们,给它们拍一张照片(比如用你的手机),然后打印一份)。

您将拥有相关的实体(频道、节目、时间)。 整理好高层次后,开始从低层次开始工作 - 可能通过在纸上设计数据库表。

这是架构与编程发挥作用的时候;如果是我,我会将所有数据保存在一个后端系统中——比如一个关系数据库——因为所有数据都是相关的,最好将它们都保存在同一个地方:

  • 您只需要开发一个 DAL(数据访问层)
  • 您可以提出涉及各种相关实体的问题(在下午 2 点到 5 点之间获取所有频道的所有节目)。

或者,如果这是一个学习技术技能的练习,我可以理解您为什么要在这里使用 XML 并在此处使用 DB - 因为它可以让您学到更多的东西。

架构可以在这方面为您提供帮助(并且是另一个值得学习的好技能)。如果是我(并且我在 .Net 中这样做),我会将所有数据访问抽象到接口后面 - 这样我就可以拥有尽可能多的不同物理 DAL;看看Dependency Inversion Principle

【讨论】:

    猜你喜欢
    • 2010-09-29
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多