2010-07-18 77 views
2

我开始尝试为电视电子节目指南创建Web应用程序的新项目。这不是一个大规模的项目,而只是一些我可以用来学习Web应用程序编程的东西。我将为此使用PHP。Web应用程序体系结构设计

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

我应该如何实现应用程序的体系结构?

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

  • 将节目描述放在XML文件中。
  • 将通道名称放入数据库的表中。
  • 将演出名称和ID放入其他表格中,并从XML文档中获取演出描述。

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

您是否比上述架构有更好的建议?

+0

为什么你想在xml文件中存储任何东西? 一个不错的视频,我今天发现有关此主题:http://vimeo.com/10506751 – antpaw 2010-07-18 22:01:56

+0

因为xml的酷炫因素,可能 – mvds 2010-07-18 22:10:11

回答

6

从我假设电视节目指南存储的数据类型来看,它确实看起来好像可以将所有内容存储在关系数据库中。我认为使用filestsytem或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_id是一个surrogate key,你甚至可以让它generate a unique serial number automaticallyname字段只是名称字段,description字段有一个text数据类型,可以存储可变数量的文本。

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

然后channel_slots表为每个频道的每一天分配显示位置。

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

slot_id又是一个代理键,channel_idshow_id字段foreign keys到的相关表格。 startend字段只是定义节目的准确开始和结束时间。如果您要插入节目时间尚未定义的节目,则可能需要在这些字段中插入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进行研究,这是我的答案中未涉及的一个重要主题。

+0

的确,唯一的原因不是当担心压力时获取相关数据数据库,在这种情况下,只需缓存从数据库信息构建的更复杂的对象,如memcache或apc。 – Wrikken 2010-07-18 22:15:29

0

有一对夫妇,你需要牢记的思想“流”的:

  • “业务问题”(如何做一个酷乐视网络应用 - 专注于业务价值)
  • “架构问题“ - 如何构建应用/酷技术。
  • “编程问题” - 编写/冷却要使用的技术的代码。 (如何制作一个很酷的网络应用程序 - 专注于技术自学)

首先,按优先级排列这些。如果这只是关于PHP的话,那么关于它是否是一个好的“电视网络应用程序”或者不是真的很重要(在短期内)。

如果业务方面很重要(出于任何原因),那么您需要给予应有的注意,在这种情况下,我会先考虑数据如何挂在一起。在纸上绘制一些简单的概念模型,并将它们固定在你工作的墙上(或者在白板上做一张照片(例如使用手机)并打印出副本)。

你将有相关的实体(频道,节目,时间)。 一旦你有了高层次的清理,就可以开始在较低的层次上工作 - 可能是通过在纸面上设计数据库表。

这是架构vs编程发挥作用;如果是我的话我会坚持所有的数据在一个后端系统 - 比方说一个关系数据库 - 因为所有的数据是与它更好地保持它都在同一个地方:

  • 你只需要开发一个DAL(数据访问层)
  • 您可以提出涵盖各种相关实体的问题(让我在所有频道的下午2点至5点之间播放所有节目)。

另外,如果这是一个练习,是学习技术技能,我可以看到为什么你想在这里有XML和一个数据库 - 因为它给你一个更大范围的东西,你会学习。

建筑可以帮助你在这里(和另一个伟大的技能学习)。如果是我(我在.Net中这样做),我会将所有的数据访问抽象出来在一个接口后面 - 这样我就可以拥有尽可能多的不同物理DAL;看看Dependency Inversion Principle