From the kind of data that I assume TV programme guides store, it really looks like you can store everything inside a relational database. I see no advantage in using the filestsytem or XML files.
The queries for time-tracking should be very straightforward in SQL.
You could consider using a schema such as the following (using MySQL in this example):
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;
The shows
table should define each show. show_id
is a surrogate key, and you can even make it generate a unique serial number automatically. The name
field is just name field, and the description
field has a text
data type which can store a variable amount of text.
The channels
table should be quite straightforward. Again we're using a surrogate key as a channel_id
. I'm not sure if channels have some unique standard code that can be used as a natural key instead, but you should be safe with a surrogate key.
Then the channel_slots
table allocates show slots to each day of each channel.
I might be wrong, but I think most TV programme guides do not strictly define a day as starting and ending at midnight. Sometimes the day might at at 2:00am of the following day, and a programme that start at 1.30am and ends at 2.00am would make part of that day. If this is the case, that's the reason for using a day
field in this table. In this field we can define the day that this show belongs to, in terms of "programme guide days".
The slot_id
is again a surrogate key, and the channel_id
and show_id
fields are foreign keys to the relevant table. The start
and end
fields simply define the accurate start and end times of the show. If you will be inserting shows where the show times are not yet defined, you may want to insert NULL
in these fields. Another option could be to use another field as a flag to mark if show times are confirmed of not.
If you are going to use MySQL as your DBMS, note that the InnoDB storage engine supports foreign key constraints, while the default MyISAM engine does not. However, only the MyISAM engine supports full text indexing. This may be useful if you intend to allow your users to search for text inside the show descriptions.
To give you an example of the above schema, let's populate some data in it:
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');
This is how our tables look like now:
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)
Now let's say that the time now is 2010-07-17 17:45:00
and you want to display what is the next show on 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;
Result:
+--------------------------------+---------------------+---------------------+
| 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)
Then the following query displays the remaining schedule of the day for 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;
Result:
+--------------------------------+---------------------+---------------------+
| 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)
And so on. I hope this gets you going in the right direction. You should also make sure to research on database indexes, an important topic not covered in my answer.