2010-07-18 48 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