php - 网络应用架构设计

标签 php javascript architecture web-applications

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

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

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

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

  • 将演出描述放入 XML 文件中。
  • 将 channel 名称放入数据库的表中。
  • 将节目名称和 ID 放入另一个表中,并从 XML 文档中获取节目描述。

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

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

最佳答案

从我假设的电视节目指南存储的数据来看,看起来确实可以将所有内容存储在关系数据库中。我认为使用 filetsytem 或 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。我不确定 channel 是否有一些独特的标准代码可以用作 natural key相反,但使用代理键应该是安全的。

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

我可能是错的,但我认为大多数电视节目指南并没有严格将一天定义为午夜开始和结束。有时,这一天可能会在第二天的凌晨 2:00,并且从凌晨 1.30 开始并于凌晨 2.00 结束的节目将成为当天的一部分。如果是这种情况,那就是在此表中使用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,您想要显示 channel 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)

然后以下查询显示 channel 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 ,这是我的回答中未涵盖的一个重要主题。

关于php - 网络应用架构设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3277420/

相关文章:

php - 如何在通过php存储在文件夹中时更改图像名称

php - 将参数添加到从 Python 调用的 PHP 脚本

php - 使用 Doctrine 2 转储数据库数据

php渲染html表格

javascript - 双击禁用单选按钮正在启动 IE11 中的单击事件

javascript - 在 Javascript 中动态添加事件处理程序

c# - 为 64 位和 32 位开发

architecture - AMD 设备上的物理内存 : local vs private

javascript - 带下拉菜单的 Mixitup 插件

generics - 如何避免传递类型依赖?