TL;DR
Trying to "future proof" your data is done by making your tools, processes, and data structures flexible, not by fixing them for eternity. You do this by embracing test-first database design, ensuring your data is normalized and extensible, and that your tools and processes support change. You do not accomplish this by treating your data or designs as if they are written on stone tablets.
The closest you will likely come to future-proofing your product is to design your data for extensibility, not for immutability. Immutable data may have value in some architectural or engineering domains, but is almost never in itself a business advantage. Adaptability should therefore be a key objective for most projects.
Agility Embraces Change, So Iterative & Incremental Development are Features
[I want] to develop all of the functionality quickly thereafter, with minimal rework[.]
Avoiding "rework" misses the central objective of agile frameworks, which is to embrace changing requirements. The Agile Manifesto values and principles include:
- Responding to change over following a plan[.]
- [Welcoming] changing requirements, even late in
development. Agile processes harness change for
the customer's competitive advantage.
Agility is emphatically not about getting everything right the first time, or avoiding the need for refactorings, redesign, or even rework. Instead, agility is meant to address sunk costs and the inability to quickly adapt to change. Sunk costs and inflexibility are often byproducts of big, upfront development approaches resulting from the mistaken notion that product development or support are fully equivalent to a manufacturing assembly line. However, even many modern assembly lines (e.g. the Toyota Production Method) now embrace agility or other just-in-time processes rather than going down the upfront planning rabbit hole.
Databases Aren't Special
The idea that data doesn't change or evolve, or that what data is needed or how it will be used should be fixed, is a straw man. By accepting this a priori you are boxing yourself into a corner. Don't do that.
Data, databases, and the applications that consume or rely on them all change over time, and the need for adaptability is just as real on the database side as it is anywhere else. The idea that you can fully know what data you will need in the future, or how it needs to be structured, is provably wrong.
Databases are just as susceptible as anything else to over-engineering and violations of the YAGNI principle, leading to additional build, carry, and delay costs among others. There are a number of books and approaches to agile database architecture, design, and engineering that embrace change, and many application frameworks (with Ruby on Rails as a singularly outstanding example) that allow you to treat database migrations as an effective and test-driven approach to evolving your data or schema over time.
Design for Flexibility and Extensibility
Whether you're talking about data or the applications that consume them, the accepted modern wisdom is to start with what you know, build that in such a way that it can be extended or modified in the future, and then iterate over your design as required by business needs. This applies just as much to database design as to anything else.
There's no magic bullet. The way you implement agility in any product is by not painting yourself into a corner. As just one database-centric example, denormalized data is a way to trade extensibility for speed. It involves a deliberate trade-off where you must acknowledge that you are creating something that may require more work to refactor in the future (e.g. if the data or its representation needs to change) in exchange for more speed today. If you want to reduce the burden of refactoring or re-engineering your data, don't do that. On the other hand, if you have a non-functional requirement today that can't be solved in a way that is more flexible, then you bite the bullet and do what is necessary rather than worrying about a potential business case that no one is demanding that you solve for right now.
This all involves balance. You can sink unnecessary costs now and accept the risk that you will never actually need that feature; or you say we may never need it and accept the risk that you may in fact need to pay for that feature (including any refactoring, rework, or net-new work required) at some point down the road. By simply measuring and acknowledging the risks, you can then find the optimal business approach that balances risk and reward within the appetite of the project sponsors.
See Also