Many database applications require the storage and manipulation of different versions of data objects. However, current database systems do not support versioning well. Each application area treats versions in its own way, and these ways are usually incompatible with each other. We show how this incompatibility can be resolved by separating the physical, conceptual, and logical levels of versioning. We develop a version specification language at the conceptual level, and a multidimensional specification language at the logical level. By encoding the logical versioning semantics of an application into orthogonal dimensions, we generalize the ideas of historical and temporal databases to arbitrary object-oriented databases. The result is a unified, application-independent treatment of versioning.