Create a new table, that has all the columns of the existing table, but also a time column, which is set to the value of the time the snapshot was initiated. You're adding a new fact to store about an existing set of facts (each table should store one kind of fact, ideally). The value of the time column identifies each snapshot. If you need to query across the whole table, then that's a practical disk IO problem. But, by keeping the data in plain old columns from the DB, you can add indexes to columns that are used by those time-consuming queries. If you need to keep aggregate data on the information, there's a disk IO problem with it being big, and the answer is to design views that perform those aggregations on updates, with intermediate historical data being maintained, instead of going over the whole data set every time. Keep as much large IO in the DB as possible. A large table can be a problem for your memory and hard drives, should you need to access more than a small part of it, and is going to need a human touch to manage any large queries over it, *with any design*. MySQL, OTOH, will be fine with a very large table. Over-complicating it with many tables, or JSON stores, will do no good, and could come back to bite you if you ever need to perform any historical queries over it. However, the implementation may eventually need partitioning. When you start reaching whatever limit is relevant for your DB or table, decide on partitioning. You will, *in the future*, have enough information to decide what the best method is. With InnoDB, it's quite possible that you may never reach any such limit. Likewise, depending on settings, you could hit such a limit with many tables just as well as one big one. http://dev.mysql.com/doc/refman/5.0/en/table-size-limit.html