********************************************************************************* * * * DATABASE SCHEMA * * * ********************************************************************************* This file isn't going to describe the ENTIRE database - that would take forever, and Gazelle RC1 would never be released. Most of the database is pretty self-explanatory, but there are some funky bits that might trip you up. //--------- General ------------------------------------------------------------- Tables names are lower_case_with_underscores, and column names are MixedCase. The only exceptions to these rules are the xbtt tables and columns, which are named the 'xbtt way'. //--------- Users --------------------------------------------------------------- The users table is broken into two tables - users_main and users_info. The users_main table contains all of the essential information about the user, eg. username, password, email, class, etc. The users_info table contains information that isn't used as often, such as their avatar URL. This is so we don't have to sift through giant tables all the time, especially on the tracker end (the tracker should never have to touch the users_info table). //--------- Torrents ------------------------------------------------------------ At the time of this writing, we have a database of 211,000 torrents. All of these torrents must be searched through and sorted every time someone performs a search (we average at around one search per second) - as such, the torrents tables are designed more around speed than developer usability. We have 3 main torrents tables - torrents, torrents_group, and torrent_hash. torrents holds information on individual torrents. In a database of 211,000 torrents, it has 211,000 rows. It is the only torrents table touched by the tracker, and is where you'll find any information on torrents that doesn't apply to the entire group (such as the encoding). torrents_group holds information that applies to the entire group, such as the name, category, and description. Since there can be multiple torrents per group, the number of rows in torrents_group is less than in torrents. We have 149,000 rows in torrents_group. The data in the torrents tables all conforms to proper organization practices, and would make any young web 2.0 standards freak want to touch himself in excitement. Unfortunately, organization isn't everything, especially when you've got a 200,000 row table on your hands. JOINs are quite costly things, and the way we laid out the tables would require us to join the torrents table with the torrents_group table, the torrents_tags table, the tags table, and the artists table, and stick in a bunch of GROUP_CONCATs. We tried it on a 14k row table once, and it took around 20 seconds to generate torrents.php. Not fun. The solution to this is to group all this data together and stick it in a new table - the torrent_hash table. The torrent_hash table contains pipe-separated values, and there is one row for each row in torrents_group. It has all the information needed to display a torrent group on the browse page. The torrent_hash table is extremely low-write and all the information in it is 'disposable'. As such, we chose to make it a MyISAM table, which has the added benefit of allowing a FULLTEXT index on the SearchText field. The torrent_hash table is built every 15 minutes by schedule.php, and takes 23 seconds on our database. The torrent_hash entry for a specific group can be updated by running the update_hash function.